Carl Mummert: add unquote() function for removing quotes from RFC-2822 headers
[mmh] / sbr / fmt_scan.c
index 4365e35..7558eca 100644 (file)
@@ -88,6 +88,25 @@ match (char *str, char *sub)
 /*
  * macros to format data
  */
+#define PUTDF(cp, num, wid, fill)\
+       if (cp + wid < ep) {\
+           if ((i = (num)) < 0)\
+               i = -(num);\
+           if ((c = (wid)) < 0)\
+               c = -c;\
+           sp = cp + c;\
+           do {\
+               *--sp = (i % 10) + '0';\
+               i /= 10;\
+           } while (i > 0 && sp > cp);\
+           if (i > 0)\
+               *sp = '?';\
+           else if ((num) < 0 && sp > cp)\
+               *--sp = '-';\
+           while (sp > cp)\
+               *--sp = fill;\
+           cp += c;\
+           }
 
 #ifdef LOCALE
 #define PUTSF(cp, str, wid, fill) {\
@@ -111,7 +130,7 @@ match (char *str, char *sub)
                                sp++;\
                        }\
                        while ((c = (unsigned char) *sp++) && --i >= 0 && cp < ep)\
-                               if (isgraph(c)) \
+                               if (!iscntrl(c) && !isspace(c)) \
                                    *cp++ = c;\
                                else {\
                                        while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
@@ -129,7 +148,7 @@ match (char *str, char *sub)
                    while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
                        sp++;\
                    while((c = (unsigned char) *sp++) && cp < ep)\
-                       if (isgraph(c)) \
+                       if (!iscntrl(c) && !isspace(c)) \
                            *cp++ = c;\
                        else {\
                            while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\
@@ -310,12 +329,7 @@ fmt_scan (struct format *format, char *scanl, int width, int *dat)
            if (n >= 0) cp += n;
            break;
        case FT_NUMF:
-           n = snprintf(cp, ep - cp, "%d", value);
-           if (n >= 0) {
-               cp += n;
-           } else n = 0;
-           c = abs(fmt->f_width) - n;
-           for (; (c > 0) && (cp < ep); c--) *cp++ = fmt->f_fill;
+           PUTDF (cp, value, fmt->f_width, fmt->f_fill);
            break;
 
        case FT_CHAR:
@@ -668,6 +682,38 @@ fmt_scan (struct format *format, char *scanl, int width, int *dat)
                  }
                }
            }
+           break;  
+
+
+               /* UNQUOTEs RFC-2822 quoted-string and quoted-pair */
+       case FT_LS_UNQUOTE:
+           if (str) {          
+               int m;
+               strncpy(buffer, str, sizeof(buffer));
+               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';
+               str = buffer2;
+            }
            break;
 
        case FT_LOCALDATE: