2010-10-03 [colin] 3.7.6cvs53
authorColin Leroy <colin@colino.net>
Sun, 3 Oct 2010 11:46:24 +0000 (11:46 +0000)
committerColin Leroy <colin@colino.net>
Sun, 3 Oct 2010 11:46:24 +0000 (11:46 +0000)
* src/folder.c
* src/folder.h
* src/imap.c
* src/mh.c
* src/procmsg.c
Get rid of GRelation which were, mostly, used as
GHashTables. Probably fixes bug #2277, 'Segfault when
loading inbox for the first time'

ChangeLog
PATCHSETS
configure.ac
src/folder.c
src/folder.h
src/imap.c
src/mh.c
src/procmsg.c

index 4c4a1a3..e89dea3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-10-03 [colin]     3.7.6cvs53
+
+       * src/folder.c
+       * src/folder.h
+       * src/imap.c
+       * src/mh.c
+       * src/procmsg.c
+               Get rid of GRelation which were, mostly, used as
+               GHashTables. Probably fixes bug #2277, 'Segfault when
+               loading inbox for the first time'
+
 2010-10-03 [mir]       3.7.6cvs52
 
        * manual/de/dist/html/Makefile.am
index 897b3a4..e6b7c7c 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.6 -r 1.1.2.7 manual/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/fr/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/pl/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/txt/Makefile.am;  ) > 3.7.6cvs50.patchset
 ( cvs diff -u -r 1.53.2.36 -r 1.53.2.37 po/POTFILES.in;  ) > 3.7.6cvs51.patchset
 ( cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.6 -r 1.1.2.7 manual/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/fr/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/txt/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/html/Makefile.am;  cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/pl/dist/pdf/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/ps/Makefile.am;  cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/txt/Makefile.am;  ) > 3.7.6cvs52.patchset
+( cvs diff -u -r 1.213.2.196 -r 1.213.2.197 src/folder.c;  cvs diff -u -r 1.87.2.61 -r 1.87.2.62 src/folder.h;  cvs diff -u -r 1.179.2.251 -r 1.179.2.252 src/imap.c;  cvs diff -u -r 1.79.2.69 -r 1.79.2.70 src/mh.c;  cvs diff -u -r 1.150.2.115 -r 1.150.2.116 src/procmsg.c;  ) > 3.7.6cvs53.patchset
index 1a2107b..9dfc299 100644 (file)
@@ -12,7 +12,7 @@ MINOR_VERSION=7
 MICRO_VERSION=6
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=52
+EXTRA_VERSION=53
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index 0ee5637..affd58a 100644 (file)
@@ -1883,7 +1883,7 @@ static gint folder_sort_folder_list(gconstpointer a, gconstpointer b)
 
 static gint syncronize_flags(FolderItem *item, MsgInfoList *msglist)
 {
-       GRelation *relation;
+       GHashTable *relation;
        gint ret = 0;
        GSList *cur;
 
@@ -1894,38 +1894,32 @@ static gint syncronize_flags(FolderItem *item, MsgInfoList *msglist)
        if (item->no_select)
                return 0;
 
-       relation = g_relation_new(2);
-       g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
+       relation = g_hash_table_new(g_direct_hash, g_direct_equal);
        if ((ret = item->folder->klass->get_flags(
            item->folder, item, msglist, relation)) == 0) {
-               GTuples *tuples;
+               gpointer data, old_key;
                MsgInfo *msginfo;
                MsgPermFlags permflags = 0;
-               gboolean skip;
 
                folder_item_update_freeze();
                folder_item_set_batch(item, TRUE);
                for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
                        msginfo = (MsgInfo *) cur->data;
                
-                       tuples = g_relation_select(relation, msginfo, 0);
-                       skip = tuples->len < 1;
-                       if (!skip)
-                               permflags = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
-                       g_tuples_destroy(tuples);
-                       if (skip)
-                               continue;
-                       
-                       if (msginfo->flags.perm_flags != permflags) {
-                               procmsg_msginfo_change_flags(msginfo,
-                                       permflags & ~msginfo->flags.perm_flags, 0,
-                                       ~permflags & msginfo->flags.perm_flags, 0);
+                       if (g_hash_table_lookup_extended(relation, msginfo, &old_key, &data)) {
+                               permflags = GPOINTER_TO_INT(data);
+
+                               if (msginfo->flags.perm_flags != permflags) {
+                                       procmsg_msginfo_change_flags(msginfo,
+                                               permflags & ~msginfo->flags.perm_flags, 0,
+                                               ~permflags & msginfo->flags.perm_flags, 0);
+                               }
                        }
                }
                folder_item_set_batch(item, FALSE);
                folder_item_update_thaw();
        }
-       g_relation_destroy(relation);   
+       g_hash_table_destroy(relation); 
 
        return ret;
 }
