Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / core / nicklist.c
index 96f6a8ea2b870e7398d338d6506e06aa522f07d3..4f322bf55a5dd225030d3a473b0b0f3a1e75a2ef 100644 (file)
@@ -28,7 +28,7 @@
 #include "masks.h"
 
 #define isalnumhigh(a) \
-        (isalnum(a) || (unsigned char) (a) >= 128)
+        (i_isalnum(a) || (unsigned char) (a) >= 128)
 
 static void nick_hash_add(CHANNEL_REC *channel, NICK_REC *nick)
 {
@@ -76,6 +76,8 @@ static void nick_hash_remove(CHANNEL_REC *channel, NICK_REC *nick)
 /* Add new nick to list */
 void nicklist_insert(CHANNEL_REC *channel, NICK_REC *nick)
 {
+       /*MODULE_DATA_INIT(nick);*/
+
        nick->type = module_get_uniq_id("NICK", 0);
         nick->chat_type = channel->chat_type;
 
@@ -100,6 +102,10 @@ static void nicklist_destroy(CHANNEL_REC *channel, NICK_REC *nick)
 {
        signal_emit("nicklist remove", 2, channel, nick);
 
+       if (channel->ownnick == nick)
+                channel->ownnick = NULL;
+
+        /*MODULE_DATA_DEINIT(nick);*/
        g_free(nick->nick);
        g_free_not_null(nick->realname);
        g_free_not_null(nick->host);
@@ -350,20 +356,56 @@ GSList *nicklist_get_same_unique(SERVER_REC *server, void *id)
        return rec.list;
 }
 
+#if GLIB_MAJOR_VERSION < 2
+/* glib1 doesn't have g_slist_sort_with_data, so non-standard prefixes won't be sorted correctly */
+int nicklist_compare_glib1(NICK_REC *p1, NICK_REC *p2)
+{
+       return nicklist_compare(p1, p2, NULL);
+}
+#endif
+
 /* nick record comparision for sort functions */
-int nicklist_compare(NICK_REC *p1, NICK_REC *p2)
+int nicklist_compare(NICK_REC *p1, NICK_REC *p2, const char *nick_prefix)
 {
+       int status1, status2;
+       
        if (p1 == NULL) return -1;
        if (p2 == NULL) return 1;
 
-       if (p1->op && !p2->op) return -1;
-       if (!p1->op && p2->op) return 1;
-
-       if (!p1->op) {
-               if (p1->voice && !p2->voice) return -1;
-               if (!p1->voice && p2->voice) return 1;
-       }
-
+       /* we assign each status (op, halfop, voice, normal) a number
+        * and compare them. this is easier than 100,000 if's and
+        * returns :-)
+        * -- yath */
+
+       if (p1->other) {
+               const char *other = (nick_prefix == NULL) ? NULL : strchr(nick_prefix, p1->other);
+               status1 = (other == NULL) ? 5 : 1000 - (other - nick_prefix);
+       } else if (p1->op)
+               status1 = 4;
+       else if (p1->halfop)
+               status1 = 3;
+       else if (p1->voice)
+               status1 = 2;
+       else
+               status1 = 1;
+
+       if (p2->other) {
+               const char *other = (nick_prefix == NULL) ? NULL : strchr(nick_prefix, p2->other);
+               status2 = (other == NULL) ? 5 : 1000 - (other - nick_prefix);
+       } else if (p2->op)
+               status2 = 4;
+       else if (p2->halfop)
+               status2 = 3;
+       else if (p2->voice)
+               status2 = 2;
+       else
+               status2 = 1;
+       
+       if (status1 < status2)
+               return 1;
+       else if (status1 > status2)
+               return -1;
+       
        return g_strcasecmp(p1->nick, p2->nick);
 }
 
@@ -507,10 +549,10 @@ int nick_match_msg(CHANNEL_REC *channel, const char *msg, const char *nick)
 
                /* check if it matches for alphanumeric parts of nick */
                while (*nick != '\0' && *msg != '\0') {
-                       if (toupper(*nick) == toupper(*msg)) {
+                       if (i_toupper(*nick) == i_toupper(*msg)) {
                                /* total match */
                                msg++;
-                       } else if (isalnum(*msg) && !isalnum(*nick)) {
+                       } else if (i_isalnum(*msg) && !i_isalnum(*nick)) {
                                /* some strange char in your nick, pass it */
                                 fullmatch = FALSE;
                        } else
@@ -527,7 +569,7 @@ int nick_match_msg(CHANNEL_REC *channel, const char *msg, const char *nick)
                                /* remove the rest of the non-alphanum chars
                                   from nick and check if it then matches. */
                                 fullmatch = FALSE;
-                               while (*nick != '\0' && !isalnum(*nick))
+                               while (*nick != '\0' && !i_isalnum(*nick))
                                        nick++;
                        }