]> diplodocus.org Git - nmh/blobdiff - sbr/fmt_scan.c
At this point we're assuming at least C89 support, so there's no reason
[nmh] / sbr / fmt_scan.c
index ac4d23afdedd7a9ad496a861ccd04f23c27d9e07..de44c44ac6dd9a933b115f4a21fcf4797fdcb185 100644 (file)
 #  include <wchar.h>
 #endif
 
-#ifdef LBL
-struct msgs *fmt_current_folder; /* current folder (set by main program) */
-#endif
-
 extern int fmt_norm;           /* defined in sbr/fmt_def.c = AD_NAME */
 struct mailname fmt_mnull = { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
                              NULL, NULL };
@@ -118,7 +114,8 @@ cpnumber(char **dest, int num, unsigned int wid, char fill, size_t n) {
  * no more than n bytes are copied
  */
 static void
-cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
+cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n,
+         size_t max) {
     int remaining;     /* remaining output width available */
     int c, ljust;
     int end;           /* number of input bytes remaining in str */
@@ -129,7 +126,8 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
 #endif
     char *sp;          /* current position in source string */
     char *cp = *dest;  /* current position in destination string */
-    char *ep = cp + n; /* end of destination buffer */
+    char *ep = cp + n; /* end of destination buffer based on desired width */
+    char *epmax = cp + max; /* true end of destination buffer */
     int prevCtrl = 1;
 
     /* get alignment */
@@ -144,6 +142,13 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
        while (*sp && remaining > 0 && end > 0) {
 #ifdef MULTIBYTE_SUPPORT
            char_len = mbtowc(&wide_char, sp, end);
+
+           /* Account for multibyte characters taking only one character's
+              width of output. */
+           if (char_len > 1  &&  epmax - ep >= char_len - 1) {
+               ep += char_len - 1;
+           }
+
            if (char_len <= 0 || (cp + char_len > ep))
                break;
 
@@ -208,7 +213,7 @@ cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n) {
 }
 
 static void
-cpstripped (char **dest, char *end, char *str)
+cpstripped (char **dest, char *end, char *max, char *str)
 {
     int prevCtrl = 1;  /* This is 1 so we strip out leading spaces */
     int len;
@@ -235,6 +240,12 @@ cpstripped (char **dest, char *end, char *str)
 #ifdef MULTIBYTE_SUPPORT
        char_len = mbtowc(&wide_char, str, len);
 
+       /* Account for multibyte characters taking only one character's
+          width of output. */
+       if (char_len > 1  &&  max - end >= char_len - 1) {
+           end += char_len - 1;
+       }
+
        if (char_len <= 0 || *dest + char_len > end)
            break;
 
@@ -373,10 +384,11 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
        switch (fmt->f_type) {
 
        case FT_COMP:
-           cpstripped (&cp, ep, fmt->f_comp->c_text);
+           cpstripped (&cp, ep, scanl + max - 1, fmt->f_comp->c_text);
            break;
        case FT_COMPF:
-           cptrimmed (&cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill, ep - cp);
+           cptrimmed (&cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill,
+                      ep - cp, scanl - cp + max - 1);
            break;
 
        case FT_LIT:
@@ -399,10 +411,11 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
            break;
 
        case FT_STR:
-           cpstripped (&cp, ep, str);
+           cpstripped (&cp, ep, scanl + max - 1, str);
            break;
        case FT_STRF:
-           cptrimmed (&cp, str, fmt->f_width, fmt->f_fill, ep - cp);
+           cptrimmed (&cp, str, fmt->f_width, fmt->f_fill, ep - cp,
+                      scanl - cp + max - 1);
            break;
        case FT_STRLIT:
            sp = str;
@@ -926,7 +939,7 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
                        *cp++ = ' ';
                }
            }
-           cpstripped (&cp, ep, lp);
+           cpstripped (&cp, ep, scanl + max - 1, lp);
            }
            break;
 
@@ -980,17 +993,6 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat)
                comp->c_mn = &fmt_mnull;
            }
            break;
-
-       case FT_ADDTOSEQ:
-#ifdef LBL
-           /* If we're working on a folder (as opposed to a file), add the
-            * current msg to sequence given in literal field.  Don't
-            * disturb string or value registers.
-            */
-           if (fmt_current_folder)
-                   seq_addmsg(fmt_current_folder, fmt->f_text, dat[0], -1);
-#endif
-           break;
        }
        fmt++;
     }