When doing an if-test on the result of a function which returns a string
[mmh] / sbr / fmt_compile.c
index e857c7d..c42f1e3 100644 (file)
@@ -3,11 +3,15 @@
  * fmt_compile.c -- "compile" format strings for fmt_scan
  *
  * $Id$
+ *
+ * This code is Copyright (c) 2002, by the authors of nmh.  See the
+ * COPYRIGHT file in the root directory of the nmh distribution for
+ * complete copyright information.
  */
 
 #include <h/mh.h>
 #include <h/addrsbr.h>
-#include <zotnet/tws/tws.h>
+#include <h/tws.h>
 #include <h/fmt_scan.h>
 #include <h/fmt_compile.h>
 
@@ -49,6 +53,9 @@ extern struct mailname fmt_mnull;
 #define        TF_NOP     8        /* like expr but no result            */
 
 /* ftable->flags */
+/* NB that TFL_PUTS is also used to decide whether the test
+ * in a "%<(function)..." should be a string or numeric one.
+ */
 #define        TFL_PUTS   1        /* implicit putstr if top level */
 #define        TFL_PUTN   2        /* implicit putnum if top level */
 
@@ -145,6 +152,8 @@ static struct ftable functable[] = {
      { "mymbox",     TF_COMP,  FT_LV_COMPFLAG, FT_MYMBOX,      TFL_PUTN },
      { "addtoseq",   TF_STR,   FT_ADDTOSEQ,    0,              0 },
 
+     { "unquote",   TF_EXPR,   FT_LS_UNQUOTE,  0,              TFL_PUTS},
+
      { NULL,         0,                0,              0,              0 }
 };
 
@@ -177,7 +186,7 @@ static struct ftable functable[] = {
 #define PUTC(c)                        NEW(FT_CHAR,0,0); fp->f_char = (c);
 
 static char *format_string;
-static char *usr_fstring;      /* for CERROR */
+static unsigned char *usr_fstring;     /* for CERROR */
 
 #define CERROR(str) compile_error (str, cp)
 
@@ -419,13 +428,11 @@ do_name(char *sp, int preprocess)
        if (cm->c_type & CT_ADDR) {
            CERROR("component used as both date and address");
        }
-       if (! (cm->c_type & CT_DATE)) {
-           cm->c_tws = (struct tws *)
-                               calloc((size_t) 1, sizeof(*cm->c_tws));
-           fp->f_type = preprocess;
-           PUTCOMP(sp);
-           cm->c_type |= CT_DATE;
-       }
+       cm->c_tws = (struct tws *)
+           calloc((size_t) 1, sizeof(*cm->c_tws));
+       fp->f_type = preprocess;
+       PUTCOMP(sp);
+       cm->c_type |= CT_DATE;
        break;
 
     case FT_MYMBOX:
@@ -433,18 +440,15 @@ do_name(char *sp, int preprocess)
            ismymbox ((struct mailname *) 0);
            primed++;
        }
-       cm->c_type |= CT_MYMBOX;
        /* fall through */
     case FT_PARSEADDR:
        if (cm->c_type & CT_DATE) {
            CERROR("component used as both date and address");
        }
-       if (! (cm->c_type & CT_ADDRPARSE)) {
-           cm->c_mn = &fmt_mnull;
-           fp->f_type = preprocess;
-           PUTCOMP(sp);
-           cm->c_type |= (CT_ADDR | CT_ADDRPARSE);
-       }
+       cm->c_mn = &fmt_mnull;
+       fp->f_type = preprocess;
+       PUTCOMP(sp);
+       cm->c_type |= CT_ADDR;
        break;
 
     case FT_FORMATADDR:
@@ -609,7 +613,14 @@ do_if(char *sp)
                if (ftbl->f_type >= IF_FUNCS)
                    fp->f_type = ftbl->extra;
                else {
-                   LV (FT_IF_V_NE, 0);
+                   /* Put out a string test or a value test depending
+                    * on what this function's return type is.
+                    */
+                   if (ftbl->flags & TFL_PUTS) {
+                       LV (FT_IF_S, 0);
+                   } else {
+                       LV (FT_IF_V_NE, 0);
+                   }
                }
            }
            else {