]> diplodocus.org Git - nmh/commitdiff
Added multiply format function, requested by Norm.
authorDavid Levine <levinedl@acm.org>
Sat, 10 Jan 2015 23:12:49 +0000 (17:12 -0600)
committerDavid Levine <levinedl@acm.org>
Sat, 10 Jan 2015 23:12:49 +0000 (17:12 -0600)
docs/pending-release-notes
h/fmt_compile.h
man/mh-format.man
sbr/fmt_compile.c
sbr/fmt_scan.c
test/format/test-functions
uip/fmtdump.c
uip/fmttest.c

index c621ca1a1d6cc7e61a985b5784834484ed240a4c..d1d0d5831646add1692f7bf05072fc7e73a3fee4 100644 (file)
@@ -29,6 +29,7 @@ NEW FEATURES
   to mhfixmsg(1).
 - mhfixmsg now removes an extraneous trailing semicolon from header
   parameter lists.
   to mhfixmsg(1).
 - mhfixmsg now removes an extraneous trailing semicolon from header
   parameter lists.
+- added multiply format function
 
 -----------------
 OBSOLETE FEATURES
 
 -----------------
 OBSOLETE FEATURES
index 9e94b3c0958272128a71f1101166d6c7d4fe0328..f34613a94a49c845e1a0b2ee7a00a0206e38c905 100644 (file)
  */
 
 /* types that output text */
  */
 
 /* types that output text */
-#define FT_COMP         1       /* the text of a component                 */
-#define FT_COMPF        2       /* comp text, filled                       */
-#define FT_LIT          3       /* literal text                            */
-#define FT_LITF         4       /* literal text, filled                    */
-#define FT_CHAR         5       /* a single ascii character                */
-#define FT_NUM          6       /* "value" as decimal number               */
-#define FT_NUMF         7       /* "value" as filled dec number            */
-#define FT_STR          8       /* "str" as text                           */
-#define FT_STRF         9       /* "str" as text, filled                   */
-#define FT_STRFW        10      /* "str" as text, filled, width in "value" */
-#define FT_STRLIT       11      /* "str" as text, no space compression     */
-#define FT_STRLITZ      12      /* literal text with zero display width    */
-#define FT_PUTADDR      13      /* split and print address line            */
+#define FT_COMP          1       /* the text of a component                 */
+#define FT_COMPF         2       /* comp text, filled                       */
+#define FT_LIT           3       /* literal text                            */
+#define FT_LITF          4       /* literal text, filled                    */
+#define FT_CHAR          5       /* a single ascii character                */
+#define FT_NUM           6       /* "value" as decimal number               */
+#define FT_NUMF          7       /* "value" as filled dec number            */
+#define FT_STR           8       /* "str" as text                           */
+#define FT_STRF          9       /* "str" as text, filled                   */
+#define FT_STRFW         10      /* "str" as text, filled, width in "value" */
+#define FT_STRLIT        11      /* "str" as text, no space compression     */
+#define FT_STRLITZ       12      /* literal text with zero display width    */
+#define FT_PUTADDR       13      /* split and print address line            */
 
 /* types that modify the "str" or "value" registers                     */
 
 /* types that modify the "str" or "value" registers                     */
