From: pdmef Date: Wed, 24 Aug 2005 15:21:29 +0000 (+0000) Subject: Rocco Rutte: X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=618ceafdc9564dbb8f3bf45c3869297a1d5a3320 Rocco Rutte: - bug fix for f=f adding new bugs: when composing replies, compress all quotes and change quoting char by force to '>' (see BUGS for discussion) git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@437 e385b8ad-14ed-0310-8656-cc95a2468c6d --- diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..207cad1 --- /dev/null +++ b/BUGS @@ -0,0 +1,26 @@ +This document lists bug known to exist in mutt-ng. + +RfC 3676 defining format=flowed +=============================== + +This RfC specifies quote chars to be '>' and due to space-stuffing lines +there're no spaces withing the quote prefix of a line allowed. +Currently, the implementation does: + +- Change all quote characters by force to '>'. This is plain wrong in + some cases where a character from $quote_regexp (even with the default + setting) may appear at the beginning of a line but actually doesn't + represent a quoted line. For example, someone may quote parts of + muttng configs with comments. However, _if_ this _is_ a quoted line + using e.g. '#' as $indent_string, we need to change the '#' prefix to + '>'. + +- Compress the complete quote, i.e. remove any spaces within the + complete quote prefix of a line. This, too, is just plain wrong. For + example, some people may have $indent_string set to '> ' and this gets + quoted several times to something like '>> >>'. However this + semanticly has a quote level of 3 as the second poster space-stuffed + that line. IMHO it's more common that people use spaces in + $indent_string (which the implementation removes right now) than + people space-stuffing lines which start '>' to ' >' when composing new + messages. diff --git a/rfc3676.c b/rfc3676.c index 3869b33..9efa39d 100644 --- a/rfc3676.c +++ b/rfc3676.c @@ -32,9 +32,6 @@ #include "lib/str.h" #include "lib/debug.h" -typedef int handler_f (BODY *, STATE *); -typedef handler_f *handler_t; - #define FLOWED_MAX 77 static int get_quote_level (char *line) @@ -91,36 +88,35 @@ static void print_flowed_line (char *line, STATE * s, /* only search a new position when we're not over * the end of the string w/ pos */ if (pos < line + len) { - /* fprintf(stderr,"if 1\n"); */ if (*pos == ' ') { - /* fprintf(stderr,"if 2: good luck! found a space\n"); */ + debug_print (4, ("f=f: found space directly at width\n")); *pos = '\0'; ++pos; } else { - /* fprintf(stderr,"if 2: else\n"); */ char *save = pos; + debug_print (4, ("f=f: need to search for space\n")); while (pos >= oldpos && *pos != ' ') { - /* fprintf(stderr,"pos(%p) > oldpos(%p)\n",pos,oldpos); */ --pos; } if (pos < oldpos) { - /* fprintf(stderr,"wow, no space found, - * searching the other direction\n"); */ + debug_print (4, ("f=f: no space found while searching " + "to left; going right\n")); pos = save; while (pos < line + len && *pos && *pos != ' ') { - /* fprintf(stderr,"pos(%p) < line+len(%p)\n",pos,line+len); */ ++pos; } - /* fprintf(stderr,"found a space pos = %p\n",pos); */ + debug_print (4, ("f=f: found space at pos %d\n", pos-line)); + } else { + debug_print (4, ("f=f: found space while searching to left\n")); } *pos = '\0'; ++pos; } } else { - /* fprintf(stderr,"if 1 else\n"); */ + debug_print (4, ("f=f: line completely fits on screen\n")); } if (s->prefix) state_puts (s->prefix, s); @@ -135,7 +131,7 @@ static void print_flowed_line (char *line, STATE * s, * to eliminate all spaces which were trailing due to DelSp */ for (i = 0; i < str_len (oldpos); i++) { if (oldpos[i] == ' ' && spaces[&(oldpos[i])-line] != 0) { - debug_print (4, ("DelSp: spaces[%d] forces space removal\n", + debug_print (4, ("f=f: DelSp: spaces[%d] forces space removal\n", &(oldpos[i])-line)); continue; } @@ -170,7 +166,7 @@ int rfc3676_handler (BODY * a, STATE * s) { t = NULL; } - debug_print (2, ("DelSp: %s\n", delsp ? "yes" : "no")); + debug_print (2, ("f=f: DelSp: %s\n", delsp ? "yes" : "no")); while (bytes > 0 && fgets (buf, sizeof (buf), s->fpin)) { buf_len = str_len (buf); @@ -232,7 +228,7 @@ int rfc3676_handler (BODY * a, STATE * s) { */ if (delsp && curline && *curline && curline_len-2 >= 0 && curline[curline_len-2] == ' ') { - debug_print (4, ("DelSp: marking spaces[%d] for later removal\n", + debug_print (4, ("f=f: DelSp: marking spaces[%d] for later removal\n", curline_len-2)); spaces[curline_len-2] = 1; } @@ -243,3 +239,39 @@ int rfc3676_handler (BODY * a, STATE * s) { mem_free (&curline); return (0); } + +void rfc3676_quote_line (STATE* s, char* dst, size_t dstlen, + const char* line) { + char quote[SHORT_STRING]; + int offset = 0, i = 0, count = 0; + regmatch_t pmatch[1]; + + quote[0] = '\0'; + + while (regexec ((regex_t *) QuoteRegexp.rx, &line[offset], + 1, pmatch, 0) == 0) + offset += pmatch->rm_eo; + + if (offset > 0) { + /* first count number of real quoting characters; + * read: non-spaces + * this maybe just plain wrong, but leaving spaces + * within quoting characters is what I consider + * more plain wrong... + */ + for (i = 0; i < offset; i++) + if (line[i] != ' ') + count++; + /* just make sure we're inside quote althoug we + * likely won't have more than SHORT_STRING quote levels... */ + i = (count > SHORT_STRING-1) ? SHORT_STRING-1 : count; + memset (quote, '>', i); + quote[i] = '\0'; + } + debug_print (4, ("f=f: quotelevel = %d, new prefix = '%s'\n", + i, NONULL (quote))); + /* if we changed prefix, make sure we respect $stuff_quoted */ + snprintf (dst, dstlen, "%s%s%s%s", NONULL (s->prefix), NONULL (quote), + option (OPTSTUFFQUOTED) && line[offset] != ' ' ? " " : "", + &line[offset]); +} diff --git a/rfc3676.h b/rfc3676.h index d7d6397..9dfcfd8 100644 --- a/rfc3676.h +++ b/rfc3676.h @@ -14,10 +14,15 @@ #include "mutt.h" #include "state.h" +/* body handler implementing RfC 3676 for format=flowed */ +int rfc3676_handler (BODY * a, STATE * s); + /* - * body handler implementing RfC 3676 for format=flowed + * this properly ensures correct quoting; correct is: + * - no spaces within the complete quote prefix of line (sect. 4.5) + * - change all quoting chars to '>' by force; see BUGS in srcdir */ - -int rfc3676_handler (BODY * a, STATE * s); +void rfc3676_quote_line (STATE* s, char* dst, size_t dstlen, + const char* line); #endif /* !_MUTT_RFC3676_H */ diff --git a/state.c b/state.c index 715cc9e..3dfdbfb 100644 --- a/state.c +++ b/state.c @@ -15,6 +15,9 @@ #include "mutt.h" #include "state.h" +#include "rfc3676.h" + +#include "lib/debug.h" static void state_prefix_put (const char *d, size_t dlen, STATE * s) { @@ -74,6 +77,9 @@ void state_prefix_putc (char c, STATE * s) char buf[2 * SHORT_STRING]; int j = 0, offset = 0; regmatch_t pmatch[1]; +#ifdef DEBUG + unsigned char save = '\0'; +#endif state_reset_prefix (s); while (regexec @@ -84,7 +90,8 @@ void state_prefix_putc (char c, STATE * s) if (!option (OPTQUOTEEMPTY) && Quotebuf[offset] == '\n') { buf[0] = '\n'; buf[1] = '\0'; - } + } else if (option (OPTTEXTFLOWED)) + rfc3676_quote_line (s, buf, sizeof (buf), Quotebuf); else if (option (OPTQUOTEQUOTED) && offset) { for (i = 0; i < offset; i++) if (Quotebuf[i] != ' ') @@ -95,6 +102,15 @@ void state_prefix_putc (char c, STATE * s) else snprintf (buf, sizeof (buf), "%s%s", NONULL (s->prefix), Quotebuf); +#ifdef DEBUG + if (str_len (buf) >= 2) { + save = buf[str_len (buf) - 1]; + buf[str_len (buf) - 1] = '\0'; + debug_print (2, ("buf = '%s'\n", buf)); + buf[str_len (buf)] = save; + } +#endif + state_puts (buf, s); } }