From 7cb8f6cbd4f8d0ac713daabef3b07d4b5275b9fb Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Mon, 25 Jun 2007 18:43:43 +0200 Subject: [PATCH] Moved all functions related to charsets to a separate file and fixed a couple of bugs in incremental counting of flagged messages. --- Makefile | 4 +-- rfc2047.c => charset.c | 67 ++++++++++++++++++++++++++++++++++++------ charset.h | 4 +++ cm.c | 65 ++++++++-------------------------------- rfc2047.h | 23 --------------- 5 files changed, 76 insertions(+), 87 deletions(-) rename rfc2047.c => charset.c (88%) create mode 100644 charset.h delete mode 100644 rfc2047.h diff --git a/Makefile b/Makefile index 9b28ac6..38cf8b1 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,11 @@ YEAR=2006 all: cm -cm: cm.o util.o rfc2047.o +cm: cm.o util.o charset.o cm.o: cm.c clists.h util.h util.o: util.c util.h -rfc2047.o: rfc2047.c util.h +charset.o: charset.c util.h clean: rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core` diff --git a/rfc2047.c b/charset.c similarity index 88% rename from rfc2047.c rename to charset.c index c94e259..606d8dc 100644 --- a/rfc2047.c +++ b/charset.c @@ -1,6 +1,10 @@ /* - * This code for parsing rfc2047 encoding of headers has been adapted - * from the Mutt 1.5.16 MUA by Martin Mares . + * Incoming Mail Checker: Charsets + * + * (c) 2007 Martin Mares + * + * The code for parsing rfc2047 encoding of headers has been adapted + * from the Mutt 1.5.16 MUA. Here is the original copyright message: * * Copyright (C) 1996-2000 Michael R. Elkins * Copyright (C) 2000-2001 Edmund Grimley Evans @@ -21,22 +25,21 @@ */ #include "util.h" -#include "rfc2047.h" +#include "charset.h" -#include #include #include #include #include #include +#include +#include #include #include #include static char *system_charset; -#define assert(x) -#define ICONV_CONST #define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0 enum encoding { @@ -77,7 +80,7 @@ static int option(int opt UNUSED) return 1; } -static size_t convert_string (ICONV_CONST char *f, size_t flen, +static size_t convert_string (char *f, size_t flen, const char *from, const char *to, char **t, size_t *tlen) { @@ -281,7 +284,7 @@ static size_t lwsrlen (const char *s, size_t n) /* try to decode anything that looks like a valid RFC2047 encoded * header field, ignoring RFC822 parsing rules */ -void rfc2047_decode (char **pd) +static void rfc2047_decode (char **pd) { const char *p, *q; size_t m, n; @@ -365,7 +368,8 @@ void rfc2047_decode (char **pd) } /* Initialize the whole machinery */ -void rfc2047_init(void) +void +charset_init(void) { setlocale(LC_CTYPE, ""); system_charset = nl_langinfo(CODESET); @@ -373,3 +377,48 @@ void rfc2047_init(void) system_charset = NULL; debug("Charset is %s\n", system_charset); } + +static void +do_add_snippet(char **ppos, char *term, unsigned char *add) +{ + char *pos = *ppos; + int space = 1; + mbtowc(NULL, NULL, 0); + + while (pos + MB_CUR_MAX < term) + { + wchar_t c; + int l = mbtowc(&c, add, MB_CUR_MAX); + if (!l) + break; + if (l < 0) + { + l = 1; + c = '?'; + } + add += l; + if (!iswprint(c)) + c = '?'; + if (iswspace(c)) + { + if (space) + continue; + space = 1; + } + else + space = 0; + l = wctomb(pos, c); + pos += l; + } + *ppos = pos; + *pos = 0; +} + +void +add_snippet(char **ppos, char *term, char *add) +{ + char *buf = xstrdup(add); + rfc2047_decode(&buf); + do_add_snippet(ppos, term, buf); + free(buf); +} diff --git a/charset.h b/charset.h new file mode 100644 index 0000000..bb3bf27 --- /dev/null +++ b/charset.h @@ -0,0 +1,4 @@ +/* Charset handling */ + +void add_snippet(char **ppos, char *term, char *add); +void charset_init(void); diff --git a/cm.c b/cm.c index 76db248..963fe04 100644 --- a/cm.c +++ b/cm.c @@ -20,7 +20,7 @@ #include "util.h" #include "clists.h" -#include "rfc2047.h" +#include "charset.h" static int check_interval = 30; static int force_refresh; @@ -65,7 +65,7 @@ struct mbox { time_t last_time; int last_size, last_pos; int total, new, flagged; - int last_total, last_new; + int last_total, last_new, last_flagged; int last_beep_new; int force_refresh; int snippet_is_new; @@ -204,49 +204,6 @@ mbox_visible_p(struct mbox *b) return 1; } -static void -do_add_snippet(char **ppos, char *term, unsigned char *add) -{ - char *pos = *ppos; - int space = 1; - while (*add && pos < term) - { - if (*add <= ' ') - { - if (!space) - *pos++ = ' '; - space = 1; - } - else if (*add >= 0x7f) - { - *pos++ = '?'; - space = 0; - } - else - { - *pos++ = *add; - space = 0; - } - add++; - } - *ppos = pos; - *pos = 0; -} - -static void -add_snippet(char **ppos, char *term, unsigned char *add) -{ -#if 1 - char *buf = xmalloc(strlen(add) + 1); - strcpy(buf, add); - rfc2047_decode(&buf); - do_add_snippet(ppos, term, buf); - free(buf); -#else - do_add_snippet(ppos, term, add); -#endif -} - static void prepare_snippet(struct mbox *b, char *sender, char *subject) { @@ -342,7 +299,7 @@ scan_mbox(struct mbox *b, struct stat *st) if (!st->st_size) { - b->total = b->new = 0; + b->total = b->new = b->flagged = 0; b->last_pos = 0; return; } @@ -353,7 +310,7 @@ scan_mbox(struct mbox *b, struct stat *st) if (mb_fd < 0) { debug("[open failed: %m] "); - b->total = b->new = -1; + b->total = b->new = b->flagged = -1; return; } mb_reset(0); @@ -378,17 +335,18 @@ scan_mbox(struct mbox *b, struct stat *st) if (!mb_check(from+1, 5)) { debug("[inconsistent] "); - b->total = b->new = -1; + b->total = b->new = b->flagged = -1; goto done; } - b->total = b->new = 0; - b->last_total = b->last_new = 0; + b->total = b->new = b->flagged = 0; + b->last_total = b->last_new = b->last_flagged = 0; b->snippet_is_new = 0; } else { b->total = b->last_total; b->new = b->last_new; + b->flagged = b->last_flagged; } for(;;) @@ -398,6 +356,7 @@ scan_mbox(struct mbox *b, struct stat *st) b->last_pos--; // last_pos should be the previous \n character b->last_total = b->total; b->last_new = b->new; + b->last_flagged = b->flagged; while ((c = mb_get()) >= 0 && c != '\n') ; @@ -530,7 +489,7 @@ scan(void) b->force_refresh = 1; if (stat(b->path, &st) < 0) { - b->total = b->new = -1; + b->total = b->new = b->flagged = -1; debug("%m\n"); } else if (!b->last_time || st.st_mtime != b->last_time || st.st_size != b->last_size || b->force_refresh) @@ -542,7 +501,7 @@ scan(void) scan_mbox(b, &st); b->last_time = st.st_mtime; b->last_size = st.st_size; - debug("%d %d (stopped at %d of %d)\n", b->total, b->new, b->last_pos, b->last_size); + debug("%d %d %d (stopped at %d of %d)\n", b->total, b->new, b->flagged, b->last_pos, b->last_size); b->scanning = 0; redraw_line(b->index); @@ -934,7 +893,7 @@ main(int argc, char **argv) while (optind < argc) add_pattern(argv[optind++]); - rfc2047_init(); + charset_init(); term_init(); scan_and_redraw(); next_active(0, 1); diff --git a/rfc2047.h b/rfc2047.h deleted file mode 100644 index 0d1750b..0000000 --- a/rfc2047.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This code for parsing rfc2047 encoding of headers has been adapted - * from the Mutt 1.5.16 MUA by Martin Mares . - * - * Copyright (C) 1996-2000 Michael R. Elkins - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -void rfc2047_decode (char **); -void rfc2047_init (void); -- 2.39.2