From 4af1c6d6e20ec5e803ba760760a3dec46bec04c7 Mon Sep 17 00:00:00 2001 From: Thomas Roessler Date: Wed, 17 Sep 2008 22:27:43 +0200 Subject: [PATCH] sorting efficiency --- alias.c | 41 ++++++++++++++++++++++++++------------- globals.h | 1 + init.c | 6 ++++-- mutt_idna.c | 55 ++++++++++++++++++++++++++++++++++++----------------- muttlib.c | 1 + rfc822.h | 2 ++ sort.c | 16 ++++++++-------- 7 files changed, 82 insertions(+), 40 deletions(-) diff --git a/alias.c b/alias.c index 623dd697..520c8b1b 100644 --- a/alias.c +++ b/alias.c @@ -332,6 +332,8 @@ retry_name: return; } + alias_add_reverse (new); + if ((t = Aliases)) { while (t->next) @@ -440,23 +442,36 @@ int mutt_check_alias_name (const char *s, char *dest, size_t destlen) */ ADDRESS *alias_reverse_lookup (ADDRESS *a) { - ALIAS *t = Aliases; - ADDRESS *ap; - if (!a || !a->mailbox) - return NULL; + return NULL; + + return hash_find (ReverseAlias, a->mailbox); +} - for (; t; t = t->next) +void alias_add_reverse (ALIAS *t) +{ + ADDRESS *ap; + if (!t) + return; + + for (ap = t->addr; ap; ap = ap->next) { - /* cycle through all addresses if this is a group alias */ - for (ap = t->addr; ap; ap = ap->next) - { - if (!ap->group && ap->mailbox && - ascii_strcasecmp (ap->mailbox, a->mailbox) == 0) - return ap; - } + if (!ap->group && ap->mailbox) + hash_insert (ReverseAlias, ap->mailbox, ap, 1); + } +} + +void alias_delete_reverse (ALIAS *t) +{ + ADDRESS *ap; + if (!t) + return; + + for (ap = t->addr; ap; ap = ap->next) + { + if (!ap->group && ap->mailbox) + hash_delete (ReverseAlias, ap->mailbox, ap, NULL); } - return 0; } /* alias_complete() -- alias completion routine diff --git a/globals.h b/globals.h index 4921daa1..25d6bab5 100644 --- a/globals.h +++ b/globals.h @@ -151,6 +151,7 @@ WHERE char *LastFolder; WHERE const char *ReleaseDate; WHERE HASH *Groups; +WHERE HASH *ReverseAlias; WHERE LIST *AutoViewList INITVAL(0); WHERE LIST *AlternativeOrderList INITVAL(0); diff --git a/init.c b/init.c index 29e33fc0..f2c5be8c 100644 --- a/init.c +++ b/init.c @@ -1263,7 +1263,7 @@ static int parse_unalias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *er { if (CurrentMenu == MENU_ALIAS) { - for (tmp = Aliases; tmp ; tmp = tmp->next) + for (tmp = Aliases; tmp ; tmp = tmp->next) tmp->del = 1; set_option (OPTFORCEREDRAWINDEX); } @@ -1336,6 +1336,7 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) } else { + alias_delete_reverse (tmp); /* override the previous value */ rfc822_free_address (&tmp->addr); if (CurrentMenu == MENU_ALIAS) @@ -1360,7 +1361,7 @@ static int parse_alias (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) } mutt_group_context_add_adrlist (gc, tmp->addr); - + alias_add_reverse (tmp); #ifdef DEBUG if (debuglevel >= 2) @@ -2881,6 +2882,7 @@ void mutt_init (int skip_sys_rc, LIST *commands) err.dsize = sizeof (error); Groups = hash_create (1031); + ReverseAlias = hash_create (1031); /* * XXX - use something even more difficult to predict? diff --git a/mutt_idna.c b/mutt_idna.c index 721bf4f0..47839e1c 100644 --- a/mutt_idna.c +++ b/mutt_idna.c @@ -42,6 +42,29 @@ int mutt_local_to_idna (const char *in, char **out) #else +/* check whether an address is an IDN */ + +static int check_idn (ADDRESS *ap) +{ + char *p = 0; + + if (!ap || !ap->mailbox) + return 0; + + if (!ap->idn_checked) + { + ap->idn_checked = 1; + for (p = strchr (ap->mailbox, '@'); p && *p; p = strchr (p, '.')) + if (ascii_strncasecmp (++p, "xn--", 4) == 0) + { + ap->is_idn = 1; + break; + } + } + + return ap->is_idn; +} + int mutt_idna_to_local (const char *in, char **out, int flags) { *out = NULL; @@ -51,7 +74,7 @@ int mutt_idna_to_local (const char *in, char **out, int flags) if (!in) goto notrans; - + /* Is this the right function? Interesting effects with some bad identifiers! */ if (idna_to_unicode_8z8z (in, out, 1) != IDNA_SUCCESS) goto notrans; @@ -132,16 +155,17 @@ int mutt_local_to_idna (const char *in, char **out) static int mbox_to_udomain (const char *mbx, char **user, char **domain) { + static char *buff = NULL; char *p; - *user = NULL; - *domain = NULL; - p = strchr (mbx, '@'); + mutt_str_replace (&buff, mbx); + + p = strchr (buff, '@'); if (!p || !p[1]) return -1; - *user = safe_calloc((p - mbx + 1), sizeof(mbx[0])); - strfcpy (*user, mbx, (p - mbx + 1)); - *domain = safe_strdup(p + 1); + *p = '\0'; + *user = buff; + *domain = p + 1; return 0; } @@ -171,10 +195,9 @@ int mutt_addrlist_to_idna (ADDRESS *a, char **err) { safe_realloc (&a->mailbox, mutt_strlen (user) + mutt_strlen (tmp) + 2); sprintf (a->mailbox, "%s@%s", NONULL(user), NONULL(tmp)); /* __SPRINTF_CHECKED__ */ + a->idn_checked = 0; } - FREE (&domain); - FREE (&user); FREE (&tmp); if (e) @@ -193,17 +216,17 @@ int mutt_addrlist_to_local (ADDRESS *a) { if (!a->mailbox) continue; + if (!check_idn (a)) + continue; if (mbox_to_udomain (a->mailbox, &user, &domain) == -1) continue; - if (mutt_idna_to_local (domain, &tmp, 0) == 0) { safe_realloc (&a->mailbox, mutt_strlen (user) + mutt_strlen (tmp) + 2); sprintf (a->mailbox, "%s@%s", NONULL (user), NONULL (tmp)); /* __SPRINTF_CHECKED__ */ + a->idn_checked = 0; } - FREE (&domain); - FREE (&user); FREE (&tmp); } @@ -221,13 +244,13 @@ const char *mutt_addr_for_display (ADDRESS *a) char *user = NULL; FREE (&buff); - + + if (!check_idn (a)) + return a->mailbox; if (mbox_to_udomain (a->mailbox, &user, &domain) != 0) return a->mailbox; if (mutt_idna_to_local (domain, &tmp, MI_MAY_BE_IRREVERSIBLE) != 0) { - FREE (&user); - FREE (&domain); FREE (&tmp); return a->mailbox; } @@ -235,8 +258,6 @@ const char *mutt_addr_for_display (ADDRESS *a) safe_realloc (&buff, mutt_strlen (tmp) + mutt_strlen (user) + 2); sprintf (buff, "%s@%s", NONULL(user), NONULL(tmp)); /* __SPRINTF_CHECKED__ */ FREE (&tmp); - FREE (&user); - FREE (&domain); return buff; } diff --git a/muttlib.c b/muttlib.c index 510078b3..edee887a 100644 --- a/muttlib.c +++ b/muttlib.c @@ -746,6 +746,7 @@ void mutt_free_alias (ALIAS **p) { t = *p; *p = (*p)->next; + alias_delete_reverse (t); FREE (&t->name); rfc822_free_address (&t->addr); FREE (&t); diff --git a/rfc822.h b/rfc822.h index 5cabdf31..65b7a5cd 100644 --- a/rfc822.h +++ b/rfc822.h @@ -39,6 +39,8 @@ typedef struct address_t char *mailbox; /* mailbox and host address */ int group; /* group mailbox? */ struct address_t *next; + unsigned is_idn : 1; + unsigned idn_checked : 1; } ADDRESS; diff --git a/sort.c b/sort.c index c9e7137e..087be875 100644 --- a/sort.c +++ b/sort.c @@ -111,13 +111,13 @@ int compare_to (const void *a, const void *b) { HEADER **ppa = (HEADER **) a; HEADER **ppb = (HEADER **) b; - const char *fa, *fb; + char fa[SHORT_STRING]; + const char *fb; int result; - fa = safe_strdup (mutt_get_name ((*ppa)->env->to)); + strfcpy (fa, mutt_get_name ((*ppa)->env->to), SHORT_STRING); fb = mutt_get_name ((*ppb)->env->to); - result = mutt_strcasecmp (fa, fb); - FREE(&fa); + result = mutt_strncasecmp (fa, fb, SHORT_STRING); AUXSORT(result,a,b); return (SORTCODE (result)); } @@ -126,13 +126,13 @@ int compare_from (const void *a, const void *b) { HEADER **ppa = (HEADER **) a; HEADER **ppb = (HEADER **) b; - const char *fa, *fb; + char fa[SHORT_STRING]; + const char *fb; int result; - fa = safe_strdup (mutt_get_name ((*ppa)->env->from)); + strfcpy (fa, mutt_get_name ((*ppa)->env->from), SHORT_STRING); fb = mutt_get_name ((*ppb)->env->from); - result = mutt_strcasecmp (fa, fb); - FREE(&fa); + result = mutt_strncasecmp (fa, fb, SHORT_STRING); AUXSORT(result,a,b); return (SORTCODE (result)); } -- 2.40.0