#include #include #include #include #include #include #include "config.h" #include "regexset.h" #include "channel.h" #include "user.h" #include "word.h" #include "export_xml.h" #include "nick.h" #define NICK_BUFFER_SIZE 0x100 #define TEXT_BUFFER_SIZE 0x400 #define LINE_BUFFER_SIZE 0x400 #define TIME_BUFFER_SIZE 0xf int main(int argc, char **argv) { /* Set locale. */ setlocale(LC_CTYPE, ""); /* Regex sets must be initialized before config. */ rs_init(); channel_init(); nick_init(); if(!cfg_init()) { /* Free any registered regex sets and channels when config fails. Config will fail if a regex set fails to compile all parts. */ rs_free(); channel_free(); return 1; } /* Parsing stuff goes here. */ for(int chan_i = 0; chan_i < channel_get_count(); chan_i++) { user_init(); word_init(); struct channel_t *channel = channel_get(chan_i); printf("Channel %s\n", channel->name); struct channel_file_t *file = channel->files; while(file) { struct regexset_t *rs = file->rs; FILE *f = fopen(file->path, "r"); if(!f) { fprintf(stderr, "\tFailed to open %s\n", file->path); file = file->next; continue; } else printf("\tParsing %s\n", file->path); char line[LINE_BUFFER_SIZE]; while(fgets(line, LINE_BUFFER_SIZE, f)) { int rc; int ovector[30]; rc = pcre_exec(rs->text, rs->text_e, line, strlen(line), 0, 0, ovector, 30); if(rc > 0) { char nick[NICK_BUFFER_SIZE], text[TEXT_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; pcre_copy_named_substring(rs->text, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); pcre_copy_named_substring(rs->text, line, ovector, rc, "text", text, TEXT_BUFFER_SIZE); pcre_copy_named_substring(rs->text, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); pcre_copy_named_substring(rs->text, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); struct user_t *user = user_get(nick); /* Calculate array index for lines. */ int hour, min, time_i; hour = atoi(hour_s); min = atoi(min_s); time_i = hour*4 + min / 15; user->lines[time_i]++; channel->hours[time_i]++; /* Count words. */ wchar_t wtext[TEXT_BUFFER_SIZE]; mbstowcs(wtext, text, TEXT_BUFFER_SIZE); wchar_t word[TEXT_BUFFER_SIZE]; wchar_t *end = wcschr(wtext, '\0'); *word = '\0'; int len = 0; for(wchar_t *pos = wtext; pos < end; pos++) { if(iswblank(*pos)) { if(len) { user->words++; word[len] = '\0'; char mbword[TEXT_BUFFER_SIZE]; wcstombs(mbword, word, TEXT_BUFFER_SIZE); struct word_t *word_s = word_get(mbword); word_s->count++; } len = 0; *word = '\0'; } else if(iswalpha(*pos)) { word[len++] = towlower(*pos); } else { len = 0; *word = '\0'; } } if(len) { user->words++; word[len] = '\0'; char mbword[TEXT_BUFFER_SIZE]; wcstombs(mbword, word, TEXT_BUFFER_SIZE); struct word_t *word_s = word_get(mbword); word_s->count++; } continue; } rc = pcre_exec(rs->join, rs->join_e, line, strlen(line), 0, 0, ovector, 30); if(rc > 0) { char nick[NICK_BUFFER_SIZE]; pcre_copy_named_substring(rs->join, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); struct user_t *user = user_get(nick); continue; } } fclose(f); file = file->next; } export_xml(channel, users); user_free(); word_free(); } nick_free(); cfg_free(); channel_free(); rs_free(); return 0; }