Last active
December 11, 2015 23:09
-
-
Save fbstj/4674888 to your computer and use it in GitHub Desktop.
ini file parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string.h> | |
#include <stdio.h> | |
enum ini_parts { | |
ini_section, ini_key, ini_value, | |
ini_section_start = '[', ini_section_end=']', | |
ini_key_value = '=', | |
ini_comment = ';' | |
}; | |
static char valid_token(const char token[]) | |
{ | |
return strchr(token, ini_section_start) == NULL | |
&& strchr(token, ini_section_end) == NULL | |
&& strchr(token, ini_comment) == NULL; | |
} | |
// find the start and length of the next section title | |
char *ini_next_section(char * const file, int * const length) | |
{ | |
char * start, * end; | |
start = strchr(file, ini_section_start); | |
if (start == NULL) return NULL; | |
end = strchr(++start, ini_section_end); | |
if (end == NULL) return NULL; | |
*length = end - start; | |
return start; | |
} | |
int ini_find_value(const char file[], const char section[], const char key[], char * const value) | |
{ | |
size_t _sl = strlen(section) + 2, _kl = strlen(key) + 1, _end; | |
char _section[_sl], _key[_kl]; | |
const char * _start, * _next, * _value; | |
if (!valid_token(section) || !valid_token(key)) | |
return -1; | |
sprintf(_section, "%c%s%c", ini_section_start, section, ini_section_end); | |
sprintf(_key, "%s%c", key, ini_key_value); | |
_start = strstr(file, _section); | |
if (_start == NULL) return -2; // no '[section]' | |
_value = strstr(_start + _sl, _key); | |
if (_value == NULL) return -3; // no 'key=' | |
_value += _kl; | |
_next = strchr(_start + _sl, ini_section_start); | |
if (_next == NULL) _next = file + strlen(file); | |
if (_value > _next) return -4; // 'key=' is after the next '[section]' | |
_end = strcspn(_value, "\n\r;"); | |
memcpy(value, _value, _end); | |
value[_end] = 0; | |
return _end; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* test ini.c */ | |
#include <stdio.h> | |
#include <stdlib.h> | |
size_t fsize(FILE * const file) | |
{ | |
size_t size = -1; | |
fseek(file, 0, SEEK_END); | |
size = ftell(file); | |
rewind(file); | |
return size; | |
} | |
char * fgeta(FILE * const file) | |
{ | |
char * buffer = NULL; | |
size_t string_size, read_size; | |
if (file) | |
{ | |
string_size = fsize(file); | |
buffer = (char*) malloc(sizeof(char) * (string_size + 1)); | |
read_size = fread(buffer, sizeof(char), string_size, file); | |
buffer[string_size + 1] = '\0'; | |
if (string_size != read_size) | |
{ | |
free(buffer); | |
buffer = NULL; | |
} | |
} | |
return buffer; | |
} | |
extern int ini_find_value(const char file[], const char section[], const char key[], char * const value); | |
void test_ini(const char file[], const char section[], const char key[]) | |
{ | |
static char value[200]; | |
if (ini_find_value(file, section, key, value) < 0) | |
fprintf(stderr, "![%s]%s not found\n", section, key); | |
else | |
printf("[%s]%s=%s\n", section, key, value); | |
} | |
int main(int argc, char **argv) | |
{ | |
char * file = fgeta(fopen(argv[1], "r")); | |
test_ini(file, "section","key"); | |
test_ini(file, "section","key2"); | |
test_ini(file, "section","key3"); | |
test_ini(file, "section","bcde"); | |
test_ini(file, "section","prev"); | |
test_ini(file, "next","prev"); | |
test_ini(file, "next","test"); | |
test_ini(file, "test","test"); | |
test_ini(file, "test=0","test"); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[section] | |
key=1 | |
key2=3;comment | |
bcde=fghi | |
[next];section comment | |
prev=four;comment;with;comments | |
[test] | |
[test=0] | |
test=3 | |
;end comment |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment