From 98595a88a89b634febe3c9302162bb2bed748b55 Mon Sep 17 00:00:00 2001 From: Melvin Hadasht Date: Sat, 29 Dec 2001 05:29:09 +0000 Subject: [PATCH] Improved subject simplification by regexp. --- ChangeLog.claws | 16 +++++++ configure.in | 2 +- src/prefs_folder_item.h | 3 ++ src/string_match.c | 102 +++++++++++++++------------------------- src/string_match.h | 27 ++++++----- src/summaryview.c | 69 ++++++++++++++++++--------- 6 files changed, 121 insertions(+), 98 deletions(-) diff --git a/ChangeLog.claws b/ChangeLog.claws index 5165891fb..0216d27af 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,19 @@ +2001-12-29 [melvin] 0.6.6claws30 + + * src/string_match.[ch] + Optimized a bit: regexp pattern buffer compiled only once, and + one subroutine call removed. Fixed ^ regexp search: Now, + "(^Re: )|(^Hello)" removes only "Re: " from "Re: Hello". + + * src/summaryview.c + Subject filtering changed to filter summary columns and + not directly the messages subject cache. The loss in + performance is balanced by the improvement of string_match. + Added an alert panel if there is an error in the regexp. + + * src/src/prefs_folder_item.h + Added a regexp pattern buffer. + 2001-12-28 [alfons] 0.6.6claws29 * src/string_match.[ch] diff --git a/configure.in b/configure.in index 909692a8e..2a42e2997 100644 --- a/configure.in +++ b/configure.in @@ -8,7 +8,7 @@ MINOR_VERSION=6 MICRO_VERSION=6 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=claws29 +EXTRA_VERSION=claws30 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION dnl diff --git a/src/prefs_folder_item.h b/src/prefs_folder_item.h index 0892293f6..a39fc48e1 100644 --- a/src/prefs_folder_item.h +++ b/src/prefs_folder_item.h @@ -23,6 +23,8 @@ #include "folder.h" #include +#include +#include struct _PrefsFolderItem { gchar * directory; @@ -49,6 +51,7 @@ struct _PrefsFolderItem { gchar *default_to; gboolean enable_simplify_subject; gchar *simplify_subject_regexp; + regex_t *simplify_subject_preg; gboolean enable_folder_chmod; gint folder_chmod; gboolean enable_default_account; diff --git a/src/string_match.c b/src/string_match.c index a70366606..0517e4fbb 100644 --- a/src/string_match.c +++ b/src/string_match.c @@ -1,6 +1,7 @@ /* * Sylpheed -- regexp pattern matching utilities * Copyright (C) 2001 Thomas Link, Hiroyuki Yamamoto + * Modified by Melvin Hadasht. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,80 +18,55 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include -#include +#include "intl.h" #include "string_match.h" -/* the size used for regexec in string_remove_match */ -#define STRING_MATCH_MR_SIZE 30 - - -static int string_match_regexp (char * txt, char * rexp, - int size, regmatch_t matches[], - int cflags, int eflags); - -int string_remove_match(char *txt, char *rexp, int cflags, int eflags) +int string_match_precompile (gchar *rexp, regex_t *preg, int cflags) { - regmatch_t matches[STRING_MATCH_MR_SIZE]; - int foundp; + int problem = 0; - g_return_val_if_fail(txt, -1); g_return_val_if_fail(rexp, -1); + g_return_val_if_fail(*rexp, -1); - if (strlen(txt) > 0 && strlen(rexp) > 0) { - foundp = string_match_regexp(txt, rexp, STRING_MATCH_MR_SIZE, - matches, cflags, eflags); - } else { - return -1; - } - - if (foundp && matches[0].rm_so != -1 && matches[0].rm_eo != -1) { - if (matches[0].rm_so == matches[0].rm_eo) { - /* in case the match is an empty string */ - return matches[0].rm_so + 1; - } else { - strcpy(txt + matches[0].rm_so, txt + matches[0].rm_eo); - return matches[0].rm_so; - } - } else { - return -1; - } + problem = regcomp(preg, rexp, cflags); + + return problem; } -int string_remove_all_matches(char *txt, char *rexp, int cflags, int eflags) -{ - int pos = 0; - int pos0 = pos; - - g_return_val_if_fail(txt, 0); - g_return_val_if_fail(rexp, 0); - - while (pos0 >= 0 && pos < strlen(txt) && strlen(txt) > 0) { - /* printf("%s %d:%d\n", txt, pos0, pos); */ - pos0 = string_remove_match(txt + pos, rexp, cflags, eflags); - if (pos0 >= 0) { - pos = pos + pos0; - } - } - return pos; -} -static int string_match_regexp(char * txt, char * rexp, - int size, regmatch_t matches[], - int cflags, int eflags) +gchar *string_remove_match(gchar *buf, gint buflen, gchar * txt, regex_t *preg) { - regex_t re; - int problem; - - g_return_val_if_fail(txt, 0); - g_return_val_if_fail(rexp, 0); + regmatch_t match; + int notfound; + gint i, j ,k; - problem = regcomp(&re, rexp, cflags); - if (problem == 0) { - problem = regexec(&re, txt, size, matches, eflags); + if (!preg) + return txt; + if (*txt != 0x00) { + i = 0; + j = 0; + do { + notfound = regexec(preg, txt+j, 1, &match, (j ? REG_NOTBOL : 0)); + if (notfound) { + while (txt[j] && i < buflen -1) + buf[i++] = txt[j++]; + } else { + if ( match.rm_so == match.rm_eo) + buf[i++] = txt[j++]; + else { + k = j; + while (txt[j] && j != k + match.rm_so) + buf[i++] = txt[j++]; + if (txt[j]) + j = k + match.rm_eo; + } + } + } while (txt[j] && i < buflen - 1); + buf[i] = 0x00; + if (buf[0] == 0x00) + strcpy(buf, _("(Subject cleared by regexp)")); + return buf; } - regfree(&re); - return problem == 0; + return txt; } diff --git a/src/string_match.h b/src/string_match.h index 0bd5f78be..86793bd3c 100644 --- a/src/string_match.h +++ b/src/string_match.h @@ -1,6 +1,7 @@ /* * Sylpheed -- regexp pattern matching utilities * Copyright (C) 2001 Thomas Link, Hiroyuki Yamamoto + * Modified by Melvin Hadasht. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,22 +18,24 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #ifndef STRING_MATCH_H__ #define STRING_MATCH_H__ -/* remove substring matching REXP from TXT. Destructive! */ -/* for documentation of CFLAGS and EFLAGS see "man regex" */ -/* returns -1 = not found; N = next find pos */ -/* if the match is an empty string (e.g. "x\?"), the find position will - be increased by 1 */ -int string_remove_match (char *txt, char *rexp, int cflags, int eflags); +#include +#include +#include -/* remove all substrings matching REXP from TXT. Destructive! */ -/* for documentation of CFLAGS and EFLAGS see "man regex" */ -/* returns position of last replacement (i.e. TXT has been modified up - to this position, use this as the starting point for further mangling) */ -int string_remove_all_matches (char *txt, char *rexp, int cflags, int eflags); +/* Precompile the preg buffer for the rexp regexp string. See regex man for the + * meaning of cflags. + */ +int string_match_precompile (gchar *rexp, regex_t *preg, int cflags); -#endif /* STRING_MATCH_H__ */ +/* remove from txt the substrings matching the regexp in the precompiled preg buffer. + * The result is stored in the preallocated buf buffer which maximal length + * is buflen. + */ +gchar *string_remove_match(gchar *buf, gint buflen, gchar * txt, regex_t *preg); +#endif /* STRING_MATCH_H__ */ diff --git a/src/summaryview.c b/src/summaryview.c index 367b0029c..bfdb89766 100644 --- a/src/summaryview.c +++ b/src/summaryview.c @@ -16,7 +16,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "defs.h" #include @@ -199,6 +198,7 @@ static void summary_display_msg (SummaryView *summaryview, static void summary_toggle_view (SummaryView *summaryview); static void summary_set_row_marks (SummaryView *summaryview, GtkCTreeNode *row); +static void summaryview_subject_filter_init (PrefsFolderItem *prefs); /* message handling */ static void summary_mark_row (SummaryView *summaryview, @@ -819,14 +819,6 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item, mlist = not_killed; } - if (item->prefs->enable_simplify_subject - && item->prefs->simplify_subject_regexp != NULL - && strlen(item->prefs->simplify_subject_regexp) != 0) { - summary_simplify_subject(summaryview, - item->prefs->simplify_subject_regexp, - mlist); - } - STATUSBAR_POP(summaryview->mainwin); /* set ctree and hash table from the msginfo list @@ -2012,6 +2004,8 @@ static void summary_set_ctree_from_list(SummaryView *summaryview, summaryview->important_score = summaryview->folder_item->prefs->important_score; } + + summaryview_subject_filter_init(summaryview->folder_item->prefs); if (summaryview->folder_item->threaded) { GNode *root, *gnode; @@ -2194,6 +2188,8 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[], static gchar *from_name = NULL; static gchar col_number[11]; static gchar col_score[11]; + static gchar buf[BUFFSIZE]; + PrefsFolderItem *prefs = summaryview->folder_item->prefs; gint *col_pos = summaryview->col_pos; text[col_pos[S_COL_MARK]] = NULL; @@ -2253,8 +2249,16 @@ static void summary_set_header(SummaryView *summaryview, gchar *text[], } } - text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? msginfo->subject : - _("(No Subject)"); + if (prefs->enable_simplify_subject + && prefs->simplify_subject_preg != NULL ) + text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? + string_remove_match(buf, BUFFSIZE, msginfo->subject, + prefs->simplify_subject_preg) : + + _("(No Subject)"); + else + text[col_pos[S_COL_SUBJECT]] = msginfo->subject ? msginfo->subject : + _("(No Subject)"); } #define CHANGE_FLAGS(msginfo) \ @@ -3650,17 +3654,6 @@ static void summary_unthread_for_exec_func(GtkCTree *ctree, GtkCTreeNode *node, } } -void summary_simplify_subject(SummaryView *summaryview, gchar * rexp, - GSList * mlist) -{ - GSList * cur; - for(cur = mlist ; cur != NULL ; cur = cur->next) { - MsgInfo * msginfo = (MsgInfo *) cur->data; - string_remove_all_matches(msginfo->subject, rexp, - REG_EXTENDED, 0); - } -} - void summary_processing(SummaryView *summaryview, GSList * mlist) { GSList * processing_list; @@ -4956,6 +4949,38 @@ static void summary_set_hide_read_msgs_menu (SummaryView *summaryview, gtk_object_set_data(GTK_OBJECT(widget), "dont_toggle", GINT_TO_POINTER(0)); } +static void summaryview_subject_filter_init(PrefsFolderItem *prefs) +{ + int err; + gchar buf[BUFFSIZE]; + if (prefs->enable_simplify_subject) { + if (prefs->simplify_subject_regexp && + *prefs->simplify_subject_regexp != 0x00) { + + if (!prefs->simplify_subject_preg) + prefs->simplify_subject_preg = g_new(regex_t, 1); + else + regfree(prefs->simplify_subject_preg); + + err = string_match_precompile(prefs->simplify_subject_regexp, + prefs->simplify_subject_preg, REG_EXTENDED); + if (err) { + regerror(err, prefs->simplify_subject_preg, buf, BUFFSIZE); + alertpanel_error(_("Regular expression (regexp) error:\n%s"), buf); + g_free(prefs->simplify_subject_preg); + prefs->simplify_subject_preg = NULL; + } + } else { + if (prefs->simplify_subject_preg) { + regfree(prefs->simplify_subject_preg); + g_free(prefs->simplify_subject_preg); + prefs->simplify_subject_preg = NULL; + } + } + } +} + + /* * End of Source. */ -- 2.25.1