I used sysprof to take a look at where uulib spends most of its time,
and it turns out its top two bottlenecks were very tweakable.
With this tweak, the `freeze' time while Pan's decoding and saving
attachments is much shorter.
Testers, give this a spin and see what you think.
cheers,
Charles
Only in pan-devel/uulib/: asfd
Only in pan-devel/uulib/: .deps
diff -u old/uulib/fptools.c pan-devel/uulib/fptools.c
--- old/uulib/fptools.c 2006-04-17 22:19:43.000000000 -0500
+++ pan-devel/uulib/fptools.c 2006-04-24 23:28:37.000000000 -0500
@@ -433,76 +433,36 @@
* My own fgets function. It handles all kinds of line terminators
* properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the
* terminator is replaced by a single LF
+ *
+ * Pan change: sysprof says this function is standard uulib's biggest
+ * hotspot, and with the per-char fgetc and feof it's easy to see why.
+ * Pan doesn't run on OS9 anyway, so don't sweat CR.
+ * Handle LF (Unix, OSX) and CRLF (DOS) correctly.
+ * In all cases, the terminator is replaced by a single LF
*/
-
char * TOOLEXPORT
_FP_fgets (char *buf, int n, FILE *stream)
{
- char *obp = buf;
- int c;
-
- if (feof (stream))
+ int len;
+ *buf = '\0';
+ if (!fgets (buf, n, stream))
return NULL;
-
- while (--n && !feof (stream)) {
- if ((c = fgetc (stream)) == EOF) {
- if (ferror (stream))
- return NULL;
- else {
- if (obp == buf)
- return NULL;
- *buf = '\0';
- return obp;
- }
- }
- if (c == '\015') { /* CR */
- /*
- * Peek next character. If it's no LF, push it back.
- * ungetc(EOF, stream) is handled correctly according
- * to the manual page
- */
- if ((c = fgetc (stream)) != '\012')
- if (!feof (stream))
- ungetc (c, stream);
- *buf++ = '\012';
- *buf = '\0';
- return obp;
- }
- else if (c == '\012') { /* LF */
- *buf++ = '\012';
- *buf = '\0';
- return obp;
- }
- /*
- * just another standard character
- */
- *buf++ = c;
+ len = strlen (buf);
+ if (!len)
+ return NULL;
+ if (buf[len-1] != '\n') { // eof
+ buf[len++] = '\n';
+ buf[len] = '\0';
}
-
- /*
- * n-1 characters already transferred
- */
-
- *buf = '\0';
-
- /*
- * If a line break is coming up, read it
- */
-
- if (!feof (stream)) {
- if ((c = fgetc (stream)) == '\015' && !feof (stream)) {
- if ((c = fgetc (stream)) != '\012' && !feof (stream)) {
- ungetc (c, stream);
- }
- }
- else if (c != '\012' && !feof (stream)) {
- ungetc (c, stream);
- }
+ else if (buf[len-2] == '\r') { // crlf
+ buf[len-1] = '\n';
+ buf[len] = '\0';
+ --len;
}
-
- return obp;
+ return buf;
}
+
/*
* A replacement strerror function that just returns the error code
*/
Only in pan-devel/uulib/: Makefile
Only in pan-devel/uulib/: makelog
diff -u old/uulib/uuscan.c pan-devel/uulib/uuscan.c
--- old/uulib/uuscan.c 2006-04-17 21:54:12.000000000 -0500
+++ pan-devel/uulib/uuscan.c 2006-04-24 23:26:01.000000000 -0500
@@ -65,29 +65,26 @@
* of usual MDA, News and MIME headers.
* We make a distinction of MIME headers as we need the difference
* to scan the bodies from partial multipart messages.
+ *
+ * Change for Pan: for efficiency's sake, converted to lowercase
+ * and sorted them, so that IsKnownHeader can pass a lowercase buf
+ * to bsearch rather than having to do a stricmp against each header.
*/
static char *knownmsgheaders[] = {
- "From ", "Return-Path:", "Received:", "Reply-To:",
- "From:", "Sender:", "Resent-Reply-To:", "Resent-From:",
- "Resent-Sender:", "Date:", "Resent-Date:", "To:",
- "Resent-To:", "Cc:", "Bcc:", "Resent-bcc:",
- "Message-ID:", "Resent-Message-Id:", "In-Reply-To:",
- "References:", "Keywords:", "Subject:", "Comments:",
-
- "Delivery-Date:", "Posted-Date:", "Received-Date:",
- "Precedence:",
-
- "Path:", "Newsgroups:", "Organization:", "Lines:",
- "NNTP-Posting-Host:",
- NULL
+ "bcc:", "cc:", "comments:", "date:", "delivery-date:",
+ "from ", "from:", "in-reply-to:", "keywords:", "lines:",
+ "message-id:", "newsgroups:", "nntp-posting-host:",
+ "organization:", "path:", "posted-date:", "precedence:",
+ "received-date:", "received:", "references:", "reply-to:",
+ "resent-bcc:", "resent-date:", "resent-from:", "resent-message-id:",
+ "resent-reply-to:", "resent-sender:", "resent-to:", "return-path:",
+ "sender:", "subject:", "to:"
};
static char *knownmimeheaders[] = {
- "Mime-Version:", "Content-Transfer-Encoding:",
- "Content-Type:", "Content-Disposition:",
- "Content-Description:", "Content-Length:",
- NULL
+ "content-description:", "content-disposition:", "content-length:",
+ "content-transfer-encoding:", "content-type:", "mime-version:"
};
/*
@@ -541,20 +538,26 @@
static int
IsKnownHeader (char *line)
{
- char **iter = knownmsgheaders;
-
- while (iter && *iter) {
- if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
- return 1;
- iter++;
- }
-
- iter = knownmimeheaders;
-
- while (iter && *iter) {
- if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
- return 2;
- iter++;
+ static int n_msg = sizeof(knownmsgheaders) / sizeof(knownmsgheaders[0]);
+ static int n_mime = sizeof(knownmimeheaders) / sizeof(knownmimeheaders[0]);
+ static int max_width = 25; // content-transfer-encoding
+
+ int retval = 0;
+ if (line && *line && strlen(line)<max_width)
+ {
+ // buf holds a lowercase version of `line'
+ char buf[32], *pch=buf, *end=buf+sizeof(buf);
+ while (line && *line && !isspace(*line) && pch!=end)
+ *pch++ = tolower (*line++);
+ *pch = '\0';
+
+ // search for that in knownmsgheaders
+ if (bsearch (&buf, knownmsgheaders, n_msg, sizeof(char*), strcmp) != NULL)
+ retval = 1;
+
+ // search for that in knownmimeheaders
+ else if (bsearch (&buf, knownmimeheaders, n_mime, sizeof(char*), strcmp)
!= NULL)
+ retval = 2;
}
return 0;
_______________________________________________
Pan-users mailing list
Pan-users@nongnu.org
http://lists.nongnu.org/mailman/listinfo/pan-users