summaryrefslogtreecommitdiff
path: root/config.c
blob: 3d683c24d6b8e53deff32a5ac41d6955897cdc68 (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 <string.h>
#include <stdlib.h>

#include <libconfig.h>

#include "regexset.h"
#include "channel.h"

config_t config;

int cfg_init() {
	config_init(&config);

	char cfg_file[0xff];
	strcpy(cfg_file, getenv("HOME"));
	strcat(cfg_file, "/.ircstats/config");

	if(config_read_file(&config, cfg_file) == CONFIG_FALSE) {
		int line = config_error_line(&config);
		if(line == 0)
			fprintf(stderr, "Could not read config: %s\n", config_error_text(&config));
		else
			fprintf(stderr, "Parse error on line %d: %s\n", config_error_line(&config), config_error_text(&config));
		return 0;
	}

	config_setting_t *regexes_setting = config_lookup(&config, "regexes");
	if(!config_setting_is_aggregate(regexes_setting)) {
		fprintf(stderr, "Setting \"regexes\" must be an aggregate type.\n");
		return 0;
	}

	int regex_count = config_setting_length(regexes_setting);

	for(int i = 0; i < regex_count; i++) {
		config_setting_t *re_setting = config_setting_get_elem(regexes_setting, i);
		const char *text, *join;
		if(!(config_setting_lookup_string(re_setting, "text", &text) && config_setting_lookup_string(re_setting, "join", &join))) {
			fprintf(stderr, "Regex set #%d missing one or more keys.\n", i+1);
			return 0;
		}
		if(!rs_add(text, join))
			return 0;
	}

	config_setting_t *channels_setting = config_lookup(&config, "channels");
	if(!config_setting_is_aggregate(channels_setting)) {
		fprintf(stderr, "Setting \"channels\" must be an aggregate type.\n");
		return 0;
	}

	int channel_count = config_setting_length(channels_setting);
	for(int i = 0; i < channel_count; i++) {
		config_setting_t *channel_setting = config_setting_get_elem(channels_setting, i);
		const char *name;
		if(!config_setting_lookup_string(channel_setting, "name", &name)) {
			char *sname;
			sname = malloc(sizeof(char) * 16);
			sprintf(sname, "channel #%d", i+1);
			name = sname;
		}
		printf("Channel %s\n", name);
		struct channel_t *channel;
		if(!(channel = channel_add(name))) {
			return 0;
		}
		config_setting_t *files = config_setting_get_member(channel_setting, "files");
		if(!config_setting_is_aggregate(files)) {
			fprintf(stderr, "Setting \"files\" must be an aggregate type (no files added).\n", name);
			continue;
		}
		int file_count = config_setting_length(files);
		/* Break if we can't set file count, most likely any following channels will also fail. */
		if(!channel_set_file_count(channel, file_count))
			break;
		/* Iterate through files. */
		for(int j = 0; j < file_count; j++) {
			const char *filepath;
			int rs_index;
			config_setting_t *file = config_setting_get_elem(files, j);
			/* (filepath, regexset) pair. */
			if(config_setting_is_aggregate(file)) {
				if(config_setting_length(file) != 2) {
					fprintf(stderr, "File lists must have exactly two elements.\n");
					continue;
				}
				config_setting_t *path_setting = config_setting_get_elem(file, 0);
				config_setting_t *rs_setting = config_setting_get_elem(file, 1);
				if(!(config_setting_type(path_setting) == CONFIG_TYPE_STRING && config_setting_type(rs_setting) == CONFIG_TYPE_INT)) {
					fprintf(stderr, "File lists must have a string and an integer.\n");
					continue;
				}
				filepath = config_setting_get_string(path_setting);
				rs_index = config_setting_get_int(rs_setting);
			} else { /* filepath only. */
				filepath = config_setting_get_string(file);
				rs_index = 0;
			}
			if(!channel_set_file(channel, j, filepath, rs_index)) {
				fprintf(stderr, "Failed to set file #%d (%s) for channel %s.\n", j+1, filepath, name);
			}
		}
	}

	return 1;
}

void cfg_free() {
	config_destroy(&config);
}