diff --git a/.gitignore b/.gitignore index 5f6b0d0..c8db801 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .gdb_history *.o +*.out hibot diff --git a/source/bot.h b/source/bot.h index 3b32323..283b781 100644 --- a/source/bot.h +++ b/source/bot.h @@ -6,7 +6,6 @@ #include #include #include -#include extern syntax_setter_t syntax_functions[]; @@ -31,111 +30,30 @@ char * username_root(const char * const fullname){ return r; } -typedef struct { - int is_active; - char * user; - language_t language; - struct itimerval timer; - char * buffer[128]; // XXX: no overflow detection/avertion - unsigned int buffer_head; // is implemented on this bunch -} request_t; - -void init_request(request_t * request) { - request->is_active = 0; - request->timer.it_value.tv_sec = 0; - request->timer.it_value.tv_usec = 0; - request->timer.it_interval.tv_sec = 0; - request->timer.it_interval.tv_usec = 0; - request->buffer_head = 0; +void on_request_timeout(int unused) { + (void)(unused); + drop_request(request_queue[0]); } -request_t request_queue__[message_queue_size]; -request_t * request_queue[message_queue_size]; -unsigned int request_queue_head = 0; - -static inline -void touch_request_timer(request_t * request) { - request->timer.it_value.tv_sec = message_timeout; - setitimer(ITIMER_REAL, &(request->timer), NULL); -} - -void activate_request(request_t * request) { - request->is_active = 1; - - /* message header */ +void flush_request(request_t * request) { + // Message header char * short_name = username_root(request->user); irc_message(short_name); free(short_name); -} -request_t * take_request(const char * const user, language_t language) { - for (unsigned int i = 0; i < request_queue_head; i++) { - if(!strcmp(request_queue[i]->user, user)) { - return request_queue[i]; - } - } + // Message body + syntax_count = 0; + syntax_functions[request->language](); + for (unsigned i = 0; i < request->buffer_head; i++) { + irc_message(syntax_highlight(request->buffer[i])); + } - if (request_queue_head == message_queue_size) { - return NULL; - } - - request_t * request = request_queue[request_queue_head]; - - request->language = language; - request->user = strdup(user); - - if (request_queue_head == 0) { - activate_request(request); - } - - ++request_queue_head; - - char * log_message; - asprintf(&log_message, "Took message: %p (%d)", (void*)request, request_queue_head); - log_notice(log_message); - free(log_message); - - return request; -} - -void drop_reqest() { - request_t * request = request_queue[0]; - - if (message_queue_size > 1) { - for (unsigned int i = 0; i < request_queue_head; i++) { - request_queue[i] = request_queue[i+1]; - } - request_queue[request_queue_head] = request; - } - - --request_queue_head; - - request->is_active = 0; - free(request->user); - - if (request_queue_head) { - activate_request(request_queue[0]); - for (unsigned int i = 0; i < request_queue[0]->buffer_head; i++) { - irc_message(request_queue[0]->buffer[i]); - free(request_queue[0]->buffer[i]); - } - request_queue[0]->buffer_head = 0; - touch_request_timer(request_queue[0]); - } - - char * log_message; - asprintf(&log_message, "Dropped message: %p (%d)", (void*)request, request_queue_head); - log_notice(log_message); - free(log_message); -} - -void on_message_timeout(int unused) { - (void)unused; - - /* message footer */ + // Message footer irc_message("--"); - drop_reqest(request_queue); + logf_notice("Flushed message: %p (%d)", (void*)request, request_queue_head); + + drop_request(request); } static @@ -165,6 +83,7 @@ void irc_help() { irc_message(" ! // set language for next message"); irc_message(" // echo this code"); irc_message(" ! // set language and echo code"); + irc_message(" !-- // flush all code"); irc_message("--"); } @@ -182,10 +101,7 @@ void event_connect(irc_session_t * session, log_notice("IRC connection secured."); irc_cmd_join(session, channel, 0); - char * buffer; - asprintf(&buffer, "Joined destination channel: `%s`.", channel); - log_notice(buffer); - free(buffer); + logf_notice("Joined destination channel: `%s`.", channel); } static @@ -194,6 +110,7 @@ void event_disconnect(irc_session_t * session, const char * origin, const char ** params, unsigned int count) { + (void)session; (void)event; (void)origin; (void)params; @@ -218,6 +135,11 @@ void event_privmsg(irc_session_t * session, /* Is command */ if (*message == '!') { + if (!strcmp(message, "!help")) { + irc_help(); + goto END; + } + /* */ terminator = message; while (*terminator != ' ') { if (*terminator == '\0') { @@ -227,38 +149,39 @@ void event_privmsg(irc_session_t * session, ++terminator; } *terminator = '\0'; - /* */ - if (!strcmp(message, "!help")) { - irc_help(); - goto END; - } - /* get language */ - for (char * s = message + 1; *s != '\0'; s++) { - *s = toupper(*s); - } - int l = translate_language(message + 1); - message = terminator + 1; - if (l != -1) { - language = l; - syntax_count = 0; - syntax_functions[language](); - } + /* */ + { + request_t * request = take_request(origin); + + if (!strcmp(message, "!--")) { + if (request) { + flush_request(request); + } + goto END; + } + + /* get language */ + for (char * s = message + 1; *s != '\0'; s++) { + *s = toupper(*s); + } + int l = translate_language(message + 1); + message = terminator + 1; + if (l != -1) { + request->language = l; + } + } } /* Is code */ if (is_code) { - request_t * request = take_request(origin, language); + request_t * request = take_request(origin); if (!request) { irc_private_message(origin, message_queue_full_message); goto END; } - if (request->is_active) { - touch_request_timer(request); - irc_message(syntax_highlight(message)); - } else { - request->buffer[request->buffer_head++] = strdup(syntax_highlight(message)); - } + touch_request_timer(request); + request->buffer[request->buffer_head++] = strdup(message); } END: @@ -302,7 +225,7 @@ int connect_bot(const char * const server, const short port) { request_queue[i] = &request_queue__[i]; init_request(request_queue[i]); } - signal(SIGALRM, on_message_timeout); + signal(SIGALRM, on_request_timeout); irc_connect(session, server, diff --git a/source/config.inc b/source/config.inc index a9de7c4..43ae521 100644 --- a/source/config.inc +++ b/source/config.inc @@ -2,7 +2,7 @@ const char * const username = PROGRAM_NAME; const char * const password = ""; -const int message_timeout = 3; +const int message_timeout = 10; const char * const message_queue_full_message = "Air space too crowded in this area."; #define message_queue_size 3 #define DEFAULT_LANGUAGE C diff --git a/source/log.h b/source/log.h index 8e894b9..d359f04 100644 --- a/source/log.h +++ b/source/log.h @@ -1,6 +1,8 @@ #ifndef LOG_H #include +#include +#include FILE * log_file; @@ -13,12 +15,32 @@ void log(const char * const message, const char * const color) { } void log_notice(const char * const message) { - log("", message); + log("", message); +} + +void logf_notice(const char * const format, ...) { + va_list args; + va_start(args, format); + + char * msg; + vasprintf(&msg, format, args); + log_notice(msg); + free(msg); } void log_error(const char * const message) { log("\033[33m", message); } +void logf_error(const char * const format, ...) { + va_list args; + va_start(args, format); + + char * msg; + vasprintf(&msg, format, args); + log_error(msg); + free(msg); +} + #define LOG_H #endif diff --git a/source/main.c b/source/main.c index ac48db9..f8d6c5e 100644 --- a/source/main.c +++ b/source/main.c @@ -14,12 +14,11 @@ typedef enum { ADA, } language_t; -language_t language = DEFAULT_LANGUAGE; - typedef void (*syntax_setter_t)(void); #include "log.h" #include "syntax.h" +#include "request.h" #include "bot.h" syntax_setter_t syntax_functions[] = { @@ -55,7 +54,7 @@ signed main(int argc, char * * argv) { log_file = LOG_FILE; - syntax_functions[language](); + syntax_functions[DEFAULT_LANGUAGE](); connect_bot(server, port_i); connection_loop(); diff --git a/source/request.h b/source/request.h new file mode 100644 index 0000000..dba5846 --- /dev/null +++ b/source/request.h @@ -0,0 +1,83 @@ +#ifndef REQUEST_H +#define REQUEST_H + +#include +#include + +typedef struct { + char * user; + language_t language; + struct itimerval timer; + char * buffer[128]; // XXX: no overflow detection/avertion + unsigned int buffer_head; // is implemented on this bunch +} request_t; + +request_t request_queue__[message_queue_size]; +request_t * request_queue[message_queue_size]; +unsigned int request_queue_head = 0; + +static inline +void init_request(request_t * request) { + request->timer.it_value.tv_sec = 0; + request->timer.it_value.tv_usec = 0; + request->timer.it_interval.tv_sec = 0; + request->timer.it_interval.tv_usec = 0; + request->language = DEFAULT_LANGUAGE; + request->buffer_head = 0; +} + +static inline +void reinit_request(request_t * request) { + free(request->user); + for (long i = 0; i < request->buffer_head; i++) { + free(request->buffer[i]); + } + init_request(request); +} + +static inline +void touch_request_timer(request_t * const request) { + request->timer.it_value.tv_sec = message_timeout; + setitimer(ITIMER_REAL, &(request->timer), NULL); +} + +request_t * take_request(const char * const user) { + for (unsigned int i = 0; i < request_queue_head; i++) { + if(!strcmp(request_queue[i]->user, user)) { + return request_queue[i]; + } + } + + if (request_queue_head == message_queue_size) { + return NULL; + } + + request_t * request = request_queue[request_queue_head]; + + request->user = strdup(user); + + ++request_queue_head; + + logf_notice("Took message: %p (%d)", (void*)request, request_queue_head); + + return request; +} + +void drop_request(request_t * const request) { + setitimer(ITIMER_REAL, NULL, NULL); + + reinit_request(request); + + if (message_queue_size > 1) { + for (unsigned int i = 0; i < request_queue_head; i++) { + request_queue[i] = request_queue[i+1]; + } + request_queue[request_queue_head] = request; + } + + --request_queue_head; + + logf_notice("Dropped message: %p (%d)", (void*)request, request_queue_head); +} + +#endif diff --git a/source/syntax.h b/source/syntax.h index 32c2378..ead5fae 100644 --- a/source/syntax.h +++ b/source/syntax.h @@ -210,7 +210,8 @@ void syntax_cpp (void) { char * specials [] = { "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", - "FILE", "std", "typeof", "cout", "cin", "endl", "timespec", "tm" + "FILE", "std", "typeof", "cout", "cin", "endl", "timespec", "tm", + "vector", "stack", "map", "unordered_map", "queue", "deque", /* TODO: I don't really care about this, but some people do, Anon please add what you find interesting in here... */ };