@@ -3123,7 +3117,7 @@ gint folder_item_add_msgs(FolderItem *dest, GSList *file_list,
         Folder *folder;
         gint ret, num, lastnum = -1;
        GSList *file_cur;
-       GRelation *relation;
+       GHashTable *relation;
        MsgFileInfo *fileinfo = NULL;
        gboolean folderscan = FALSE;
 
@@ -3135,13 +3129,12 @@ gint folder_item_add_msgs(FolderItem *dest, GSList *file_list,
 
         folder = dest->folder;
 
-       relation = g_relation_new(2);
-       g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
+       relation = g_hash_table_new(g_direct_hash, g_direct_equal);
 
        if (folder->klass->add_msgs != NULL) {
                ret = folder->klass->add_msgs(folder, dest, file_list, relation);
                if (ret < 0) {
-                       g_relation_destroy(relation);
+                       g_hash_table_destroy(relation);
                        return ret;
                }
        } else {
@@ -3150,20 +3143,21 @@ gint folder_item_add_msgs(FolderItem *dest, GSList *file_list,
 
                        ret = folder->klass->add_msg(folder, dest, fileinfo->file, fileinfo->flags);
                        if (ret < 0) {
-                               g_relation_destroy(relation);
+                               g_hash_table_destroy(relation);
                                return ret;
                        }
-                       g_relation_insert(relation, fileinfo, GINT_TO_POINTER(ret));
+                       g_hash_table_insert(relation, fileinfo, GINT_TO_POINTER(ret));
                }
        }
 
        for (file_cur = file_list; file_cur != NULL; file_cur = g_slist_next(file_cur)) {
-               GTuples *tuples;
+               gpointer data, old_key;
 
                fileinfo = (MsgFileInfo *) file_cur->data;
-               tuples = g_relation_select(relation, fileinfo, 0);
-               num = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
-               g_tuples_destroy(tuples);
+               if (g_hash_table_lookup_extended(relation, fileinfo, &old_key, &data))
+                       num = GPOINTER_TO_INT(data);
+               else
+                       num = -1;
 
                if (num >= 0) {
                        MsgInfo *newmsginfo;
@@ -3199,7 +3193,7 @@ gint folder_item_add_msgs(FolderItem *dest, GSList *file_list,
                }
        }
 
-       g_relation_destroy(relation);
+       g_hash_table_destroy(relation);
 
         return lastnum;
 }
@@ -3351,6 +3345,27 @@ gint folder_item_move_to(FolderItem *src, FolderItem *dest, FolderItem **new_ite
        return F_MOVE_OK;
 }
 
+struct find_data
+{
+       gboolean found;
+};     
+static void find_num(gpointer key, gpointer value, gpointer data)
+{
+       struct find_data *fdata = (struct find_data *)data;
+       if (GPOINTER_TO_INT(value) == 0)
+               fdata->found = TRUE;
+}
+
+static gboolean some_msgs_have_zero_num(GHashTable *hashtable)
+{
+       struct find_data fdata;
+       
+       fdata.found = FALSE;
+       g_hash_table_foreach(hashtable, find_num, &fdata);
+       
+       return fdata.found;
+}
+
 /**
  * Copy a list of message to a new folder and remove
  * source messages if wanted
@@ -3361,7 +3376,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
        GSList *l;
        gint num, lastnum = -1;
        gboolean folderscan = FALSE;
-       GRelation *relation;
+       GHashTable *relation;
        GSList *not_moved = NULL;
        gint total = 0, curmsg = 0;
        MsgInfo *msginfo = NULL;
@@ -3409,9 +3424,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
                return queue_err ? -1:0;
        }
 
-       relation = g_relation_new(2);
-       g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
-       g_relation_index(relation, 1, g_direct_hash, g_direct_equal);
+       relation = g_hash_table_new(g_direct_hash, g_direct_equal);
 
        for (l = msglist ; l != NULL ; l = g_slist_next(l)) {
                MsgInfo * msginfo = (MsgInfo *) l->data;
@@ -3430,7 +3443,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
         */
        if (folder->klass->copy_msgs != NULL) {
                if (folder->klass->copy_msgs(folder, dest, msglist, relation) < 0) {
-                       g_relation_destroy(relation);
+                       g_hash_table_destroy(relation);
                        return -1;
                }
        } else {
@@ -3441,7 +3454,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
                if (l != NULL) {
                        msginfo = (MsgInfo *) l->data;
                        if (msginfo != NULL && msginfo->folder == dest) {
-                               g_relation_destroy(relation);
+                               g_hash_table_destroy(relation);
                                return -1;
                        }
                }
@@ -3451,7 +3464,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
 
                        num = folder->klass->copy_msg(folder, dest, msginfo);
                        if (num > 0)
-                               g_relation_insert(relation, msginfo, GINT_TO_POINTER(num));
+                               g_hash_table_insert(relation, msginfo, GINT_TO_POINTER(num));
                        else
                                not_moved = g_slist_prepend(not_moved, msginfo);
                }
@@ -3472,20 +3485,14 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
                                                                relation);
                }
                for (l = msglist; l != NULL; l = g_slist_next(l)) {
-                       GTuples *tuples;
+                       gpointer old_key, data;
                        msginfo = (MsgInfo *) l->data;
                        item = msginfo->folder;
 
-                       tuples = g_relation_select(relation, msginfo, 0);
-                       if (tuples) {
-                               if (tuples->len)
-                                       num = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
-                               else
-                                       num = 0;
-                               g_tuples_destroy(tuples);
-                       } else {
+                       if (g_hash_table_lookup_extended(relation, msginfo, &old_key, &data))
+                               num = GPOINTER_TO_INT(data);
+                       else
                                num = -1;
-                       }
 
                        if (g_slist_find(not_moved, msginfo))
                                continue;
@@ -3509,7 +3516,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
         * Fetch new MsgInfos for new messages in dest folder,
         * add them to the msgcache and update folder message counts
         */
-       if (g_relation_count(relation, GINT_TO_POINTER(0), 1) > 0) {
+       if (some_msgs_have_zero_num(relation)) {
                folder_item_scan_full(dest, FALSE);
                folderscan = TRUE;
        }
@@ -3524,19 +3531,16 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
        folder_item_set_batch(dest, TRUE);
        for (l = msglist; l != NULL; l = g_slist_next(l)) {
                MsgInfo *msginfo = (MsgInfo *) l->data;
-                GTuples *tuples;
+                gpointer data, old_key;
 
                if (!msginfo)
                        continue;
-                tuples = g_relation_select(relation, msginfo, 0);
-               if (tuples && tuples->len > 0) {
-                       num = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
-                       g_tuples_destroy(tuples);
-               } else {
-                       num = 0;
-                       if (tuples)
-                               g_tuples_destroy(tuples);
-               }
+
+                if (g_hash_table_lookup_extended(relation, msginfo, &old_key, &data))
+                       num = GPOINTER_TO_INT(data);
+               else
+                       num = -1;
+
                statusbar_progress_all(curmsg++,total, 100);
                if (curmsg % 100 == 0)
                        GTK_EVENTS_FLUSH();
@@ -3590,7 +3594,7 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
        statusbar_progress_all(0,0,0);
        statusbar_pop_all();
 
-       g_relation_destroy(relation);
+       g_hash_table_destroy(relation);
        if (not_moved != NULL) {
                g_slist_free(not_moved);
                return -1;
index 602cd8e..3c500d7 100644 (file)
@@ -474,7 +474,7 @@ struct _FolderClass
        gint            (*add_msgs)             (Folder         *folder,
                                                 FolderItem     *dest,
                                                 GSList         *file_list,
-                                                GRelation      *relation);
+                                                GHashTable     *relation);
        /**
         * Copy a message to a FolderItem
         *
@@ -505,7 +505,7 @@ struct _FolderClass
        gint            (*copy_msgs)            (Folder         *folder,
                                                 FolderItem     *dest,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *relation);
+                                                GHashTable     *relation);
        /**
         * Remove a message from a \c FolderItem.
         *
@@ -520,7 +520,7 @@ struct _FolderClass
        gint            (*remove_msgs)          (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *relation);
+                                                GHashTable     *relation);
        gint            (*expunge)              (Folder         *folder,
                                                 FolderItem     *item);
        /**
@@ -578,7 +578,7 @@ struct _FolderClass
        gint            (*get_flags)            (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *msgflags);
+                                                GHashTable     *msgflags);
        
        /* Sets batch mode for a FolderItem. It means that numerous flags updates
         * could follow, and the FolderClass implementation can cache them in order
index 9620ce8..5eaf148 100644 (file)
@@ -212,7 +212,7 @@ static gint         imap_add_msg            (Folder         *folder,
 static gint    imap_add_msgs           (Folder         *folder, 
                                         FolderItem     *dest,
                                         GSList         *file_list,
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 
 static gint    imap_copy_msg           (Folder         *folder,
                                         FolderItem     *dest, 
@@ -220,7 +220,7 @@ static gint         imap_copy_msg           (Folder         *folder,
 static gint    imap_copy_msgs          (Folder         *folder, 
                                         FolderItem     *dest, 
                                         MsgInfoList    *msglist, 
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 
 static gint    imap_remove_msg         (Folder         *folder, 
                                         FolderItem     *item, 
@@ -228,7 +228,7 @@ static gint         imap_remove_msg         (Folder         *folder,
 static gint    imap_remove_msgs        (Folder         *folder, 
                                         FolderItem     *dest, 
                                         MsgInfoList    *msglist, 
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 static gint    imap_expunge            (Folder         *folder, 
                                         FolderItem     *dest);
 static gint    imap_remove_all_msg     (Folder         *folder, 
@@ -278,7 +278,7 @@ static FolderItem *imap_create_special_folder
 static gint imap_do_copy_msgs          (Folder         *folder,
                                         FolderItem     *dest,
                                         MsgInfoList    *msglist,
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 
 static void imap_delete_all_cached_messages    (FolderItem     *item);
 static void imap_set_batch             (Folder         *folder,
@@ -409,7 +409,7 @@ static void imap_change_flags                       (Folder         *folder,
 static gint imap_get_flags                     (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfoList    *msglist,
-                                                GRelation      *msgflags);
+                                                GHashTable     *msgflags);
 static gchar *imap_folder_get_path             (Folder         *folder);
 static gchar *imap_item_get_path               (Folder         *folder,
                                                 FolderItem     *item);
@@ -1577,7 +1577,7 @@ static gint imap_add_msg(Folder *folder, FolderItem *dest,
 }
 
 static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
-                  GRelation *relation)
+                  GHashTable *relation)
 {
        gchar *destdir;
        IMAPSession *session;
@@ -1672,7 +1672,7 @@ static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
                }
 
                if (relation != NULL)
-                       g_relation_insert(relation, fileinfo->msginfo != NULL ? 
+                       g_hash_table_insert(relation, fileinfo->msginfo != NULL ? 
                                          (gpointer) fileinfo->msginfo : (gpointer) fileinfo,
                                          GINT_TO_POINTER(new_uid));
                if (last_uid < new_uid) {
@@ -1732,7 +1732,7 @@ static GSList *flatten_mailimap_set(struct mailimap_set * set)
        return result;
 }
 static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest, 
-                             MsgInfoList *msglist, GRelation *relation)
+                             MsgInfoList *msglist, GHashTable *relation)
 {
        FolderItem *src;
        gchar *destdir;
@@ -1865,7 +1865,7 @@ static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
                
                if (hashval != NULL) {
                        gint num = GPOINTER_TO_INT(hashval);
-                       g_relation_insert(relation, msginfo,
+                       g_hash_table_insert(relation, msginfo,
                                          GINT_TO_POINTER(num));
                        if (num > last_num)
                                last_num = num;
@@ -1894,7 +1894,7 @@ static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
                                g_free(cache_path);
                        }
                } else
-                       g_relation_insert(relation, msginfo,
+                       g_hash_table_insert(relation, msginfo,
                                          GINT_TO_POINTER(0));
        }
        statusbar_pop_all();
@@ -1929,7 +1929,7 @@ static gint imap_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 }
 
 static gint imap_copy_msgs(Folder *folder, FolderItem *dest, 
-                   MsgInfoList *msglist, GRelation *relation)
+                   MsgInfoList *msglist, GHashTable *relation)
 {
        MsgInfo *msginfo;
        gint ret;
@@ -1947,7 +1947,7 @@ static gint imap_copy_msgs(Folder *folder, FolderItem *dest,
 
 
 static gint imap_do_remove_msgs(Folder *folder, FolderItem *dest, 
-                               MsgInfoList *msglist, GRelation *relation)
+                               MsgInfoList *msglist, GHashTable *relation)
 {
        gchar *destdir, *dir;
        GSList *numlist = NULL, *cur;
@@ -2027,7 +2027,7 @@ static gint imap_do_remove_msgs(Folder *folder, FolderItem *dest,
 }
 
 static gint imap_remove_msgs(Folder *folder, FolderItem *dest, 
-                   MsgInfoList *msglist, GRelation *relation)
+                   MsgInfoList *msglist, GHashTable *relation)
 {
        MsgInfo *msginfo;
 
@@ -4546,7 +4546,7 @@ typedef struct _get_flags_data {
        Folder *folder;
        FolderItem *item;
        MsgInfoList *msginfo_list;
-       GRelation *msgflags;
+       GHashTable *msgflags;
        gboolean full_search;
        gboolean done;
 } get_flags_data;
@@ -4557,7 +4557,7 @@ static /*gint*/ void *imap_get_flags_thread(void *data)
        Folder *folder = stuff->folder;
        FolderItem *fitem = (FolderItem *) stuff->item;
        MsgInfoList *msginfo_list = stuff->msginfo_list;
-       GRelation *msgflags = stuff->msgflags;
+       GHashTable *msgflags = stuff->msgflags;
        GSList *elem;
        carray * lep_uidtab;
        IMAPSession *session;
@@ -4821,7 +4821,7 @@ bail:
                        }
                }
 
-               g_relation_insert(msgflags, msginfo, GINT_TO_POINTER(flags));
+               g_hash_table_insert(msgflags, msginfo, GINT_TO_POINTER(flags));
        }
        
        if (got_alien_tags) {
@@ -4848,7 +4848,7 @@ bail:
 }
 
 static gint imap_get_flags(Folder *folder, FolderItem *item,
-                           MsgInfoList *msginfo_list, GRelation *msgflags)
+                           MsgInfoList *msginfo_list, GHashTable *msgflags)
 {
        gint result;
        get_flags_data *data = g_new0(get_flags_data, 1);
index 3cfa7a0..c0dfaf6 100644 (file)
--- a/src/mh.c
+++ b/src/mh.c
@@ -75,21 +75,21 @@ static gint     mh_add_msg          (Folder         *folder,
 static gint     mh_add_msgs            (Folder         *folder,
                                         FolderItem     *dest,
                                         GSList         *file_list,
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 static gint     mh_copy_msg            (Folder         *folder,
                                         FolderItem     *dest,
                                         MsgInfo        *msginfo);
 static gint    mh_copy_msgs            (Folder         *folder, 
                                         FolderItem     *dest, 
                                         MsgInfoList    *msglist, 
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 static gint     mh_remove_msg          (Folder         *folder,
                                         FolderItem     *item,
                                         gint            num);
 static gint    mh_remove_msgs          (Folder         *folder, 
                                         FolderItem     *item, 
                                         MsgInfoList    *msglist, 
-                                        GRelation      *relation);
+                                        GHashTable     *relation);
 static gint     mh_remove_all_msg      (Folder         *folder,
                                         FolderItem     *item);
 static gboolean mh_is_msg_changed      (Folder         *folder,
@@ -134,7 +134,7 @@ static int mh_item_close            (Folder         *folder,
                                         FolderItem     *item);
 #if 0
 static gint mh_get_flags               (Folder *folder, FolderItem *item,
-                                        MsgInfoList *msginfo_list, GRelation *msgflags);
+                                        MsgInfoList *msginfo_list, GHashTable *msgflags);
 #endif
 static void mh_write_sequences         (FolderItem     *item, gboolean remove_unseen);
 
@@ -401,7 +401,7 @@ static gint mh_add_msg(Folder *folder, FolderItem *dest, const gchar *file, MsgF
 } 
  
 static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list, 
-                 GRelation *relation)
+                 GHashTable *relation)
 { 
        gchar *destfile;
        GSList *cur;
@@ -435,7 +435,7 @@ static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
 #endif
 
                if (relation != NULL)
-                       g_relation_insert(relation, fileinfo, GINT_TO_POINTER(dest->last_num + 1));
+                       g_hash_table_insert(relation, fileinfo, GINT_TO_POINTER(dest->last_num + 1));
                g_free(destfile);
                dest->last_num++;
        }
@@ -456,7 +456,7 @@ static gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
 }
 
 static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist, 
