diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2002-11-11 23:14:49 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2002-11-11 23:14:49 +0800 |
commit | c2793329a93b03bcf7ba6bdaf4dadd7d0c52c0d8 (patch) | |
tree | b288cdefa202e3ec74a11c72ebba2e64cbf1e93c | |
parent | e1ef0a9ced256cb86d19b379c3097efdbcdb498e (diff) | |
download | gsoc2013-evolution-c2793329a93b03bcf7ba6bdaf4dadd7d0c52c0d8.tar.gz gsoc2013-evolution-c2793329a93b03bcf7ba6bdaf4dadd7d0c52c0d8.tar.zst gsoc2013-evolution-c2793329a93b03bcf7ba6bdaf4dadd7d0c52c0d8.zip |
Rewritten. Much much much cleaner implementation now, though uses
2002-11-11 Jeffrey Stedfast <fejj@ximian.com>
* camel-mime-filter-tohtml.c (html_convert): Rewritten. Much much
much cleaner implementation now, though uses malloc/free more
often than I'd like.
svn path=/trunk/; revision=18691
-rw-r--r-- | camel/ChangeLog | 6 | ||||
-rw-r--r-- | camel/camel-mime-filter-tohtml.c | 581 | ||||
-rw-r--r-- | camel/camel-mime-filter-tohtml.h | 8 |
3 files changed, 263 insertions, 332 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 3a5d115458..5ccf0d32e4 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,5 +1,11 @@ 2002-11-11 Jeffrey Stedfast <fejj@ximian.com> + * camel-mime-filter-tohtml.c (html_convert): Rewritten. Much much + much cleaner implementation now, though uses malloc/free more + often than I'd like. + +2002-11-11 Jeffrey Stedfast <fejj@ximian.com> + * providers/imap/camel-imap-folder.c (get_message_simple): Use g_strerror when setting an exception string (we need it to be in UTF-8). diff --git a/camel/camel-mime-filter-tohtml.c b/camel/camel-mime-filter-tohtml.c index 980d6fcf7f..0f7fbfebf3 100644 --- a/camel/camel-mime-filter-tohtml.c +++ b/camel/camel-mime-filter-tohtml.c @@ -28,14 +28,34 @@ #include <stdio.h> #include <string.h> #include <ctype.h> +#include <regex.h> #include "camel-mime-filter-tohtml.h" #define d(x) + +struct _UrlRegexPattern { + unsigned int mask; + char *pattern; + char *prefix; + regex_t *preg; + regmatch_t matches; +}; + +static struct _UrlRegexPattern patterns[] = { + { CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, "(news|nntp|telnet|file|ftp|http|https)://([-a-z0-9]+(:[-a-z0-9]+)?@)?[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-a-z0-9_$.+!*(),;:@%&=?/~#]*[^]'.}>\\) ,?!;:\"]?)?", "", NULL, { 0, 0 } }, + { CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]'.}>\\) ,?!;:\"]?)?", "http://", NULL, { 0, 0 } }, + { CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, "ftp\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]'.}>\\) ,?!;:\"]?)?", "ftp://", NULL, { 0, 0 } }, + { CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, "([-_a-z0-9.\\+]+@[-_a-z0-9.]+)", "mailto:", NULL, { 0, 0 } } +}; + +#define NUM_URL_REGEX_PATTERNS (sizeof (patterns) / sizeof (patterns[0])) + + static void camel_mime_filter_tohtml_class_init (CamelMimeFilterToHTMLClass *klass); -static void camel_mime_filter_tohtml_init (CamelObject *o); -static void camel_mime_filter_tohtml_finalize (CamelObject *o); +static void camel_mime_filter_tohtml_init (CamelMimeFilterToHTML *filter); +static void camel_mime_filter_tohtml_finalize (CamelObject *obj); static CamelMimeFilterClass *camel_mime_filter_tohtml_parent; @@ -60,15 +80,43 @@ camel_mime_filter_tohtml_get_type (void) } static void -camel_mime_filter_tohtml_finalize (CamelObject *o) +camel_mime_filter_tohtml_finalize (CamelObject *obj) { - ; + CamelMimeFilterToHTML *filter = (CamelMimeFilterToHTML *) obj; + int i; + + for (i = 0; i < NUM_URL_REGEX_PATTERNS; i++) { + if (filter->patterns[i].preg) { + regfree (filter->patterns[i].preg); + g_free (filter->patterns[i].preg); + } + } + + g_free (filter->patterns); } static void -camel_mime_filter_tohtml_init (CamelObject *o) +camel_mime_filter_tohtml_init (CamelMimeFilterToHTML *filter) { - ; + int i; + + /* FIXME: use a global set of patterns instead? */ + filter->patterns = g_malloc (sizeof (patterns)); + memcpy (filter->patterns, patterns, sizeof (patterns)); + + for (i = 0; i < NUM_URL_REGEX_PATTERNS; i++) { + filter->patterns[i].preg = g_malloc (sizeof (regex_t)); + if (regcomp (filter->patterns[i].preg, patterns[i].pattern, REG_EXTENDED) == -1) { + /* error building the regex_t so we can't use this pattern */ + filter->patterns[i].preg = NULL; + filter->patterns[i].mask = 0; + } + } + + filter->flags = 0; + filter->colour = 0; + filter->column = 0; + filter->pre_open = FALSE; } @@ -89,382 +137,261 @@ check_size (CamelMimeFilter *filter, char *outptr, char **outend, size_t len) return filter->outbuf + offset; } - -static unsigned short special_chars[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7, 4, 3, 0, 0, 0, 0, 7, 3, 7, 0, 0, 7, 12, 12, 1, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 7, 3, 0, 7, 4, - 1, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 7, 3, 0, 4, - 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 7, 4, 0, 0, -}; - - -#define IS_NON_ADDR (1 << 0) -#define IS_NON_URL (1 << 1) -#define IS_GARBAGE (1 << 2) -#define IS_DOMAIN (1 << 3) - -#define NON_EMAIL_CHARS "()<>@,;:\\\"/[]`'|\n\t " -#define NON_URL_CHARS "()<>,;\\\"[]`'|\n\t " -#define TRAILING_URL_GARBAGE ",.!?;:>)}\\`'-_|\n\t " - -#define is_addr_char(c) ((unsigned char) (c) < 128 && !(special_chars[(unsigned char) (c)] & IS_NON_ADDR)) -#define is_url_char(c) ((unsigned char) (c) < 128 && !(special_chars[(unsigned char) (c)] & IS_NON_URL)) -#define is_trailing_garbage(c) ((unsigned char) (c) > 127 || (special_chars[(unsigned char) (c)] & IS_GARBAGE)) -#define is_domain_name_char(c) ((unsigned char) (c) < 128 && (special_chars[(unsigned char) (c)] & IS_DOMAIN)) - - -#if 0 -static void -table_init (void) +static int +citation_depth (const char *in) { - int max, ch, i; - char *c; + register const char *inptr = in; + int depth = 1; - memset (special_chars, 0, sizeof (special_chars)); - for (c = NON_EMAIL_CHARS; *c; c++) - special_chars[(int) *c] |= IS_NON_ADDR; - for (c = NON_URL_CHARS; *c; c++) - special_chars[(int) *c] |= IS_NON_URL; - for (c = TRAILING_URL_GARBAGE; *c; c++) - special_chars[(int) *c] |= IS_GARBAGE; + if (*inptr++ != '>') + return 0; -#define is_ascii_alpha(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) + /* check that it isn't an escaped From line */ + if (!strncmp (inptr, "From", 4)) + return 0; - for (ch = 0; ch < 128; ch++) { - if (is_ascii_alpha (ch) || isdigit (ch) || ch == '.' || ch == '-') - special_chars[ch] |= IS_DOMAIN; - } - - max = sizeof (special_chars) / sizeof (special_chars[0]); - printf ("static unsigned short special_chars[%d] = {", max); - for (i = 0; i < max; i++) { - if (i % 16 == 0) - printf ("\n\t"); - printf ("%3d,", special_chars[i]); - } - printf ("\n};\n"); -} -#endif - -static char * -url_extract (char **in, int inlen, gboolean check, gboolean *backup) -{ - unsigned char *inptr, *inend, *p; - char *url; - - inptr = (unsigned char *) *in; - inend = inptr + inlen; - - while (inptr < inend && is_url_char (*inptr)) - inptr++; - - if ((char *) inptr == *in) - return NULL; - - /* back up if we probably went too far. */ - while (inptr > (unsigned char *) *in && is_trailing_garbage (*(inptr - 1))) - inptr--; - - if (check) { - /* make sure we weren't fooled. */ - p = memchr (*in, ':', (char *) inptr - *in); - if (!p) - return NULL; - } - - if (inptr == inend && backup) { - *backup = TRUE; - return NULL; + while (*inptr != '\n') { + if (*inptr == ' ') + inptr++; + + if (*inptr++ != '>') + break; + + depth++; } - url = g_strndup (*in, (char *) inptr - *in); - *in = inptr; - - return url; + return depth; } static char * -email_address_extract (char **in, char *inend, char *start, char **outptr, gboolean *backup) -{ - char *addr, *pre, *end, *dot; - - /* *in points to the '@'. Look backward for a valid local-part */ - pre = *in; - while (pre - 1 >= start && is_addr_char (*(pre - 1))) - pre--; - - if (pre == *in) - return NULL; - - /* Now look forward for a valid domain part */ - for (end = *in + 1, dot = NULL; end < inend && is_domain_name_char (*end); end++) { - if (*end == '.' && !dot) - dot = end; - } - - if (end >= inend && backup) { - *backup = TRUE; - *outptr -= (*in - pre); - *in = pre; - return NULL; - } - - if (!dot) - return NULL; - - /* Remove trailing garbage */ - while (end > *in && is_trailing_garbage (*(end - 1))) - end--; - if (dot > end) - return NULL; - - addr = g_strndup (pre, end - pre); - *outptr -= (*in - pre); - *in = end; - - return addr; -} - -static gboolean -is_citation (char *inptr, char *inend, gboolean saw_citation, gboolean *backup) -{ - if (*inptr != '>') - return FALSE; - - if (inend - inptr >= 6) { - /* make sure this isn't just mbox From-magling... */ - if (strncmp (inptr, ">From ", 6) != 0) - return TRUE; - } else if (backup) { - /* we don't have enough data to tell, so return */ - *backup = TRUE; - return saw_citation; - } - - /* if the previous line was a citation, then say this one is too */ - if (saw_citation) - return TRUE; - - /* otherwise it was just an isolated ">From " line */ - return FALSE; -} - -static gboolean -is_protocol (char *inptr, char *inend, gboolean *backup) -{ - if (inend - inptr >= 8) { - if (!strncasecmp (inptr, "http://", 7) || - !strncasecmp (inptr, "https://", 8) || - !strncasecmp (inptr, "ftp://", 6) || - !strncasecmp (inptr, "nntp://", 7) || - !strncasecmp (inptr, "mailto:", 7) || - !strncasecmp (inptr, "news:", 5) || - !strncasecmp (inptr, "file:", 5)) - return TRUE; - } else if (backup) { - *backup = TRUE; - return FALSE; - } - - return FALSE; -} - -static void -html_convert (CamelMimeFilter *filter, char *in, size_t inlen, size_t prespace, - char **out, size_t *outlen, size_t *outprespace, gboolean flush) +writeln (CamelMimeFilter *filter, const char *in, const char *inend, char *outptr, char **outend) { CamelMimeFilterToHTML *html = (CamelMimeFilterToHTML *) filter; - char *inptr, *inend, *outptr, *outend, *start; - gboolean backup = FALSE; - - camel_mime_filter_set_size (filter, inlen * 2 + 6, FALSE); - - inptr = start = in; - inend = in + inlen; - outptr = filter->outbuf; - outend = filter->outbuf + filter->outsize; - - if (html->flags & CAMEL_MIME_FILTER_TOHTML_PRE && !html->pre_open) { - outptr += sprintf (outptr, "%s", "<pre>"); - html->pre_open = TRUE; - } + register const char *inptr = in; while (inptr < inend) { unsigned char u; - if (html->flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION && html->column == 0) { - html->saw_citation = is_citation (inptr, inend, html->saw_citation, - flush ? &backup : NULL); - if (backup) - break; - - if (html->saw_citation) { - if (!html->coloured) { - char font[25]; - - g_snprintf (font, 25, "<font color=\"#%06x\">", html->colour); - - outptr = check_size (filter, outptr, &outend, 25); - outptr += sprintf (outptr, "%s", font); - html->coloured = TRUE; - } - } else if (html->coloured) { - outptr = check_size (filter, outptr, &outend, 10); - outptr += sprintf (outptr, "%s", "</font>"); - html->coloured = FALSE; - } - - /* display mbox-mangled ">From " as "From " */ - if (*inptr == '>' && !html->saw_citation) - inptr++; - } else if (html->flags & CAMEL_MIME_FILTER_TOHTML_CITE && html->column == 0) { - outptr = check_size (filter, outptr, &outend, 6); - outptr += sprintf (outptr, "%s", "> "); - } - - if (html->flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS && isalpha ((int) *inptr)) { - char *refurl = NULL, *dispurl = NULL; - - if (is_protocol (inptr, inend, flush ? &backup : NULL)) { - dispurl = url_extract (&inptr, inend - inptr, TRUE, - flush ? &backup : NULL); - if (backup) - break; - - if (dispurl) - refurl = g_strdup (dispurl); - } else { - if (backup) - break; - - if (!strncasecmp (inptr, "www.", 4) && ((unsigned char) inptr[4]) < 0x80 - && isalnum ((int) inptr[4])) { - dispurl = url_extract (&inptr, inend - inptr, FALSE, - flush ? &backup : NULL); - if (backup) - break; - - if (dispurl) - refurl = g_strdup_printf ("http://%s", dispurl); - } - } - - if (dispurl) { - outptr = check_size (filter, outptr, &outend, - strlen (refurl) + - strlen (dispurl) + 15); - outptr += sprintf (outptr, "<a href=\"%s\">%s</a>", - refurl, dispurl); - html->column += strlen (dispurl); - g_free (refurl); - g_free (dispurl); - } - - if (inptr >= inend) - break; - } - - if (*inptr == '@' && (html->flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES)) { - char *addr, *outaddr; - - addr = email_address_extract (&inptr, inend, start, &outptr, - flush ? &backup : NULL); - if (backup) - break; - - if (addr) { - outaddr = g_strdup_printf ("<a href=\"mailto:%s\">%s</a>", - addr, addr); - outptr = check_size (filter, outptr, &outend, strlen (outaddr)); - outptr += sprintf (outptr, "%s", outaddr); - html->column += strlen (addr); - g_free (addr); - g_free (outaddr); - } - } - - outptr = check_size (filter, outptr, &outend, 32); + outptr = check_size (filter, outptr, outend, 9); switch ((u = (unsigned char) *inptr++)) { case '<': - outptr += sprintf (outptr, "%s", "<"); + outptr = g_stpcpy (outptr, "<"); html->column++; break; - case '>': - outptr += sprintf (outptr, "%s", ">"); + outptr = g_stpcpy (outptr, ">"); html->column++; break; - case '&': - outptr += sprintf (outptr, "%s", "&"); + outptr = g_stpcpy (outptr, "&"); html->column++; break; - case '"': - outptr += sprintf (outptr, "%s", """); + outptr = g_stpcpy (outptr, """); html->column++; break; - - case '\n': - if (html->flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_NL) - outptr += sprintf (outptr, "%s", "<br>"); - - *outptr++ = '\n'; - start = inptr; - html->column = 0; - break; - case '\t': if (html->flags & (CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES)) { do { - outptr = check_size (filter, outptr, &outend, 7); - outptr += sprintf (outptr, "%s", " "); + outptr = check_size (filter, outptr, outend, 7); + outptr = g_stpcpy (outptr, " "); html->column++; } while (html->column % 8); break; } /* otherwise, FALL THROUGH */ - case ' ': if (html->flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES) { - if (inptr == in || (inptr < inend && (*(inptr + 1) == ' ' || - *(inptr + 1) == '\t' || - *(inptr - 1) == '\n'))) { - outptr += sprintf (outptr, "%s", " "); + if (inptr == (in + 1) || *inptr == ' ' || *inptr == '\t') { + outptr = g_stpcpy (outptr, " "); html->column++; break; } } /* otherwise, FALL THROUGH */ - default: - if ((u >= 0x20 && u < 0x80) || - (u == '\r' || u == '\t')) { - /* Default case, just copy. */ - *outptr++ = (char) u; - } else { + if (!(u >= 0x20 && u < 0x80)) { if (html->flags & CAMEL_MIME_FILTER_TOHTML_ESCAPE_8BIT) *outptr++ = '?'; else outptr += g_snprintf (outptr, 9, "&#%d;", (int) u); + } else { + *outptr++ = (char) u; } html->column++; break; } } - if (inptr < inend) - camel_mime_filter_backup (filter, inptr, inend - inptr); + return outptr; +} + +static void +html_convert (CamelMimeFilter *filter, char *in, size_t inlen, size_t prespace, + char **out, size_t *outlen, size_t *outprespace, gboolean flush) +{ + CamelMimeFilterToHTML *html = (CamelMimeFilterToHTML *) filter; + register char *inptr, *outptr; + char *start, *outend; + const char *inend; + int depth; + + camel_mime_filter_set_size (filter, inlen * 2 + 6, FALSE); - if (flush && html->pre_open) { - outptr = check_size (filter, outptr, &outend, 10); - outptr += sprintf (outptr, "%s", "</pre>"); - html->pre_open = FALSE; + inptr = in; + inend = in + inlen; + outptr = filter->outbuf; + outend = filter->outbuf + filter->outsize; + + if (html->flags & CAMEL_MIME_FILTER_TOHTML_PRE && !html->pre_open) { + outptr = g_stpcpy (outptr, "<pre>"); + html->pre_open = TRUE; + } + + start = inptr; + while (inptr < inend && *inptr != '\n') + inptr++; + + while (inptr < inend) { + html->column = 0; + depth = 0; + + if (html->flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION) { + if ((depth = citation_depth (start)) > 0) { + char font[25]; + + /* FIXME: we could easily support multiple colour depths here */ + + g_snprintf (font, 25, "<font color=\"#%06x\">", html->colour); + + outptr = check_size (filter, outptr, &outend, 25); + outptr = g_stpcpy (outptr, font); + } else if (*start == '>') { + /* >From line */ + start++; + } + } else if (html->flags & CAMEL_MIME_FILTER_TOHTML_CITE) { + outptr = check_size (filter, outptr, &outend, 6); + outptr = g_stpcpy (outptr, "> "); + html->column += 2; + } + +#define CONVERT_URLS (CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES) + if (html->flags & CONVERT_URLS) { + struct _UrlRegexPattern *fmatch, *pat; + size_t matchlen, len; + regoff_t offset; + char *linebuf; + char save; + int i; + + len = inptr - start; + linebuf = g_malloc (len + 1); + memcpy (linebuf, start, len); + linebuf[len] = '\0'; + + start = linebuf; + save = '\0'; + + do { + /* search for all of our patterns */ + offset = 0; + fmatch = NULL; + for (i = 0; i < NUM_URL_REGEX_PATTERNS; i++) { + pat = html->patterns + i; + if ((html->flags & pat->mask) && + !regexec (pat->preg, start, 1, &pat->matches, 0)) { + if (pat->matches.rm_so < offset) { + *(start + offset) = save; + fmatch = NULL; + } + + if (!fmatch) { + fmatch = pat; + offset = pat->matches.rm_so; + + /* optimisation so we don't have to search the + entire line buffer for the next pattern */ + save = *(start + offset); + *(start + offset) = '\0'; + } + } + } + + if (fmatch) { + /* restore our char */ + *(start + offset) = save; + + /* write out anything before the first regex match */ + outptr = writeln (filter, start, start + offset, outptr, &outend); + start += offset; + len -= offset; + +#define MATCHLEN(matches) (matches.rm_eo - matches.rm_so) + matchlen = MATCHLEN (fmatch->matches); + + i = 20 + strlen (fmatch->prefix) + matchlen + matchlen; + outptr = check_size (filter, outptr, &outend, i); + + /* write out the href tag */ + outptr = g_stpcpy (outptr, "<a href=\""); + outptr = g_stpcpy (outptr, fmatch->prefix); + memcpy (outptr, start, matchlen); + outptr += matchlen; + outptr = g_stpcpy (outptr, "\">"); + + /* now write the matched string */ + memcpy (outptr, start, matchlen); + html->column += matchlen; + outptr += matchlen; + start += matchlen; + len -= matchlen; + + /* close the href tag */ + outptr = g_stpcpy (outptr, "</a>"); + } else { + /* nothing matched so write out the remainder of this line buffer */ + outptr = writeln (filter, start, start + len, outptr, &outend); + break; + } + } while (len > 0); + + g_free (linebuf); + } else { + outptr = writeln (filter, start, inptr, outptr, &outend); + } + + if ((html->flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION) && depth > 0) { + outptr = check_size (filter, outptr, &outend, 8); + outptr = g_stpcpy (outptr, "</font>"); + } + + if (html->flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_NL) { + outptr = check_size (filter, outptr, &outend, 5); + outptr = g_stpcpy (outptr, "<br>"); + } + + *outptr++ = '\n'; + + start = ++inptr; + while (inptr < inend && *inptr != '\n') + inptr++; + } + + if (flush) { + /* flush the rest of our input buffer */ + if (start < inend) + outptr = writeln (filter, start, inend, outptr, &outend); + + if (html->pre_open) { + /* close the pre-tag */ + outptr = check_size (filter, outptr, &outend, 10); + outptr = g_stpcpy (outptr, "</pre>"); + } + } else if (start < inend) { + /* backup */ + camel_mime_filter_backup (filter, start, (unsigned) (inend - start)); } *out = filter->outbuf; @@ -493,8 +420,6 @@ filter_reset (CamelMimeFilter *filter) html->column = 0; html->pre_open = FALSE; - html->saw_citation = FALSE; - html->coloured = FALSE; } static void diff --git a/camel/camel-mime-filter-tohtml.h b/camel/camel-mime-filter-tohtml.h index 46c4051b87..d8c6e47f41 100644 --- a/camel/camel-mime-filter-tohtml.h +++ b/camel/camel-mime-filter-tohtml.h @@ -50,13 +50,13 @@ typedef struct _CamelMimeFilterToHTML CamelMimeFilterToHTML; struct _CamelMimeFilterToHTML { CamelMimeFilter parent; + struct _UrlRegexPattern *patterns; + guint32 flags; guint32 colour; - guint32 column : 29; - guint32 pre_open : 1; - guint32 saw_citation : 1; - guint32 coloured : 1; + guint32 column : 31; + guint32 pre_open : 1; }; struct _CamelMimeFilterToHTMLClass { |