Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / core / nicklist.c
index 96f6a8ea2b870e7398d338d6506e06aa522f07d3..c38df6d47e7984908edad27adefa0d1011a91003 100644 (file)
@@ -13,9 +13,9 @@
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 #include "module.h"
@@ -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);
@@ -351,19 +357,33 @@ GSList *nicklist_get_same_unique(SERVER_REC *server, void *id)
 }
 
 /* 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 i;
+
        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->prefixes[0] == p2->prefixes[0])
+               return g_strcasecmp(p1->nick, p2->nick);
+
+       if (!p1->prefixes[0])
+               return 1;
+       if (!p2->prefixes[0])
+               return -1;
 
-       if (!p1->op) {
-               if (p1->voice && !p2->voice) return -1;
-               if (!p1->voice && p2->voice) return 1;
+       /* They aren't equal.  We've taken care of that already.
+        * The first one we encounter in this list is the greater.
+        */
+
+       for (i = 0; nick_prefix[i] != '\0'; i++) {
+               if (p1->prefixes[0] == nick_prefix[i])
+                       return -1;
+               if (p2->prefixes[0] == nick_prefix[i])
+                       return 1;
        }
 
+       /* we should never have gotten here... */
        return g_strcasecmp(p1->nick, p2->nick);
 }
 
@@ -507,10 +527,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 +547,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++;
                        }
 
@@ -555,9 +575,13 @@ int nick_match_msg(CHANNEL_REC *channel, const char *msg, const char *nick)
        if (fullmatch)
                return TRUE; /* matched without fuzzyness */
 
-       /* matched with some fuzzyness .. check if there's an exact match
-          for some other nick in the same channel. */
-        return nick_nfind(channel, msgstart, (int) (msg-msgstart)) == NULL;
+       if (channel != NULL) {
+               /* matched with some fuzzyness .. check if there's an exact match
+                  for some other nick in the same channel. */
+               return nick_nfind(channel, msgstart, (int) (msg-msgstart)) == NULL;
+       } else {
+               return TRUE;
+       }
 }
 
 void nicklist_init(void)