-                        GRelation *relation)
+                        GHashTable *relation)
 {
        gboolean dest_need_scan = FALSE;
        gboolean src_need_scan = FALSE;
@@ -578,8 +578,12 @@ static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist,
                        if (filemode & S_IRGRP) filemode |= S_IWGRP;
                        if (filemode & S_IROTH) filemode |= S_IWOTH;
                }
-               if (relation)
-                       g_relation_insert(relation, msginfo, GINT_TO_POINTER(dest->last_num+1));
+               if (relation) {
+                       if (g_hash_table_lookup(relation, msginfo) != NULL)
+                               g_warning("already in : %p", msginfo);
+                       
+                       g_hash_table_insert(relation, msginfo, GINT_TO_POINTER(dest->last_num+1));
+               }
                g_free(srcfile);
                g_free(destfile);
                dest->last_num++;
@@ -640,7 +644,7 @@ static gint mh_remove_msg(Folder *folder, FolderItem *item, gint num)
 }
 
 static gint mh_remove_msgs(Folder *folder, FolderItem *item, 
-                   MsgInfoList *msglist, GRelation *relation)
+                   MsgInfoList *msglist, GHashTable *relation)
 {
        gboolean need_scan = FALSE;
        gchar *path, *file;
@@ -1239,104 +1243,6 @@ static gchar *get_unseen_seq_name(void)
        return seq_name;        
 }
 
