]> Pileus Git - ~andy/lamechat/blobdiff - chat.c
Refactor chat.
[~andy/lamechat] / chat.c
diff --git a/chat.c b/chat.c
index e35271a9b6470daea18c1a8ebf912c6b613443eb..4aa4ce63abd84d044949ecae6ddd57f0307b49a9 100644 (file)
--- a/chat.c
+++ b/chat.c
 #include "view.h"
 
 /* Global data */
-log_t *chat_log;
-int    chat_len;
+server_t  *servers;
+channel_t *channels;
+message_t *messages;
+int        history;
 
 /* Local data */
-static buf_t log_buf;
+static buf_t srv_buf;
+static buf_t chan_buf;
+static buf_t msg_buf;
 
-/* Local functions */
+static const char *proto_map[] = {
+       [IRC]  "irc",
+       [XMPP] "xmpp",
+};
 
 /* View init */
 void chat_init(void)
 {
-       chat_log = (log_t*)log_buf.data;
-       chat_len = 0;
+       servers  = (server_t*)srv_buf.data;
+       channels = (channel_t*)chan_buf.data;
+       messages = (message_t*)msg_buf.data;
+       history  = 0;
 
        irc_init();
        xmpp_init();
@@ -47,8 +56,61 @@ void chat_init(void)
 
 void chat_config(const char *group, const char *name, const char *key, const char *value)
 {
-       irc_config(group, name, key, value);
-       xmpp_config(group, name, key, value);
+       int        protocol = -1;
+       server_t  *server   = NULL;
+       channel_t *channel  = NULL;
+
+       if (match(group, "server")) {
+               server = find_server(name);
+               if (match(key, "")) {
+                       get_name(name);
+               }
+               else if (match(key, "protocol")) {
+                       protocol = get_enum(value, proto_map, N_ELEMENTS(proto_map));
+                       server = add_server(name, protocol);
+               }
+               else if (server) {
+                       protocol = server->protocol;
+               }
+               else {
+                       error("No server found for [%s]", name);
+               }
+       }
+
+       if (match(group, "channel")) {
+               channel = find_channel(name);
+               if (match(key, "")) {
+                       get_name(name);
+               }
+               else if (match(key, "server")) {
+                       server = find_server(get_string(value));
+                       if (!server)
+                               error("server '%s' does not exist", name);
+                       channel = add_channel(name, server);
+                       protocol = server->protocol;
+                       server = NULL;
+               }
+               else if (channel) {
+                       protocol = channel->server->protocol;
+               }
+               else {
+                       error("No channel found for [%s]", name);
+               }
+       }
+
+       debug("chat_config: [%s-%s \"%s\"] %s = %s",
+                       protocol>=0 ? proto_map[protocol] : "none",
+                       group, name, key, value,
+                       server, channel);
+
+       switch (protocol) {
+               case IRC:
+                       irc_config(server, channel, group, name, key, value);
+                       break;
+               case XMPP:
+                       xmpp_config(server, channel, group, name, key, value);
+                       break;
+       }
 }
 
 void chat_notice(const char *channel, const char *from, const char *fmt, ...)
@@ -63,35 +125,38 @@ void chat_notice(const char *channel, const char *from, const char *fmt, ...)
        chat_recv(channel, from, buf);
 }
 
-void chat_recv(const char *channel, const char *from, const char *msg)
+void chat_recv(const char *channel, const char *from, const char *text)
 {
-       append(&log_buf, NULL, sizeof(log_t));
-       chat_log = (log_t*)log_buf.data;
+       append(&msg_buf, NULL, sizeof(message_t));
+       messages = (message_t*)msg_buf.data;
 
-       log_t *log = &chat_log[chat_len];
-       log->when = time(NULL);
-       log->from = strcopy(from);
-       log->channel = strcopy(channel);
-       log->msg  = strcopy(msg);
+       message_t *msg = &messages[history];
+       msg->channel = find_channel(channel);
+       msg->when = time(NULL);
+       msg->from = strcopy(from);
+       msg->text = strcopy(text);
 
-       chat_len++;
+       history++;
        view_draw();
 }
 
-void chat_send(const char *channel, const char *msg)
+void chat_send(const char *channel_name, const char *text)
 {
-       append(&log_buf, NULL, sizeof(log_t));
-       chat_log = (log_t*)log_buf.data;
-
-       log_t *log = &chat_log[chat_len];
-       log->when = time(NULL);
-       log->from = "andy";
-       log->channel = strcopy(channel);
-       log->msg  = strcopy(msg);
-
-       chat_len++;
-       irc_send(channel, msg);
-       xmpp_send(channel, msg);
+       channel_t *channel = find_channel(channel_name);
+
+       append(&msg_buf, NULL, sizeof(message_t));
+       messages = (message_t*)msg_buf.data;
+
+       message_t *msg = &messages[history];
+       msg->channel = channel;
+       msg->when = time(NULL);
+       msg->from = strcopy("andy");
+       msg->text = strcopy(text);
+       history++;
+
+       irc_send(msg);
+       xmpp_send(msg);
+
        view_draw();
 }
 
@@ -100,7 +165,62 @@ void chat_exit(void)
        irc_exit();
        xmpp_exit();
 
-       for (int i = 0; i < chat_len; i++)
-               free((void*)chat_log[i].msg);
-       release(&log_buf);
+       for (int i = 0; i < history; i++)
+               free((void*)messages[i].text);
+       release(&msg_buf);
 }
+
+/* Server and channel function */
+server_t *add_server(const char *name, protocol_t protocol)
+{
+       server_t *server = NULL;
+       debug("adding %s server \"%s\"", proto_map[protocol], name);
+       switch (protocol) {
+               case IRC:
+                       server = irc_server();
+                       break;
+               case XMPP:
+                       server = xmpp_server();
+                       break;
+       }
+       server->next = servers;
+       server->name = strcopy(name);
+       server->protocol = protocol;
+       return (servers = server);
+}
+
+channel_t *add_channel(const char *name, server_t *server)
+{
+       channel_t *channel = NULL;
+       debug("adding %s channel \"%s\"", server->name, name);
+       switch (server->protocol) {
+               case IRC:
+                       channel = irc_channel();
+                       break;
+               case XMPP:
+                       channel = xmpp_channel();
+                       break;
+       }
+       channel->next = channels;
+       channel->name = strcopy(name);
+       channel->server = server;
+       return (channels = channel);
+}
+
+server_t *find_server(const char *name)
+{
+       for (server_t *cur = servers; cur; cur = cur->next)
+               if (match(cur->name, name))
+                       return cur;
+       return NULL;
+}
+
+channel_t *find_channel(const char *name)
+{
+       for (channel_t *cur = channels; cur; cur = cur->next) {
+               if (match(cur->name, name))
+                       return cur;
+       }
+       return NULL;
+}
+