C/Read an ini file

From Attie's Wiki
Revision as of 16:54, 17 October 2011 by Attie (Talk | contribs)

Jump to: navigation, search
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define CHUNK_SIZE 128
 
enum lineTypes {
	unknown,
	empty,
	comment,
	sectionHead,
	variableOnly,
	variableValue
};
 
struct lineByLine {
	char *line;
	int length;
	enum lineTypes type;
};
 
int main(int argc, char *argv[]) {
 
	FILE *f;
	void *p;
 
	struct lineByLine *lines;
	struct lineByLine *tline;
	int linec;
 
	int isNewline;
	char *c; /* contents*/
	int i;
	int l; /* length */
	int r; /* amount read */
	int s; /* memory size */
	int printedLines;
 
	f = fopen("php.ini","r");
	if (!f) {
		perror("fopen()");
		exit(1);
	}
 
	c = NULL;
	l = 0;
	s = 0;
	while (!feof(f)) {
		s += CHUNK_SIZE;
		p = realloc(c, sizeof(char) * s);
		if (!p) {
			perror("realloc()");
			goto die1;
		}
		c = p;
		r = fread(&(c[l]), 1, s - l, f);
		if (!r) {
			fprintf(stderr,"EOF?\n");
			break;
		} else if (r < 0) {
			perror("fread()");
			break;
		}
		l += r;
	}
 
	p = realloc(c, sizeof(char) * (l + 1));
	if (!p) {
		perror("realloc()");
	} else {
		c = p;
	}
 
	c[l] = '\0';
 
	lines = NULL;
	linec = 0;
	isNewline = 1;
	for (i = 0; i <= l; i++) {
		if (isNewline) {
			isNewline = 0;
			p = realloc(lines, sizeof(struct lineByLine) * (linec + 1));
			if (!p) {
				perror("realloc()");
				goto die2;
			}
			lines = p;
			tline = &(lines[linec]);
			tline->line = &(c[i]);
			tline->length = -1;
			tline->type = unknown;
			linec++;
		}
		if (i == l || c[i] == '\n') {
			isNewline = 1;
			if (i < l) c[i] = '\0';
			if (linec > 0) {
				tline = &(lines[linec-1]);
				tline->length = strlen(tline->line);
				switch (tline->line[0]) {
					case '\0': tline->type = empty; break;
					case ';':  tline->type = comment; break;
					case '[':  tline->type = sectionHead; break;
					default:
						if (strchr(tline->line,'=')) {
							tline->type = variableValue;
						} else {
							tline->type = variableOnly;
						}
				}
			}
		}
	}
 
	printedLines = 0;
	for (i = 0; i < linec; i++) {
		tline = &(lines[i]);
		switch (tline->type) {
			case sectionHead:
				if (printedLines) printf("\n");
			case variableOnly:
			case variableValue:
				printf("%s\n", tline->line);
				printedLines++;
				break;
			case empty:
			case unknown:
			case comment:
				break;
		}
	}
 
	return 0;
die2:
	if (lines) free(lines);
die1:
	if (c) free(c);
die:
	return 1;
}
Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox