]> granicus.if.org Git - neomutt/commitdiff
sorting efficiency
authorThomas Roessler <roessler@does-not-exist.org>
Wed, 17 Sep 2008 20:27:43 +0000 (22:27 +0200)
committerThomas Roessler <roessler@does-not-exist.org>
Wed, 17 Sep 2008 20:27:43 +0000 (22:27 +0200)
alias.c
globals.h
init.c
mutt_idna.c
muttlib.c
rfc822.h
sort.c

diff --git a/alias.c b/alias.c
index 623dd69718492e2e6f259c4df4c1c57ab88594e3..520c8b1b997455154d9cf85bac4b5abf2c3d5d91 100644 (file)
--- 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
index 4921daa182fb793bae0c04f5033456b49a48e860..25d6bab514ac205c47f8671ef635ffe1e5250a0b 100644 (file)
--- 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 29e33fc06ee21d4e472dea0386d901955bdc4048..f2c5be8c102cf849b681a48f13b33ec5c12df64f 100644 (file)
--- 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?
index 721bf4f0807d8fea0b0a775d4a206ccd6e62038c..47839e1cdcb1ac9558072d21a89adc4ebceede4f 100644 (file)
@@ -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;
 }
 
index 510078b38a1f83d865ca79dd1086bc01049f8399..edee887a8412ec0b0a990dc983775c9dc3d863f8 100644 (file)
--- 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);
index 5cabdf3147dcaa102c213bb55aeee42e08e7f7a9..65b7a5cd1e03cb41a7adeac2fecf629611238a56 100644 (file)
--- 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 c9e7137ed6bcc2f6f6238f7352210ba61ec23bee..087be87531a6fab34a083e6c5e710920bf292bee 100644 (file)
--- 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));
 }