aboutsummaryrefslogtreecommitdiff
path: root/parse.c
blob: ba2a5a0768815a51ffc066078a88dc2ddba1b6c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

typedef enum {
	key, value
} context;

typedef struct  {
	char *key, *value;
} kvpair;

/*
 * Max length of a line.
 * TODO update this to allow longer lines, in case someone doesn't
 * follow the standard.
 */
#define SEGSIZE 75

int ii = 0;

#define MARK do { printf("%i -- %i\n", __LINE__, ii++); } while (0)

#define ERR(x) do { \
	fprintf(stderr, "ERR %i: %s", __LINE__, (x)); \
} while(0)


int main (int argc, char* argv[argc]) {
	FILE* F = fopen(argv[1], "r");

	int segments = 1;
	char* str = malloc(segments * SEGSIZE);
	int i = 0;

	context ctx = key;
	kvpair kvs[100];
	int ki = 0;

	char c;
	while ( (c = fgetc(F)) != EOF) {
		/*
		 * A carrige return means that the current line is at an
		 * end. The following character should always be \n.
		 * However, if the first character on the next line is a
		 * whitespace then the two lines should be concatenated.
		 */
		if (c == '\r') {

			char s[2];
			s[0] = fgetc(F);
			s[1] = fgetc(F);

			if (s[0] != '\n') { ERR("expected newline after CR"); }
			else if (s[1] == ' ' || s[1] == '\t') {
				MARK;
				// TODO check return value
				// TODO segments is always incremented here, meaning
				// that segment grows larger for every multi line
				// encountered.
				str = realloc(str, ++segments * SEGSIZE);
				if (str == NULL) { /* TODO signal error */
					exit (1);
				}
				continue;
			} else {
				MARK;
				if (ungetc(s[1], F) != s[1]) { /* TODO signal error */
					exit (2);
				}

				/* At TRUE end of line */
				kvs[ki].value = malloc(i + 1);
				memcpy(kvs[ki].value, str, i);
				kvs[ki].value[i] = 0;
				ki++;
				i = 0;
				ctx = key;
				continue;
			}
		} else if (ctx == key && c == ':') {
			kvs[ki].key = malloc(i + 1);
			memcpy(kvs[ki].key, str, i);
			kvs[ki].key[i] = 0;
			printf("key := %s\n", kvs[ki].key);
			i = 0;
			ctx = value;
			continue;
		}

		str[i] = c;
		++i;
	}
	if (errno != 0) {
		printf("Error parsing, errno = %i\n", errno);
	}
	puts("File parsed");
	free(str);

	/*
	 * Just print and free all collected data
	 */
	for (int i = 0; i < ki; i++) {
		printf("[%s] := [%s]\n", kvs[i].key, kvs[i].value);
		free(kvs[i].key);
		free(kvs[i].value);
	}

}