-#define FT_LS_COMP      14      /* set "str" to component text          */
-#define FT_LS_LIT       15      /* set "str" to literal text            */
-#define FT_LS_GETENV    16      /* set "str" to getenv(text)            */
-#define FT_LS_CFIND     17      /* set "str" to context_find(text)      */
-#define FT_LS_DECODECOMP 18     /* set "str" to decoded component text  */
-#define FT_LS_DECODE    19      /* decode "str" as RFC-2047 header      */
-#define FT_LS_TRIM      20      /* trim trailing white space from "str" */
-#define FT_LV_COMP      21      /* set "value" to comp (as dec. num)    */
-#define FT_LV_COMPFLAG  22      /* set "value" to comp flag word        */
-#define FT_LV_LIT       23      /* set "value" to literal num           */
-#define FT_LV_DAT       24      /* set "value" to dat[n]                */
-#define FT_LV_STRLEN    25      /* set "value" to length of "str"       */
-#define FT_LV_PLUS_L    26      /* set "value" += literal               */
-#define FT_LV_MINUS_L   27      /* set "value" -= literal               */
-#define FT_LV_DIVIDE_L  28      /* set "value" to value / literal       */
-#define FT_LV_MODULO_L  29      /* set "value" to value % literal       */
-#define FT_LV_CHAR_LEFT 30      /* set "value" to char left in output   */
+#define FT_LS_COMP       14      /* set "str" to component text          */
+#define FT_LS_LIT        15      /* set "str" to literal text            */
+#define FT_LS_GETENV     16      /* set "str" to getenv(text)            */
+#define FT_LS_CFIND      17      /* set "str" to context_find(text)      */
+#define FT_LS_DECODECOMP 18      /* set "str" to decoded component text  */
+#define FT_LS_DECODE     19      /* decode "str" as RFC-2047 header      */
+#define FT_LS_TRIM       20      /* trim trailing white space from "str" */
+#define FT_LV_COMP       21      /* set "value" to comp (as dec. num)    */
+#define FT_LV_COMPFLAG   22      /* set "value" to comp flag word        */
+#define FT_LV_LIT        23      /* set "value" to literal num           */
+#define FT_LV_DAT        24      /* set "value" to dat[n]                */
+#define FT_LV_STRLEN     25      /* set "value" to length of "str"       */
+#define FT_LV_PLUS_L     26      /* set "value" += literal               */
+#define FT_LV_MINUS_L    27      /* set "value" -= literal               */
+#define FT_LV_MULTIPLY_L 28      /* set "value" to value * literal       */
+#define FT_LV_DIVIDE_L   29      /* set "value" to value / literal       */
+#define FT_LV_MODULO_L   30      /* set "value" to value % literal       */
+#define FT_LV_CHAR_LEFT  31      /* set "value" to char left in output   */
 
 
-#define FT_LS_MONTH     31      /* set "str" to tws month                   */
-#define FT_LS_LMONTH    32      /* set "str" to long tws month              */
-#define FT_LS_ZONE      33      /* set "str" to tws timezone                */
-#define FT_LS_DAY       34      /* set "str" to tws weekday                 */
-#define FT_LS_WEEKDAY   35      /* set "str" to long tws weekday            */
-#define FT_LS_822DATE   36      /* set "str" to 822 date str                */
-#define FT_LS_PRETTY    37      /* set "str" to pretty (?) date str         */
-#define FT_LS_KILO      38      /* set "str" to "<value>[KMGT]"             */
-#define FT_LS_KIBI      39      /* set "str" to "<value>[KMGT]"             */
-#define FT_LV_SEC       40      /* set "value" to tws second                */
-#define FT_LV_MIN       41      /* set "value" to tws minute                */
-#define FT_LV_HOUR      42      /* set "value" to tws hour                  */
-#define FT_LV_MDAY      43      /* set "value" to tws day of month          */
-#define FT_LV_MON       44      /* set "value" to tws month                 */
-#define FT_LV_YEAR      45      /* set "value" to tws year                  */
-#define FT_LV_YDAY      46      /* set "value" to tws day of year           */
-#define FT_LV_WDAY      47      /* set "value" to tws weekday               */
-#define FT_LV_ZONE      48      /* set "value" to tws timezone              */
-#define FT_LV_CLOCK     49      /* set "value" to tws clock                 */
-#define FT_LV_RCLOCK    50      /* set "value" to now - tws clock           */
-#define FT_LV_DAYF      51      /* set "value" to tws day flag              */
-#define FT_LV_DST       52      /* set "value" to tws daylight savings flag */
-#define FT_LV_ZONEF     53      /* set "value" to tws timezone flag         */
+#define FT_LS_MONTH      32      /* set "str" to tws month                   */
+#define FT_LS_LMONTH     33      /* set "str" to long tws month              */
+#define FT_LS_ZONE       34      /* set "str" to tws timezone                */
+#define FT_LS_DAY        35      /* set "str" to tws weekday                 */
+#define FT_LS_WEEKDAY    36      /* set "str" to long tws weekday            */
+#define FT_LS_822DATE    37      /* set "str" to 822 date str                */
+#define FT_LS_PRETTY     38      /* set "str" to pretty (?) date str         */
+#define FT_LS_KILO       39      /* set "str" to "<value>[KMGT]"             */
+#define FT_LS_KIBI       40      /* set "str" to "<value>[KMGT]"             */
+#define FT_LV_SEC        41      /* set "value" to tws second                */
+#define FT_LV_MIN        42      /* set "value" to tws minute                */
+#define FT_LV_HOUR       43      /* set "value" to tws hour                  */
+#define FT_LV_MDAY       44      /* set "value" to tws day of month          */
+#define FT_LV_MON        45      /* set "value" to tws month                 */
+#define FT_LV_YEAR       46      /* set "value" to tws year                  */
+#define FT_LV_YDAY       47      /* set "value" to tws day of year           */
+#define FT_LV_WDAY       48      /* set "value" to tws weekday               */
+#define FT_LV_ZONE       49      /* set "value" to tws timezone              */
+#define FT_LV_CLOCK      50      /* set "value" to tws clock                 */
+#define FT_LV_RCLOCK     51      /* set "value" to now - tws clock           */
+#define FT_LV_DAYF       52      /* set "value" to tws day flag              */
+#define FT_LV_DST        53      /* set "value" to tws daylight savings flag */
+#define FT_LV_ZONEF      54      /* set "value" to tws timezone flag         */
 
 
-#define FT_LS_PERS      54      /* set "str" to person part of addr    */
-#define FT_LS_MBOX      55      /* set "str" to mbox part of addr      */
-#define FT_LS_HOST      56      /* set "str" to host part of addr      */
-#define FT_LS_PATH      57      /* set "str" to route part of addr     */
-#define FT_LS_GNAME     58      /* set "str" to group part of addr     */
-#define FT_LS_NOTE      59      /* set "str" to comment part of addr   */
-#define FT_LS_ADDR      60      /* set "str" to mbox@host              */
-#define FT_LS_822ADDR   61      /* set "str" to 822 format addr        */
-#define FT_LS_FRIENDLY  62      /* set "str" to "friendly" format addr */
-#define FT_LV_HOSTTYPE  63      /* set "value" to addr host type       */
-#define FT_LV_INGRPF    64      /* set "value" to addr in-group flag   */
-#define FT_LS_UNQUOTE   65      /* remove RFC 2822 quotes from "str"   */
-#define FT_LV_NOHOSTF   66      /* set "value" to addr no-host flag */
+#define FT_LS_PERS       55      /* set "str" to person part of addr    */
+#define FT_LS_MBOX       56      /* set "str" to mbox part of addr      */
+#define FT_LS_HOST       57      /* set "str" to host part of addr      */
+#define FT_LS_PATH       58      /* set "str" to route part of addr     */
+#define FT_LS_GNAME      59      /* set "str" to group part of addr     */
+#define FT_LS_NOTE       60      /* set "str" to comment part of addr   */
+#define FT_LS_ADDR       61      /* set "str" to mbox@host              */
+#define FT_LS_822ADDR    62      /* set "str" to 822 format addr        */
+#define FT_LS_FRIENDLY   63      /* set "str" to "friendly" format addr */
+#define FT_LV_HOSTTYPE   64      /* set "value" to addr host type       */
+#define FT_LV_INGRPF     65      /* set "value" to addr in-group flag   */
+#define FT_LS_UNQUOTE    66      /* remove RFC 2822 quotes from "str"   */
+#define FT_LV_NOHOSTF    67      /* set "value" to addr no-host flag */
 
 /* Date Coercion */
 
 /* Date Coercion */
-#define FT_LOCALDATE    67      /* Coerce date to local timezone */
-#define FT_GMTDATE      68      /* Coerce date to gmt            */
+#define FT_LOCALDATE     68      /* Coerce date to local timezone */
+#define FT_GMTDATE       69      /* Coerce date to gmt            */
 
 /* pre-format processing */
 
 /* pre-format processing */
-#define FT_PARSEDATE    69      /* parse comp into a date (tws) struct */
-#define FT_PARSEADDR    70      /* parse comp into a mailaddr struct   */
-#define FT_FORMATADDR   71      /* let external routine format addr    */
-#define FT_CONCATADDR   72      /* formataddr w/out duplicate removal  */
-#define FT_MYMBOX       73      /* do "mymbox" test on comp            */
-#define FT_GETMYMBOX    74      /* return "mymbox" mailbox string      */
-#define FT_GETMYADDR    75      /* return "mymbox" addr string         */
+#define FT_PARSEDATE     70      /* parse comp into a date (tws) struct */
+#define FT_PARSEADDR     71      /* parse comp into a mailaddr struct   */
+#define FT_FORMATADDR    72      /* let external routine format addr    */
+#define FT_CONCATADDR    73      /* formataddr w/out duplicate removal  */
+#define FT_MYMBOX        74      /* do "mymbox" test on comp            */
+#define FT_GETMYMBOX     75      /* return "mymbox" mailbox string      */
+#define FT_GETMYADDR     76      /* return "mymbox" addr string         */
 
 /* conditionals & control flow (must be last) */
 
 /* conditionals & control flow (must be last) */
