#include #include #include #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; } 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); /* 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_file_add(channel, 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); }