Rocco Rutte:
authorpdmef <pdmef@e385b8ad-14ed-0310-8656-cc95a2468c6d>
Wed, 24 Aug 2005 15:21:29 +0000 (15:21 +0000)
committerpdmef <pdmef@e385b8ad-14ed-0310-8656-cc95a2468c6d>
Wed, 24 Aug 2005 15:21:29 +0000 (15:21 +0000)
- 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

BUGS [new file with mode: 0644]
rfc3676.c
rfc3676.h
state.c

diff --git a/BUGS b/BUGS
new file mode 100644 (file)
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.
index 3869b33..9efa39d 100644 (file)
--- 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]);
+}
index d7d6397..9dfcfd8 100644 (file)
--- a/rfc3676.h
+++ b/rfc3676.h
 #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 (file)
--- 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);
     }
   }