<<< Date Index >>>     <<< Thread Index >>>

Re: mutt Bug #2802 - stupid usage of strcat (fwd)



These patches look sane to me. I've applied them.

On Monday, 12 March 2007 at 15:19, Christoph Berg wrote:
> Apparently the sender of that one isn't subscribed...
> 
> Christoph

> From: Sami Farin <safari-mutt@xxxxxxxxxxxxx>
> To: Mutt Development List <mutt-dev@xxxxxxxx>
> Date: Sat, 10 Mar 2007 20:12:30 +0200
> Subject: mutt Bug #2802 - stupid usage of strcat
> User-Agent: Mutt/1.5.14 (2007-02-12)
> 
> mutt would benefit from replacing strcat and friends with
> a better string library,...  but because that's too much
> work for me, I only checked what it helps if I do
> one basic optimization for mutt's usage of strcat.
> 
> http://bugs.mutt.org/cgi-bin/gnatsweb.pl?database=mutt&cmd=view%20audit-trail&pr=2802
> mutt -f ./big.mbox
> cpu usage before: 98180452048 cycles
> cpu usage after:   4245703875 cycles
> (speedup: 23.1x)
> 
> when Bcc is two times longer:
> cpu usage before: 385111497988 cycles
> cpu usage after:    8414844886 cycles
> (speedup: 45.8x)
> 
> [ mutt-1.5.14-optimize_strcat_usage.patch ]
> 
> rfc822_write_address could as well return the length.
> [ mutt-1.5.14-rfc822_write_address_return_int.patch ]
> 
> mutt_canonical_charset does stupid loop when searching
> for correct entry, with this patch "mutt -f ./big.mbox"
> is 2x faster when I use utf-8 charset
> [ mutt-1.5.14-mutt_canonical_charset-optimize.patch]
> Searching PreferredMIMENames should be converted to 
> a better algorithm instead of applying this patch
> to mutt, I'd say.  This was just for testing the speed
> effect.  And it shouldn't need to call that function
> /that/ often, charset doesn't change while parsing
> one header field...?!
> 
> 
> 

> +++ mutt-1.5.14/rfc822.c      2007-03-10 17:37:28.268829563 +0200
> @@ -687,7 +687,7 @@ done:
>  }
>  
>  /* note: it is assumed that `buf' is nul terminated! */
> -void rfc822_write_address (char *buf, size_t buflen, ADDRESS *addr, int 
> display)
> +int rfc822_write_address (char *buf, size_t buflen, ADDRESS *addr, int 
> display)
>  {
>    char *pbuf = buf;
>    size_t len = mutt_strlen (buf);
> @@ -739,6 +739,7 @@ void rfc822_write_address (char *buf, si
>    }
>  done:
>    *pbuf = 0;
> +  return pbuf - buf;
>  }
>  
>  /* this should be rfc822_cpy_adr */
> +++ mutt-1.5.14/rfc822.h      2007-03-10 17:35:37.551182393 +0200
> @@ -48,7 +48,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *
>  ADDRESS *rfc822_cpy_adr (ADDRESS *addr);
>  ADDRESS *rfc822_cpy_adr_real (ADDRESS *addr);
>  ADDRESS *rfc822_append (ADDRESS **a, ADDRESS *b);
> -void rfc822_write_address (char *, size_t, ADDRESS *, int);
> +int rfc822_write_address (char *, size_t, ADDRESS *, int);
>  void rfc822_write_address_single (char *, size_t, ADDRESS *, int);
>  void rfc822_free_address (ADDRESS **addr);
>  void rfc822_cat (char *, size_t, const char *, const char *);

