aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog21
-rw-r--r--camel/camel-folder.c5
-rw-r--r--camel/camel-mime-utils.c38
-rw-r--r--camel/camel-mime-utils.h2
-rw-r--r--camel/camel-search-private.c174
5 files changed, 229 insertions, 11 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index c042c728b5..49d31e26a7 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,24 @@
+2001-02-06 Not Zed <NotZed@Ximian.com>
+
+ * camel-search-private.c: Removed unwanted header. It was never
+ put in for a reason. Stop fixing irrelevant warnings.
+
+ (camel_ustrstrcase): Our own strstrcase impl for utf8 strings.
+ (camel_ustrcasecmp): Ditto for strcasecmp.
+ (camel_ustrncasecmp): And strncasecmp.
+ (utf8_get): Simpler interface to utf8 string processing.
+ (camel_search_header_match): Use the new things.
+
+2001-02-05 Not Zed <NotZed@Ximian.com>
+
+ * camel-folder.c (get_summary): Removed some old variables/a small
+ memleak.
+ (free_summary): Removed old variables.
+
+ * camel-mime-utils.c (header_raw_check_mailing_list): New utility
+ function to get the mailing list (if any) that a set of headers
+ came from.
+
2001-02-05 Christopher James Lahey <clahey@helixcode.com>
* camel-stream-fs.c: Added a missing #include.
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index 17d65097b5..e9d72d879d 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -924,9 +924,6 @@ camel_folder_free_uids (CamelFolder *folder, GPtrArray *array)
static GPtrArray *
get_summary(CamelFolder *folder)
{
- GPtrArray *res = g_ptr_array_new();
- int i, count;
-
g_assert(folder->summary != NULL);
return camel_folder_summary_array(folder->summary);
@@ -957,8 +954,6 @@ camel_folder_get_summary (CamelFolder *folder)
static void
free_summary(CamelFolder *folder, GPtrArray *summary)
{
- int i;
-
g_assert(folder->summary != NULL);
camel_folder_summary_array_free(folder->summary, summary);
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 0b77dbe9c8..7b63baae14 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -41,6 +41,8 @@
#include <ctype.h>
#include <errno.h>
+#include <regex.h>
+
#include "camel-mime-utils.h"
#include "camel-charset-map.h"
@@ -2892,6 +2894,42 @@ header_raw_clear(struct _header_raw **list)
*list = NULL;
}
+static struct {
+ char *name;
+ char *pattern;
+} mail_list_magic[] = {
+ { "Sender", "^Sender: owner-([^@]+)" },
+ { "X-BeenThere", "^X-BeenThere: ([^@]+)" },
+ { "Delivered-To", "^Delivered-To: mailing list ([^@]+)" },
+ { "X-Mailing-List", "^X-Mailing-List: ([^@]+)" },
+ { "X-Loop", "^X-Loop: ([^@]+)" },
+ { "List-Id", "^List-Id: ([^<]+)" },
+};
+
+char *
+header_raw_check_mailing_list(struct _header_raw **list)
+{
+ const char *v;
+ regex_t pattern;
+ regmatch_t match[1];
+ int i;
+
+ for (i=0;i<sizeof(mail_list_magic)/sizeof(mail_list_magic[0]);i++) {
+ if (regcomp(&pattern, mail_list_magic[i].pattern, REG_EXTENDED|REG_ICASE) == -1) {
+ g_warning("Internal error, compiling regex failed: %s: %s", mail_list_magic[i].pattern, strerror(errno));
+ continue;
+ }
+
+ v = header_raw_find(list, mail_list_magic[i].name, NULL);
+ if (v != NULL && regexec(&pattern, v, 1, match, 0) == 0 && match[0].rm_so != -1) {
+ regfree(&pattern);
+ return g_strndup(v+match[0].rm_so, match[0].rm_eo-match[0].rm_so);
+ }
+ regfree(&pattern);
+ }
+
+ return NULL;
+}
/* ok, here's the address stuff, what a mess ... */
struct _header_address *header_address_new(void)
diff --git a/camel/camel-mime-utils.h b/camel/camel-mime-utils.h
index 2e478066fc..e37589d4a9 100644
--- a/camel/camel-mime-utils.h
+++ b/camel/camel-mime-utils.h
@@ -142,6 +142,8 @@ void header_raw_remove(struct _header_raw **list, const char *name);
void header_raw_fold(struct _header_raw **list);
void header_raw_clear(struct _header_raw **list);
+char *header_raw_check_mailing_list(struct _header_raw **list);
+
/* fold a header */
char *header_fold(const char *in, int headerlen);
char *header_unfold(const char *in);
diff --git a/camel/camel-search-private.c b/camel/camel-search-private.c
index e000bcd776..1162986af2 100644
--- a/camel/camel-search-private.c
+++ b/camel/camel-search-private.c
@@ -30,13 +30,12 @@
#include <ctype.h>
#include <stdio.h>
-#include <gal/widgets/e-unicode.h>
-
#include "camel-exception.h"
#include "camel-mime-message.h"
#include "camel-multipart.h"
#include "camel-stream-mem.h"
#include "e-util/e-sexp.h"
+#include <unicode.h>
#include "camel-search-private.h"
@@ -183,6 +182,169 @@ header_soundex(const char *header, const char *match)
return truth;
}
+static guint16 utf8_get(const char **inp)
+{
+ guint32 c, v = 0, s, shift;
+ const unsigned char *p = *inp;
+
+ if (p == NULL)
+ return 0;
+
+ s = *p++;
+ if ((s & 0x80) == 0) { /* 7 bit char */
+ v = s;
+ } else if (s>0xf7) { /* invalid char, we can only have upto 4 bits encoded */
+ p = NULL;
+ } else if (s>=0xc0) { /* valid start char */
+ shift = 0;
+ do {
+ c = *p++;
+ if ((c & 0xc0) == 0x80) {
+ v = (v<<6) | (c&0x3f);
+ shift += 5;
+ } else {
+ *inp = NULL;
+ return 0;
+ }
+ s <<= 1;
+ } while ((s & 0x80) != 0);
+ v |= s << shift;
+ } else { /* invalid start char, internal char */
+ p = NULL;
+ }
+
+ *inp = p;
+ return v;
+}
+
+static const char *
+camel_ustrstrcase(const char *haystack, const char *needle)
+{
+ unicode_char_t *uni, *puni, *suni, u, v;
+ const char *p, *s, *l;
+
+ if (haystack == NULL || needle == NULL)
+ return NULL;
+
+ if (needle[0] == 0)
+ return haystack;
+
+ if (haystack[0] == 0)
+ return NULL;
+
+ puni = uni = alloca(sizeof(*uni)*(strlen(needle)+1));
+ p = needle;
+ while ((u = utf8_get(&p)))
+ *puni++ = unicode_tolower(u);
+
+ if (p == NULL)
+ return NULL;
+
+ l = p = haystack;
+ while ( (u = utf8_get(&p)) ) {
+ v = unicode_tolower(u);
+ if (uni[0] == v) {
+ s = p;
+ suni = uni+1;
+ while (suni < puni) {
+ u = utf8_get(&s);
+ v = unicode_tolower(u);
+ if (v != *suni)
+ goto next;
+ suni++;
+ }
+ return l;
+ }
+ next:
+ l = p;
+ }
+
+ return NULL;
+}
+
+static int
+camel_ustrcasecmp(const char *s1, const char *s2)
+{
+ guint16 u1, u2=0;
+
+ if (s1 == NULL) {
+ if (s2 == NULL)
+ return 0;
+ else
+ return -1;
+ }
+ if (s2 == NULL)
+ return 1;
+
+ while ((u1 = utf8_get(&s1)) && (u2 = utf8_get(&s2))) {
+ u1 = unicode_tolower(u1);
+ u2 = unicode_tolower(u2);
+ if (u1 < u2)
+ return -1;
+ else if (u1 > u2)
+ return 1;
+ }
+
+ /* if we have invalid utf8 sequence ? */
+ if (s2 == NULL || s1 == NULL)
+ return 1;
+
+ if (u1 == 0) {
+ if (u2 == 0)
+ return 0;
+ else
+ return -1;
+ }
+ if (u2 == 0)
+ return 1;
+
+ return 0;
+}
+
+static int
+camel_ustrncasecmp(const char *s1, const char *s2, size_t len)
+{
+ guint16 u1, u2=0;
+
+ if (s1 == NULL) {
+ if (s2 == NULL)
+ return 0;
+ else
+ return -1;
+ }
+ if (s2 == NULL)
+ return 1;
+
+ while (len > 0 && (u1 = utf8_get(&s1)) && (u2 = utf8_get(&s2))) {
+ u1 = unicode_tolower(u1);
+ u2 = unicode_tolower(u2);
+ if (u1 < u2)
+ return -1;
+ else if (u1 > u2)
+ return 1;
+ len--;
+ }
+
+ if (len == 0)
+ return 0;
+
+ /* if we have invalid utf8 sequence ? */
+ if (s2 == NULL || s1 == NULL)
+ return 1;
+
+ if (u1 == 0) {
+ if (u2 == 0)
+ return 0;
+ else
+ return -1;
+ }
+ if (u2 == 0)
+ return 1;
+
+ return 0;
+}
+
+
/* searhces for match inside value, if match is mixed case, hten use case-sensitive,
else insensitive */
gboolean camel_search_header_match(const char *value, const char *match, camel_search_match_t how)
@@ -221,13 +383,13 @@ gboolean camel_search_header_match(const char *value, const char *match, camel_s
}
switch(how) {
case CAMEL_SEARCH_MATCH_EXACT:
- return strcasecmp(value, match) == 0;
+ return camel_ustrcasecmp(value, match) == 0;
case CAMEL_SEARCH_MATCH_CONTAINS:
- return e_utf8_strstrcase(value, match) != NULL;
+ return camel_ustrstrcase(value, match) != NULL;
case CAMEL_SEARCH_MATCH_STARTS:
- return strncasecmp(value, match, strlen(match)) == 0;
+ return camel_ustrncasecmp(value, match, strlen(match)) == 0;
case CAMEL_SEARCH_MATCH_ENDS:
- return strcasecmp(value+strlen(value)-strlen(match), match) == 0;
+ return camel_ustrcasecmp(value+strlen(value)-strlen(match), match) == 0;
default:
break;
}