diff options
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 21 | ||||
-rw-r--r-- | camel/camel-folder.c | 5 | ||||
-rw-r--r-- | camel/camel-mime-utils.c | 38 | ||||
-rw-r--r-- | camel/camel-mime-utils.h | 2 | ||||
-rw-r--r-- | camel/camel-search-private.c | 174 |
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; } |