diff options
Diffstat (limited to 'parsing.c')
-rw-r--r-- | parsing.c | 260 |
1 files changed, 208 insertions, 52 deletions
@@ -2,7 +2,7 @@ #include <string.h> #include <wctype.h> #include <wchar.h> -#include <pthread.h> +#include <errno.h> #include "parsing.h" #include "channel.h" @@ -15,29 +15,54 @@ #define TEXT_BUFFER_SIZE 0x400 #define LINE_BUFFER_SIZE 0x400 #define TIME_BUFFER_SIZE 0xf +#define DATE_BUFFER_SIZE 0x20 -static pthread_mutex_t user_mutex, word_mutex, channel_mutex; +#define max(a, b) ((a) > (b) ? (a) : (b)) static struct user_t *last_user = NULL; static int in_monolog = 0, monolog_len = 0; +static struct tm now_global; + static inline void add_word(struct user_t *user, wchar_t *word, int len) { - pthread_mutex_lock(&user_mutex); user->words++; - pthread_mutex_unlock(&user_mutex); word[len] = '\0'; char mbword[TEXT_BUFFER_SIZE]; wcstombs(mbword, word, TEXT_BUFFER_SIZE); - pthread_mutex_lock(&word_mutex); struct word_t *word_s = word_get(mbword); word_s->count++; - pthread_mutex_unlock(&word_mutex); +} + +static inline char *parse_getline(char *buffer, int bufsize, FILE *f) { + char *r; + + r = fgets(buffer, bufsize, f); + + return r; } static void process_file(FILE *f, struct channel_t *channel, struct regexset_t *rs) { char line[LINE_BUFFER_SIZE]; + const char *log_date_format, *day_date_format; + struct tm now; + + if(rs->log_date_format) { + log_date_format = rs->log_date_format; + } else if(ircstats_config.log_date_format) { + log_date_format = ircstats_config.log_date_format; + } else { + log_date_format = NULL; + } - while(fgets(line, LINE_BUFFER_SIZE, f)) { + if(rs->day_date_format) { + day_date_format = rs->day_date_format; + } else if(ircstats_config.day_date_format) { + day_date_format = ircstats_config.day_date_format; + } else { + day_date_format = NULL; + } + + while(parse_getline(line, LINE_BUFFER_SIZE, f)) { int rc; int ovector[30]; @@ -48,7 +73,6 @@ static void process_file(FILE *f, struct channel_t *channel, struct regexset_t * 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); - pthread_mutex_lock(&user_mutex); struct user_t *user = user_get(nick); if(user == last_user) { monolog_len++; @@ -65,7 +89,6 @@ static void process_file(FILE *f, struct channel_t *channel, struct regexset_t * in_monolog = 0; monolog_len = 1; } - pthread_mutex_unlock(&user_mutex); /* Calculate array index for lines. */ int hour, min, time_i; @@ -77,14 +100,21 @@ static void process_file(FILE *f, struct channel_t *channel, struct regexset_t * wchar_t wtext[TEXT_BUFFER_SIZE]; mbstowcs(wtext, text, TEXT_BUFFER_SIZE); - pthread_mutex_lock(&user_mutex); + now = now_global; + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + user->characters += wcslen(wtext); user->lines[time_i]++; - pthread_mutex_unlock(&user_mutex); - pthread_mutex_lock(&channel_mutex); + if(user->seen_first == 0 || now_ut < user->seen_first) { + user->seen_first = now_ut; + } + user->seen_last = max(now_ut, user->seen_last); + channel->hours[time_i]++; - pthread_mutex_unlock(&channel_mutex); wchar_t word[TEXT_BUFFER_SIZE]; wchar_t *end = wcschr(wtext, '\0'); @@ -112,47 +142,187 @@ static void process_file(FILE *f, struct channel_t *channel, struct regexset_t * rc = pcre_exec(rs->join, rs->join_e, line, strlen(line), 0, 0, ovector, 30); if(rc > 0) { - char nick[NICK_BUFFER_SIZE]; + char nick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; pcre_copy_named_substring(rs->join, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); - pthread_mutex_lock(&user_mutex); + pcre_copy_named_substring(rs->join, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->join, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + now = now_global; + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + struct user_t *user = user_get(nick); - pthread_mutex_unlock(&user_mutex); + + if(user->seen_first == 0 || now_ut < user->seen_first) { + user->seen_first = now_ut; + } + user->seen_last = max(now_ut, user->seen_last); + + continue; + } + + rc = pcre_exec(rs->part, rs->part_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char nick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->part, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->part, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->part, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + now = now_global; + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + struct user_t *user = user_get(nick); + + if(user->seen_first == 0 || now_ut < user->seen_first) { + user->seen_first = now_ut; + } + user->seen_last = max(now_ut, user->seen_last); + + continue; + } + + rc = pcre_exec(rs->quit, rs->quit_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char nick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->quit, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->quit, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->quit, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + now = now_global; + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + struct user_t *user = user_get(nick); + + if(user->seen_first == 0 || now_ut < user->seen_first) { + user->seen_first = now_ut; + } + user->seen_last = max(now_ut, user->seen_last); + + continue; + } + + rc = pcre_exec(rs->nick_changed, rs->nick_changed_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char newnick[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "new_nick", newnick, NICK_BUFFER_SIZE); + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->nick_changed, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + now = now_global; + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + + struct user_t *user = user_get(newnick); + + if(user->seen_first == 0 || now_ut < user->seen_first) { + user->seen_first = now_ut; + } + user->seen_last = max(now_ut, user->seen_last); + + continue; + } + + rc = pcre_exec(rs->log_opened, rs->log_opened_e, line, strlen(line), 0, 0, ovector, 30); + if(rc > 0) { + char date[DATE_BUFFER_SIZE]; + + if(!log_date_format) { + continue; + } + + pcre_copy_named_substring(rs->log_opened, line, ovector, rc, "date", date, DATE_BUFFER_SIZE); + + if(!strptime(date, log_date_format, &now)) { + fprintf(stderr, "log fail: %s\n", date); + continue; + } + + now_global = now; + + continue; + } + + /* day_changed is optional */ + rc = rs->day_changed ? pcre_exec(rs->day_changed, rs->day_changed_e, line, strlen(line), 0, 0, ovector, 30) : 0; + if(rc > 0) { + char date[DATE_BUFFER_SIZE]; + + if(!day_date_format) { + continue; + } + + pcre_copy_named_substring(rs->day_changed, line, ovector, rc, "date", date, DATE_BUFFER_SIZE); + + if(!strptime(date, day_date_format, &now)) { + fprintf(stderr, "day fail: %s\n", date); + continue; + } + + now_global = now; + continue; } rc = pcre_exec(rs->kick, rs->kick_e, line, strlen(line), 0, 0, ovector, 30); if(rc > 0) { - char nick[NICK_BUFFER_SIZE], victim[NICK_BUFFER_SIZE]; + char nick[NICK_BUFFER_SIZE], victim[NICK_BUFFER_SIZE], hour_s[TIME_BUFFER_SIZE], min_s[TIME_BUFFER_SIZE]; + pcre_copy_named_substring(rs->kick, line, ovector, rc, "hour", hour_s, TIME_BUFFER_SIZE); + pcre_copy_named_substring(rs->kick, line, ovector, rc, "minute", min_s, TIME_BUFFER_SIZE); pcre_copy_named_substring(rs->kick, line, ovector, rc, "nick", nick, NICK_BUFFER_SIZE); pcre_copy_named_substring(rs->kick, line, ovector, rc, "victim", victim, NICK_BUFFER_SIZE); - pthread_mutex_lock(&user_mutex); + + int hour, min; + hour = atoi(hour_s); + min = atoi(min_s); + + now = now_global; + + now.tm_hour = hour; + now.tm_min = min; + time_t now_ut = mktime(&now); + struct user_t *user = user_get(nick), *victim_user = user_get(victim); user->kicks++; victim_user->kicked++; - pthread_mutex_unlock(&user_mutex); + + if(user->seen_first == 0 || now_ut < user->seen_first) { + user->seen_first = now_ut; + } + user->seen_last = max(now_ut, user->seen_last); + continue; } } } -struct thread_arg_t { - FILE *f; - struct channel_t *channel; - struct regexset_t *rs; -}; - -static void *thread_func(void *arg) { - struct thread_arg_t *ta = arg; - process_file(ta->f, ta->channel, ta->rs); - - return NULL; -} - -void process(int thread_n) { - pthread_mutex_init(&user_mutex, NULL); - pthread_mutex_init(&word_mutex, NULL); - pthread_mutex_init(&channel_mutex, NULL); +void process() { /* Parsing stuff goes here. */ for(int chan_i = 0; chan_i < channel_get_count(); chan_i++) { user_init(); @@ -173,28 +343,14 @@ void process(int thread_n) { last_user = NULL; in_monolog = monolog_len = 0; - pthread_t *threads; - threads = malloc(sizeof(pthread_t) * thread_n); - struct thread_arg_t ta; - ta.f = f; - ta.channel = channel; - ta.rs = rs; - for(int i = 0; i < thread_n; i++) { - pthread_create(&threads[i], NULL, thread_func, &ta); - } - for(int i = 0; i < thread_n; i++) { - pthread_join(threads[i], NULL); - } - free(threads); + process_file(f, channel, rs); fclose(f); file = file->next; } + export_xml(channel, users); user_free(); word_free(); } - pthread_mutex_destroy(&user_mutex); - pthread_mutex_destroy(&word_mutex); - pthread_mutex_destroy(&channel_mutex); } |