-#define FT_SAVESTR      76      /* save current str reg               */
-#define FT_DONE         77      /* stop formatting                    */
-#define FT_PAUSE        78      /* pause                              */
-#define FT_NOP          79      /* nop                                */
-#define FT_GOTO         80      /* (relative) goto                    */
-#define FT_IF_S_NULL    81      /* test if "str" null                 */
-#define FT_IF_S         82      /* test if "str" non-null             */
-#define FT_IF_V_EQ      83      /* test if "value" = literal          */
-#define FT_IF_V_NE      84      /* test if "value" != literal         */
-#define FT_IF_V_GT      85      /* test if "value" > literal          */
-#define FT_IF_MATCH     86      /* test if "str" contains literal     */
-#define FT_IF_AMATCH    87      /* test if "str" starts with literal  */
-#define FT_S_NULL       88      /* V = 1 if "str" null                */
-#define FT_S_NONNULL    89      /* V = 1 if "str" non-null            */
-#define FT_V_EQ         90      /* V = 1 if "value" = literal         */
-#define FT_V_NE         91      /* V = 1 if "value" != literal        */
-#define FT_V_GT         92      /* V = 1 if "value" > literal         */
-#define FT_V_MATCH      93      /* V = 1 if "str" contains literal    */
-#define FT_V_AMATCH     94      /* V = 1 if "str" starts with literal */
+#define FT_SAVESTR       77      /* save current str reg               */
+#define FT_DONE          78      /* stop formatting                    */
+#define FT_PAUSE         79      /* pause                              */
+#define FT_NOP           80      /* nop                                */
+#define FT_GOTO          81      /* (relative) goto                    */
+#define FT_IF_S_NULL     82      /* test if "str" null                 */
+#define FT_IF_S          83      /* test if "str" non-null             */
+#define FT_IF_V_EQ       84      /* test if "value" = literal          */
+#define FT_IF_V_NE       85      /* test if "value" != literal         */
+#define FT_IF_V_GT       86      /* test if "value" > literal          */
+#define FT_IF_MATCH      87      /* test if "str" contains literal     */
+#define FT_IF_AMATCH     88      /* test if "str" starts with literal  */
+#define FT_S_NULL        89      /* V = 1 if "str" null                */
+#define FT_S_NONNULL     90      /* V = 1 if "str" non-null            */
+#define FT_V_EQ          91      /* V = 1 if "value" = literal         */
+#define FT_V_NE          92      /* V = 1 if "value" != literal        */
+#define FT_V_GT          93      /* V = 1 if "value" > literal         */
+#define FT_V_MATCH       94      /* V = 1 if "str" contains literal    */
+#define FT_V_AMATCH      95      /* V = 1 if "str" starts with literal */
 
 
-#define IF_FUNCS FT_S_NULL      /* start of "if" functions */
+#define IF_FUNCS FT_S_NULL       /* start of "if" functions */
index 1e2f41a521cec5fb3d881e5bce5cb302662408e2..dd9c6c487d7e64e34e7e406b46804f28cd33c637 100644 (file)
@@ -268,6 +268,7 @@ match       literal boolean \fIstr\fR contains \fIarg\fR
 amatch literal boolean \fIstr\fR starts with \fIarg\fR
 plus   literal integer \fIarg\fR plus \fInum\fR
 minus  literal integer \fIarg\fR minus \fInum\fR
 amatch literal boolean \fIstr\fR starts with \fIarg\fR
 plus   literal integer \fIarg\fR plus \fInum\fR
 minus  literal integer \fIarg\fR minus \fInum\fR
