Skip to content

Instantly share code, notes, and snippets.

@StSav012
Last active February 27, 2018 06:34
Show Gist options
  • Save StSav012/8a4fd50283966852f35492cd55a2aca3 to your computer and use it in GitHub Desktop.
Save StSav012/8a4fd50283966852f35492cd55a2aca3 to your computer and use it in GitHub Desktop.
INI file parser
#include <stdlib.h>
#include <stdio.h>
/*****************************************************************************
* @function readValue extracts a string value from an INI file
* @param f is a file opened for reading outside the function
* @param section is the section name to look into
* @param key is the key which value is required
* @param buffer is a buffer to store the key value into
* @note @param buffer should be long enough to store the value
* @bug the function doesn't work with multi-line values
****************************************************************************/
int readValue(FILE *f, char *section, char *key, char *buffer) {
rewind(f);
char c = 0;
int i;
int newLine = 1;
int inSectionName;
int seekKey;
int seekSection = 1;
int readValue;
do {
do {
do {
c = fgetc(f);
if (c == '\n') {
newLine = 1;
}
} while (newLine && seekSection && c != '[' && c != EOF);
seekSection = 0;
inSectionName = 1;
i = 0;
do {
c = fgetc(f);
if (c != section[i] && c != ']' && section[i]) {
seekSection = 1;
}
if (c == ']') {
inSectionName = 0;
}
if (c == '\n') {
newLine = 1;
}
} while (!seekSection && inSectionName && section[i++] && c != EOF);
while (c != EOF && c != '\n') {
c = fgetc(f);
}
newLine = 1;
} while (c != EOF && seekSection);
if (!seekSection) {
do {
seekKey = 0;
i = 0;
do {
c = fgetc(f);
if (c == '\n') {
newLine = 1;
i = 0;
}
while (newLine && (c == ' ' || c == '\t')) {
c = fgetc(f);
}
if (newLine && c == '[') {
seekSection = 1;
fseek(f, -1, SEEK_CUR);
}
newLine = 0;
if (!newLine && c != key[i++]) {
seekKey = 1;
}
} while (!seekKey && !seekSection && key[i] && c != EOF);
if (!seekSection && !seekKey) {
readValue = 0;
i = 0;
do {
c = fgetc(f);
if (c == '\n') {
newLine = 1;
}
if (c == '#') { // inline comment
newLine = 1;
do {
c = fgetc(f);
} while (c != '\n');
}
if (readValue == 0 && (c == '=' || c == ':')) {
readValue = 1;
}
else if (readValue == 1 && c != ' ' && c != '\t') {
readValue = 2;
}
if (readValue == 2 && !newLine && c != EOF) {
*buffer = c;
++buffer;
++i;
}
} while (!newLine && c != EOF);
return i;
}
} while (!seekSection && c != EOF);
}
seekSection = 1;
} while (c != EOF);
return 0;
}
int main(int argc, char **argv) {
const char fn[] = "sample.ini";
char b[256] = {0};
int r;
FILE * f;
if (f = fopen(fn, "r")) {
r = readValue(f, "section", "key", b);
printf("value: %s (%d characters)\n", b, r);
fclose(f);
}
else {
printf("%s `%s`\n", "failed to open", fn);
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment