]> diplodocus.org Git - nmh/blobdiff - sbr/fmt_scan.c
Fix a few warnings.
[nmh] / sbr / fmt_scan.c
index dad7a3c6a08c56700b2392a0af291bb548ceb928..408b1093a86786beea9e309077867d4b82b2078f 100644 (file)
@@ -134,6 +134,7 @@ cptrimmed(char **dest, char **ep, char *str, unsigned int wid, char fill,
     int char_len;      /* bytes in current character */
     int w;
     wchar_t wide_char;
+    char *altstr = NULL;
 #endif
     char *sp;          /* current position in source string */
     char *cp = *dest;  /* current position in destination string */
@@ -154,6 +155,17 @@ cptrimmed(char **dest, char **ep, char *str, unsigned int wid, char fill,
 #ifdef MULTIBYTE_SUPPORT
            char_len = mbtowc(&wide_char, sp, end);
 
+           /*
+            * See the relevant comments in cpstripped() to explain what's
+            * going on here; we want to handle the case where we get
+            * characters that mbtowc() cannot handle
+            */
+
+           if (char_len < 0) {
+               altstr = "?";
+               char_len = mbtowc(&wide_char, altstr, 1);
+           }
+
            if (char_len <= 0)
                break;
 
@@ -196,9 +208,10 @@ cptrimmed(char **dest, char **ep, char *str, unsigned int wid, char fill,
 
 #ifdef MULTIBYTE_SUPPORT
            if (w >= 0 && remaining >= w) {
-               strncpy(cp, sp, char_len);
+               strncpy(cp, altstr ? altstr : sp, char_len);
                cp += char_len;
                remaining -= w;
+               altstr = NULL;
            }
            sp += char_len;
 #else
@@ -239,6 +252,7 @@ cpstripped (char **dest, char **end, char *max, char *str)
 #ifdef MULTIBYTE_SUPPORT
     int char_len, w;
     wchar_t wide_char;
+    char *altstr = NULL;
 #endif /* MULTIBYTE_SUPPORT */
 
     if (!str)
@@ -269,6 +283,19 @@ cpstripped (char **dest, char **end, char *max, char *str)
            *end += char_len - w;
        }
 
+       /*
+        * If mbrtowc() failed, then we have a character that isn't valid
+        * in the current encoding.  Replace it with a '?'.  We do that by
+        * setting the alstr variable to the value of the replacement string;
+        * altstr is used below when the bytes are copied into the output
+        * buffer.
+        */
+
+       if (char_len < 0) {
+           altstr = "?";
+           char_len = mbtowc(&wide_char, altstr, 1);
+       }
+
        if (char_len <= 0 || *dest + char_len > *end)
            break;
 
@@ -293,9 +320,10 @@ cpstripped (char **dest, char **end, char *max, char *str)
        prevCtrl = 0;
 
 #ifdef MULTIBYTE_SUPPORT
-       memcpy(*dest, str, char_len);
+       memcpy(*dest, altstr ? altstr : str, char_len);
        str += char_len;
        *dest += char_len;
+       altstr = NULL;
 #else /* MULTIBYE_SUPPORT */
        *(*dest)++ = *str++
 #endif /* MULTIBYTE_SUPPORT */
@@ -840,32 +868,10 @@ fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat,
                /* UNQUOTEs RFC-2822 quoted-string and quoted-pair */
        case FT_LS_UNQUOTE:
            if (str) {          
-               int m;
                strncpy(buffer, str, sizeof(buffer));
                /* strncpy doesn't NUL-terminate if it fills the buffer */
                buffer[sizeof(buffer)-1] = '\0';
-               str = buffer;
-       
-               /* we will parse from buffer to buffer2 */
-               n = 0; /* n is the input position in str */
-               m = 0; /* m is the ouput position in buffer2 */
-
-               while ( str[n] != '\0') {
-                   switch ( str[n] ) {
-                       case '\\':
-                           n++;
-                           if ( str[n] != '\0')
-                               buffer2[m++] = str[n++];
-                           break;
-                       case '"':
-                           n++;
-                           break;
-                       default:
-                           buffer2[m++] = str[n++];
-                           break;
-                       }
-               }
-               buffer2[m] = '\0';
+               unquote_string(buffer, buffer2);
                str = buffer2;
             }
            break;