> +++ mutt-1.5.14/charset.c     2007-03-10 15:48:32.311906317 +0200
> @@ -245,6 +245,11 @@ void mutt_canonical_charset (char *dest,
>    char *p;
>    char scratch[LONG_STRING];
>  
> +  if (!ascii_strcasecmp (name, "utf-8")) {
> +    strfcpy (dest, name, dlen);
> +    goto found_utf8;
> +  }
> +
>    /* catch some common iso-8859-something misspellings */
>    if (!ascii_strncasecmp (name, "8859", 4) && name[4] != '-')
>      snprintf (scratch, sizeof (scratch), "iso-8859-%s", name +4);
> @@ -267,6 +272,7 @@ void mutt_canonical_charset (char *dest,
>  
>    strfcpy (dest, scratch, dlen);
>  
> +found_utf8:
>    /* for cosmetics' sake, transform to lowercase. */
>    for (p = dest; *p; p++)
>      *p = ascii_tolower (*p);

> +++ mutt-1.5.14/copy.c        2007-03-10 19:14:29.169711344 +0200
> @@ -49,13 +49,14 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF
>    int from = 0;
>    int this_is_from;
>    int ignore = 0;
> -  char buf[STRING]; /* should be long enough to get most fields in one pass 
> */
> +  char buf[LONG_STRING]; /* should be long enough to get most fields in one 
> pass */
>    char *nl;
>    LIST *t;
>    char **headers;
>    int hdr_count;
>    int x;
>    char *this_one = NULL;
> +  size_t this_one_len;
>    int error;
>  
>    if (ftello (in) != off_start)
> @@ -156,15 +157,17 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF
>       {
>         if (!address_header_decode (&this_one))
>           rfc2047_decode (&this_one);
> +       this_one_len = mutt_strlen (this_one);
>       }
> -     
> +
>       if (!headers[x])
>         headers[x] = this_one;
>       else 
>       {
> -       safe_realloc (&headers[x], mutt_strlen (headers[x]) + 
> -                     mutt_strlen (this_one) + sizeof (char));
> -       strcat (headers[x], this_one); /* __STRCAT_CHECKED__ */
> +       int hlen = mutt_strlen (headers[x]);
> +
> +       safe_realloc (&headers[x], hlen + this_one_len + sizeof (char));
> +       strcat (headers[x] + hlen, this_one); /* __STRCAT_CHECKED__ */
>         FREE (&this_one);
>       }
>  
> @@ -231,13 +234,15 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF
>      if (!ignore)
>      {
>        dprint (2, (debugfile, "Reorder: x = %d; hdr_count = %d\n", x, 
> hdr_count));
> -      if (!this_one)
> +      if (!this_one) {
>       this_one = safe_strdup (buf);
> -      else
> -      {
> -     safe_realloc (&this_one,
> -                   mutt_strlen (this_one) + mutt_strlen (buf) + sizeof 
> (char));
> -     strcat (this_one, buf); /* __STRCAT_CHECKED__ */
> +     this_one_len = mutt_strlen (this_one);
> +      } else {
> +     int blen = mutt_strlen (buf);
> +
> +     safe_realloc (&this_one, this_one_len + blen + sizeof (char));
> +     strcat (this_one + this_one_len, buf); /* __STRCAT_CHECKED__ */
> +     this_one_len += blen;
>        }
>      }
>    } /* while (ftello (in) < off_end) */
> @@ -255,9 +260,10 @@ mutt_copy_hdr (FILE *in, FILE *out, LOFF
>        headers[x] = this_one;
>      else 
>      {
> -      safe_realloc (&headers[x], mutt_strlen (headers[x]) + 
> -                 mutt_strlen (this_one) + sizeof (char));
> -      strcat (headers[x], this_one); /* __STRCAT_CHECKED__ */
> +      int hlen = mutt_strlen (headers[x]);
> +
> +      safe_realloc (&headers[x], hlen + this_one_len + sizeof (char));
> +      strcat (headers[x] + hlen, this_one); /* __STRCAT_CHECKED__ */
>        FREE (&this_one);
>      }
>  
> @@ -845,22 +851,22 @@ static void format_address_header (char 
>    char buf[HUGE_STRING];
>    char cbuf[STRING];
>    char c2buf[STRING];
> -  
> -  int l, linelen, buflen, count;
> +  char *p;
> +  int l, linelen, buflen, count, cbuflen, c2buflen, plen;
> +
>    linelen = mutt_strlen (*h);
> +  plen = linelen;
>    buflen  = linelen + 3;
> -  
> -  
> +
>    safe_realloc (h, buflen);
>    for (count = 0; a; a = a->next, count++)
>    {
>      ADDRESS *tmp = a->next;
>      a->next = NULL;
>      *buf = *cbuf = *c2buf = '\0';
> -    rfc822_write_address (buf, sizeof (buf), a, 0);
> +    l = rfc822_write_address (buf, sizeof (buf), a, 0);
>      a->next = tmp;
>      
> -    l = mutt_strlen (buf);
>      if (count && linelen + l > 74) 
>      {
>        strcpy (cbuf, "\n\t");         /* __STRCPY_CHECKED__ */
> @@ -881,16 +887,22 @@ static void format_address_header (char 
>        buflen++;
>        strcpy (c2buf, ",");   /* __STRCPY_CHECKED__ */
>      }
> -    
> -    buflen += l + mutt_strlen (cbuf) + mutt_strlen (c2buf);
> +
> +    cbuflen = mutt_strlen (cbuf);
> +    c2buflen = mutt_strlen (c2buf);
> +    buflen += l + cbuflen + c2buflen;
>      safe_realloc (h, buflen);
> -    strcat (*h, cbuf);               /* __STRCAT_CHECKED__ */
> -    strcat (*h, buf);                /* __STRCAT_CHECKED__ */
> -    strcat (*h, c2buf);              /* __STRCAT_CHECKED__ */
> +    p = *h;
> +    strcat (p + plen, cbuf);         /* __STRCAT_CHECKED__ */
> +    plen += cbuflen;
> +    strcat (p + plen, buf);          /* __STRCAT_CHECKED__ */
> +    plen += l;
> +    strcat (p + plen, c2buf);                /* __STRCAT_CHECKED__ */
> +    plen += c2buflen;
>    }
>    
>    /* Space for this was allocated in the beginning of this function. */
> -  strcat (*h, "\n");         /* __STRCAT_CHECKED__ */
> +  strcat (p + plen, "\n");           /* __STRCAT_CHECKED__ */
>  }
>  
>  static int address_header_decode (char **h)




Attachment: pgpMinLQUuOVQ.pgp
Description: PGP signature