-#if 0
-static gint mh_get_flags(Folder *folder, FolderItem *item,
-                           MsgInfoList *msginfo_list, GRelation *msgflags)
-{
-       gchar *mh_sequences_filename;
-       FILE *mh_sequences_file;
-       gchar buf[BUFFSIZE];
-       gchar *unseen_list = NULL;
-       gchar *path;
-       MsgInfoList *mcur = NULL;
-/*
-       GTimer *timer = g_timer_new();
-       g_timer_start(timer);
-*/
-       if (!item)
-               return 0;
-
-       /* don't update from .mh_sequences if the item's opened: mails may have
-        * been marked read/unread and it's not yet written in the file. */     
-       if (item->opened)
-               return 0;
-
-       path = folder_item_get_path(item);
-
-       mh_sequences_filename = g_strconcat(path, G_DIR_SEPARATOR_S,
-                                           ".mh_sequences", NULL);
-       g_free(path);
-       if ((mh_sequences_file = g_fopen(mh_sequences_filename, "r+b")) != NULL) {
-               while (fgets(buf, sizeof(buf), mh_sequences_file) != NULL) {
-                       if (!strncmp(buf, get_unseen_seq_name(), strlen(get_unseen_seq_name()))) {
-                               unseen_list = g_strdup(buf+strlen(get_unseen_seq_name()));
-                               break;
-                       }
-               }
-               fclose(mh_sequences_file);
-       }
-       
-       g_free(mh_sequences_filename);
-       
-       if (unseen_list) {
-               gchar *cur = NULL;
-               gchar *token = NULL, *next = NULL, *boundary = NULL;
-               gint num = 0;
-               GHashTable *unseen_table = g_hash_table_new(g_direct_hash, g_direct_equal);
-
-               cur = unseen_list = strretchomp(unseen_list);
-               debug_print("found unseen list in .mh_sequences: %s\n", unseen_list);
-next_token:
-               while (*cur && *cur == ' ')
-                       cur++;
-               
-               if ((next = strchr(cur, ' ')) != NULL) {
-                       token = cur;
-                       cur = next+1;
-                       *next = '\0';
-               } else {
-                       token = cur;
-                       cur = NULL;
-               }
-               
-               if ((boundary = strchr(token, '-')) != NULL) {
-                       gchar *start, *end;
-                       int i;
-                       start = token;
-                       end = boundary+1;
-                       *boundary='\0';
-                       for (i = atoi(start); i <= atoi(end); i++) {
-                               g_hash_table_insert(unseen_table, GINT_TO_POINTER(i), GINT_TO_POINTER(1));
-                       }
-               } else if ((num = atoi(token)) > 0) {
-                       g_hash_table_insert(unseen_table, GINT_TO_POINTER(num), GINT_TO_POINTER(1));
-               }
-               
-               if (cur)
-                       goto next_token;
-               for (mcur = msginfo_list; mcur; mcur = mcur->next) {
-                       MsgInfo *msginfo = (MsgInfo *)mcur->data;
-                       MsgPermFlags flags = msginfo->flags.perm_flags;
-                       if (g_hash_table_lookup(unseen_table, GINT_TO_POINTER(msginfo->msgnum))) {
-                               flags |= MSG_UNREAD;
-                       } else if (!(flags & MSG_NEW)) { /* don't mark new msgs as read */
-                               flags &= ~(MSG_UNREAD);
-                       }
-                       if (flags != msginfo->flags.perm_flags)
-                               g_relation_insert(msgflags, msginfo, GINT_TO_POINTER(flags));
-               }
-               g_hash_table_destroy(unseen_table);
-               g_free(unseen_list);
-       }
-/*
-       g_timer_stop(timer);
-       g_print("mh_get_flags: %f secs\n", g_timer_elapsed(timer, NULL));
-       g_timer_destroy(timer);
-*/
-       return 0;
-}
-#endif
-
 static void mh_write_sequences(FolderItem *item, gboolean remove_unseen)
 {
        gchar *mh_sequences_old, *mh_sequences_new;
index 1daa89a..4577c14 100644 (file)
@@ -98,21 +98,22 @@ struct MarkSum {
 /* CLAWS subject threading:
   
   in the first round it inserts subject lines in a 
-  relation (subject <-> node)
+  hashtable (subject <-> node)
 
   the second round finishes the threads by attaching
   matching subject lines to the one found in the
-  relation. will use the oldest node with the same
+  hashtable. will use the oldest node with the same
   subject that is not more then thread_by_subject_max_age
-  days old (see subject_relation_lookup)
+  days old (see subject_hashtable_lookup)
 */  
 
-static void subject_relation_insert(GRelation *relation, GNode *node)
+static void subject_hashtable_insert(GHashTable *hashtable, GNode *node)
 {
        gchar *subject;
        MsgInfo *msginfo;
+       GSList *list = NULL;
 
-       cm_return_if_fail(relation != NULL);
+       cm_return_if_fail(hashtable != NULL);
        cm_return_if_fail(node != NULL);
        msginfo = (MsgInfo *) node->data;
        cm_return_if_fail(msginfo != NULL);
@@ -120,19 +121,24 @@ static void subject_relation_insert(GRelation *relation, GNode *node)
        subject = msginfo->subject;
        if (subject == NULL)
                return;
+
        subject += subject_get_prefix_length(subject);
 
-       g_relation_insert(relation, subject, node);
+       list = g_hash_table_lookup(hashtable, subject);
+       list = g_slist_prepend(list, node);
+       g_hash_table_insert(hashtable, subject, list);
 }
 
-static GNode *subject_relation_lookup(GRelation *relation, MsgInfo *msginfo)
+static GNode *subject_hashtable_lookup(GHashTable *hashtable, MsgInfo *msginfo)
 {
        gchar *subject;
-       GTuples *tuples;
-       GNode *node = NULL;
+       GSList *list, *cur;
+       GNode *node = NULL, *hashtable_node = NULL;
        gint prefix_length;
+       MsgInfo *hashtable_msginfo = NULL, *best_msginfo = NULL;
+       gboolean match;
     
-       cm_return_val_if_fail(relation != NULL, NULL);
+       cm_return_val_if_fail(hashtable != NULL, NULL);
 
        subject = msginfo->subject;
        if (subject == NULL)
@@ -142,55 +148,52 @@ static GNode *subject_relation_lookup(GRelation *relation, MsgInfo *msginfo)
                return NULL;
        subject += prefix_length;
        
-       tuples = g_relation_select(relation, subject, 0);
-       if (tuples == NULL)
+       list = g_hash_table_lookup(hashtable, subject);
+       if (list == NULL)
                return NULL;
 
-       if (tuples->len > 0) {
-               int i;
-               GNode *relation_node;
-               MsgInfo *relation_msginfo = NULL, *best_msginfo = NULL;
-               gboolean match;
-
-               /* check all nodes with the same subject to find the best parent */
-               for (i = 0; i < tuples->len; i++) {
-                       relation_node = (GNode *) g_tuples_index(tuples, i, 1);
-                       relation_msginfo = (MsgInfo *) relation_node->data;
+       /* check all nodes with the same subject to find the best parent */
+       for (cur = list; cur; cur = cur->next) {
+               hashtable_node = (GNode *)cur->data;
+               hashtable_msginfo = (MsgInfo *) hashtable_node->data;
+               match = FALSE;
+
+               /* best node should be the oldest in the found nodes */
+               /* parent node must not be older then msginfo */
+               if ((hashtable_msginfo->date_t < msginfo->date_t) &&
+                   ((best_msginfo == NULL) ||
+                    (best_msginfo->date_t > hashtable_msginfo->date_t)))
+                       match = TRUE;
+
+               /* parent node must not be more then thread_by_subject_max_age
+                  days older then msginfo */
+               if (abs(difftime(msginfo->date_t, hashtable_msginfo->date_t)) >
+                    prefs_common.thread_by_subject_max_age * 3600 * 24)
                        match = FALSE;
 
-                       /* best node should be the oldest in the found nodes */
-                       /* parent node must not be older then msginfo */
-                       if ((relation_msginfo->date_t < msginfo->date_t) &&
-                           ((best_msginfo == NULL) ||
-                            (best_msginfo->date_t > relation_msginfo->date_t)))
-                               match = TRUE;
-
-                       /* parent node must not be more then thread_by_subject_max_age
-                          days older then msginfo */
-                       if (abs(difftime(msginfo->date_t, relation_msginfo->date_t)) >
-                            prefs_common.thread_by_subject_max_age * 3600 * 24)
-                               match = FALSE;
-
-                       /* can add new tests for all matching
-                          nodes found by subject */
-
-                       if (match) {
-                               node = relation_node;
-                               best_msginfo = relation_msginfo;
-                       }
-               }           
+               /* can add new tests for all matching
+                  nodes found by subject */
+
+               if (match) {
+                       node = hashtable_node;
+                       best_msginfo = hashtable_msginfo;
+               }
        }
 
-       g_tuples_destroy(tuples);
        return node;
 }
 
+static void subject_hashtable_free(gpointer key, gpointer value, gpointer data)
+{
+       g_slist_free(value);
+}
+
 /* return the reversed thread tree */
 GNode *procmsg_get_thread_tree(GSList *mlist)
 {
        GNode *root, *parent, *node, *next;
        GHashTable *msgid_table;
-       GRelation *subject_relation = NULL;
+       GHashTable *subject_hashtable = NULL;
        MsgInfo *msginfo;
        const gchar *msgid;
         GSList *reflist;
@@ -199,8 +202,7 @@ GNode *procmsg_get_thread_tree(GSList *mlist)
        msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
        
        if (prefs_common.thread_by_subject) {
-               subject_relation = g_relation_new(2);
-               g_relation_index(subject_relation, 0, g_str_hash, g_str_equal);
+               subject_hashtable = g_hash_table_new(g_str_hash, g_str_equal);
        }
 
        for (; mlist != NULL; mlist = mlist->next) {
@@ -219,9 +221,9 @@ GNode *procmsg_get_thread_tree(GSList *mlist)
                if ((msgid = msginfo->msgid) && g_hash_table_lookup(msgid_table, msgid) == NULL)
                        g_hash_table_insert(msgid_table, (gchar *)msgid, node);
 
-               /* CLAWS: add subject to relation (without prefix) */
+               /* CLAWS: add subject to hashtable (without prefix) */
                if (prefs_common.thread_by_subject) {
-                       subject_relation_insert(subject_relation, node);
+                       subject_hashtable_insert(subject_hashtable, node);
                }
        }
 
@@ -261,7 +263,7 @@ GNode *procmsg_get_thread_tree(GSList *mlist)
                        next = node->next;
                        msginfo = (MsgInfo *) node->data;
                        
-                       parent = subject_relation_lookup(subject_relation, msginfo);
+                       parent = subject_hashtable_lookup(subject_hashtable, msginfo);
                        
                        /* the node may already be threaded by IN-REPLY-TO, so go up 
                         * in the tree to 
@@ -284,7 +286,10 @@ GNode *procmsg_get_thread_tree(GSList *mlist)
        }
        
        if (prefs_common.thread_by_subject)
-               g_relation_destroy(subject_relation);
+       {
+               g_hash_table_foreach(subject_hashtable, subject_hashtable_free, NULL);
+               g_hash_table_destroy(subject_hashtable);
+       }
 
        g_hash_table_destroy(msgid_table);
        END_TIMING();
@@ -1131,7 +1136,8 @@ void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline)
 
        g_strchomp(buf);
        if (buf[strlen(buf) - 1] != '&') strcat(buf, "&");
-       system(buf);
+       if (system(buf) == -1)
+               g_warning("system(%s) failed.", buf);
 }
 
 MsgInfo *procmsg_msginfo_new_ref(MsgInfo *msginfo)