+multiply       literal integer \fInum\fR multiplie by \fIarg\fR
 divide literal integer \fInum\fR divided by \fIarg\fR
 modulo literal integer \fInum\fR modulo \fIarg\fR
 num    literal integer Set \fInum\fR to \fIarg\fR.
 divide literal integer \fInum\fR divided by \fIarg\fR
 modulo literal integer \fInum\fR modulo \fIarg\fR
 num    literal integer Set \fInum\fR to \fIarg\fR.
index dd43dc8acfa3f17c4f0cc41f86b0a8a0c96fa501..50722a7c418647db6b959369b237294e68dbddd0 100644 (file)
@@ -177,6 +177,7 @@ static struct ftable functable[] = {
      { "localmbox",  TF_LMBOX, FT_LS_LIT,      0,              TFL_PUTS },
      { "plus",       TF_NUM,   FT_LV_PLUS_L,   0,              TFL_PUTN },
      { "minus",      TF_NUM,   FT_LV_MINUS_L,  0,              TFL_PUTN },
      { "localmbox",  TF_LMBOX, FT_LS_LIT,      0,              TFL_PUTS },
      { "plus",       TF_NUM,   FT_LV_PLUS_L,   0,              TFL_PUTN },
      { "minus",      TF_NUM,   FT_LV_MINUS_L,  0,              TFL_PUTN },
+     { "multiply",   TF_NUM,   FT_LV_MULTIPLY_L, 0,            TFL_PUTN },
      { "divide",     TF_NUM,   FT_LV_DIVIDE_L, 0,              TFL_PUTN },
      { "modulo",     TF_NUM,   FT_LV_MODULO_L, 0,              TFL_PUTN },
      { "charleft",   TF_NONE,  FT_LV_CHAR_LEFT, 0,             TFL_PUTN },
      { "divide",     TF_NUM,   FT_LV_DIVIDE_L, 0,              TFL_PUTN },
      { "modulo",     TF_NUM,   FT_LV_MODULO_L, 0,              TFL_PUTN },
      { "charleft",   TF_NONE,  FT_LV_CHAR_LEFT, 0,             TFL_PUTN },
index 97a4a05a83a78c370eb7b0925f1a0cc0fb6294a3..ec60e1ba48bb633b50fe593c94f15331a72ab028 100644 (file)
@@ -745,6 +745,9 @@ fmt_scan (struct format *format, charstring_t scanlp, int width, int *dat,
        case FT_LV_MINUS_L:
            value = fmt->f_value - value;
            break;
        case FT_LV_MINUS_L:
            value = fmt->f_value - value;
            break;
+       case FT_LV_MULTIPLY_L:
+           value *= fmt->f_value;
+           break;
        case FT_LV_DIVIDE_L:
            if (fmt->f_value)
                value = value / fmt->f_value;
        case FT_LV_DIVIDE_L:
            if (fmt->f_value)
                value = value / fmt->f_value;
index b757e8e005273cd462a42921ce2c384b238cb844..805ddfecda11f99f506f13acb21eb7c7ccaaedde 100755 (executable)
@@ -36,5 +36,9 @@ printf '%s\n' -042 >"$expected"
 fmttest -raw -format '%04(minus -42)' 0 >"$actual"
 check "$expected" "$actual"
 
 fmttest -raw -format '%04(minus -42)' 0 >"$actual"
 check "$expected" "$actual"
 
+# check multiply
+printf '%s\n' 42 >"$expected"
+fmttest -raw -format '%(void(num 7))%(multiply 6)' 0 >"$actual"
+check "$expected" "$actual"
 
 exit $failed
 
 exit $failed
index 463c7edfa5c8374693012b2bd1f12f09915ded1c..a45ea801898198bbc1e0a4297627046ac1ba154f 100644 (file)
@@ -284,6 +284,7 @@ dumpone(struct format *fmt)
        case FT_LV_LIT:
        case FT_LV_PLUS_L:
        case FT_LV_MINUS_L:
        case FT_LV_LIT:
        case FT_LV_PLUS_L:
        case FT_LV_MINUS_L:
+       case FT_LV_MULTIPLY_L:
        case FT_LV_DIVIDE_L:
        case FT_LV_MODULO_L:
                printf(" value %d", fmt->f_value);
        case FT_LV_DIVIDE_L:
        case FT_LV_MODULO_L:
                printf(" value %d", fmt->f_value);
@@ -370,6 +371,7 @@ f_typestr(int t)
        case FT_LV_STRLEN: return("LV_STRLEN");
        case FT_LV_PLUS_L: return("LV_PLUS_L");
        case FT_LV_MINUS_L: return("LV_MINUS_L");
        case FT_LV_STRLEN: return("LV_STRLEN");
        case FT_LV_PLUS_L: return("LV_PLUS_L");
        case FT_LV_MINUS_L: return("LV_MINUS_L");
+       case FT_LV_MULTIPLY_L: return("LV_MULTIPLY_L");
        case FT_LV_DIVIDE_L: return("LV_DIVIDE_L");
        case FT_LV_MODULO_L: return("LV_MODULO_L");
        case FT_LV_CHAR_LEFT: return("LV_CHAR_LEFT");
        case FT_LV_DIVIDE_L: return("LV_DIVIDE_L");
        case FT_LV_MODULO_L: return("LV_MODULO_L");
        case FT_LV_CHAR_LEFT: return("LV_CHAR_LEFT");
index a7742bd1a5a94f6b4a367107714af5ec94944a99..712d7df2da4df57ca5356680a0792522308fa9bc 100644 (file)
@@ -920,6 +920,7 @@ dumpone(struct format *fmt)
        case FT_LV_LIT:
        case FT_LV_PLUS_L:
        case FT_LV_MINUS_L:
        case FT_LV_LIT:
        case FT_LV_PLUS_L:
        case FT_LV_MINUS_L:
+       case FT_LV_MULTIPLY_L:
        case FT_LV_DIVIDE_L:
        case FT_LV_MODULO_L:
                printf(" value %d", fmt->f_value);
        case FT_LV_DIVIDE_L:
        case FT_LV_MODULO_L:
                printf(" value %d", fmt->f_value);
@@ -1044,6 +1045,7 @@ f_typestr(int t)
        case FT_LV_STRLEN: return("LV_STRLEN");
        case FT_LV_PLUS_L: return("LV_PLUS_L");
        case FT_LV_MINUS_L: return("LV_MINUS_L");
        case FT_LV_STRLEN: return("LV_STRLEN");
        case FT_LV_PLUS_L: return("LV_PLUS_L");
        case FT_LV_MINUS_L: return("LV_MINUS_L");
+       case FT_LV_MULTIPLY_L: return("LV_MULTIPLY_L");
        case FT_LV_DIVIDE_L: return("LV_DIVIDE_L");
        case FT_LV_MODULO_L: return("LV_MODULO_L");
        case FT_LV_CHAR_LEFT: return("LV_CHAR_LEFT");
        case FT_LV_DIVIDE_L: return("LV_DIVIDE_L");
        case FT_LV_MODULO_L: return("LV_MODULO_L");
        case FT_LV_CHAR_LEFT: return("LV_CHAR_LEFT");