aboutsummaryrefslogtreecommitdiff
path: root/example/example.c
blob: 103684585a4a614cf1905dd2c7e9d94cfada905d (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
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "parcini.h"

#define EXAMPLE_INI "example/example.ini"

struct {
	struct {
		char *name;
		long int age;
	} personal;
	struct {
		char *email;
		bool visible;
	} contact;
} example = {
	.personal.name = NULL,
	.contact.email = NULL,
};

static bool
handle_keyvalue(struct parcini_line *parsed)
{
#define MATCHES(s, k) !strcmp(parsed->section, s) && !strcmp(parsed->key, k)

	if (MATCHES("personal", "name")) {
		return parcini_value_handle(&parsed->value, PARCINI_VALUE_STRING,
				&example.personal.name);
	}
	if (MATCHES("personal", "age")) {
		return parcini_value_handle(&parsed->value, PARCINI_VALUE_INTEGER,
				&example.personal.age);
	}
	if (MATCHES("contact", "email")) {
		return parcini_value_handle(&parsed->value, PARCINI_VALUE_STRING,
				&example.contact.email);
	}
	if (MATCHES("contact", "visible")) {
		return parcini_value_handle(&parsed->value, PARCINI_VALUE_BOOLEAN, 
				&example.contact.visible);
	}

	return false;
}

int
main(void)
{
	parcini_t *parser = parcini_from_file(EXAMPLE_INI);
	if (parser == NULL) {
		fprintf(stderr, "error opening file: %s\n", strerror(errno));
		return 1;
	}

	struct parcini_line parsed;
	enum parcini_result res;
	while ((res = parcini_parse_next_line(parser, &parsed)) != PARCINI_EOF) {
		switch (res) {
		case PARCINI_EMPTY_LINE:
		case PARCINI_SECTION:
			continue;

		case PARCINI_KEYVALUE:
			if (!handle_keyvalue(&parsed)) {
				fprintf(stderr, 
						"line %ld: error: unexpected section '%s'/key '%s' or "
						"invalid value type\n",
						parsed.lineno, parsed.section, parsed.key);
				goto cleanup;
			}
			continue;

		case PARCINI_MEMORY_ERROR:
		case PARCINI_STREAM_ERROR:
			fprintf(stderr, 
					"An error occurred while trying to read the next line\n");
			goto cleanup;

		default:
			fprintf(stderr, "line %ld: parse error\n", parsed.lineno);
			goto cleanup;
		};
	}

	printf("parsed example.ini:\n");
	printf("name:\t%s\n", example.personal.name);
	printf("age:\t%ld\n", example.personal.age);
	printf("email:\t%s\n", example.contact.email);
	printf("visible:\t%s\n", example.contact.visible ? "true" : "false");

cleanup:
	free(example.personal.name);
	free(example.contact.email);
	parcini_destroy(parser);
}