diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-06-30 19:01:05 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-06-30 19:01:05 +0300 |
commit | 6b16ba1983922772ad47c5feec286e9c940de705 (patch) | |
tree | 146b8faf39047c3c09c6887523dd2b9b3a9d9178 | |
parent | 5bb282734c5571bba9f3681accabfd6f3b0f4784 (diff) | |
download | mailutils-6b16ba1983922772ad47c5feec286e9c940de705.tar.gz mailutils-6b16ba1983922772ad47c5feec286e9c940de705.tar.bz2 |
Improve MH format parser.
* mh/fmtcheck.c (main): Assume -dump if no input message and
no -disass is given.
* mh/mh_fmtgram.y: Enable error-verbose mode
(funcall production): Use MHA_OPTARG_NIL flag to provide
0 (or "") default argument.
(yyerror): Improve location printer
(yylex_initial): Correctly handle %%
* mh/mh_format.c (mh_string_move): Rename to mh_string_copy
(builtin_msg, builtin_cur): Try to obtain message number only
if msgno is 0.
(builtin_tab): Fix definitions of comp, lit, and num
(mh_format_dump_disass): Print width.
* mh/mh_format.h (MHA_OPTARG_NIL): New flag.
* mh/tests/fmtcomp.at: New file.
* mh/tests/fmtfunc.at: New file.
* mh/tests/Makefile.am: Add new files.
* mh/tests/testsuite.at: Likewise.
* mh/tests/atlocal.in (MHETCDIR): New variable.
* mh/tests/scan.at: Test external formats.
-rw-r--r-- | mh/fmtcheck.c | 3 | ||||
-rw-r--r-- | mh/mh_fmtgram.y | 59 | ||||
-rw-r--r-- | mh/mh_format.c | 26 | ||||
-rw-r--r-- | mh/mh_format.h | 1 | ||||
-rw-r--r-- | mh/tests/Makefile.am | 2 | ||||
-rw-r--r-- | mh/tests/atlocal.in | 1 | ||||
-rw-r--r-- | mh/tests/fmtcomp.at | 318 | ||||
-rw-r--r-- | mh/tests/fmtfunc.at | 313 | ||||
-rw-r--r-- | mh/tests/scan.at | 60 | ||||
-rw-r--r-- | mh/tests/testsuite.at | 2 |
10 files changed, 755 insertions, 30 deletions
diff --git a/mh/fmtcheck.c b/mh/fmtcheck.c index b7ab6a1d8..8c8509744 100644 --- a/mh/fmtcheck.c +++ b/mh/fmtcheck.c @@ -97,7 +97,8 @@ main (int argc, char **argv) switch (argc) { case 0: - dump_option = 1; + if (!disass_option) + dump_option = 1; break; case 1: diff --git a/mh/mh_fmtgram.y b/mh/mh_fmtgram.y index 084445d3f..523bc5c7f 100644 --- a/mh/mh_fmtgram.y +++ b/mh/mh_fmtgram.y @@ -137,14 +137,14 @@ static struct node *typecast (struct node *node, enum mh_type type); } arg; }; -%token <num> NUMBER -%token <str> STRING COMPONENT -%token <arg> ARGUMENT -%token <builtin> FUNCTION -%token IF ELIF ELSE FI -%token <fmtspec> FMTSPEC +%token <num> NUMBER "number" +%token <str> STRING "string" COMPONENT "component" +%token <arg> ARGUMENT "argument" +%token <builtin> FUNCTION "function name" +%token IF "%<" ELIF "%?" ELSE "%|" FI "%>" +%token <fmtspec> FMTSPEC "format specifier" %token BOGUS -%token EOFN +%token EOFN ")" %type <nodelist> list zlist elif_list %type <nodeptr> item escape component funcall cntl argument @@ -152,6 +152,8 @@ static struct node *typecast (struct node *node, enum mh_type type); %type <builtin> function %type <fmtspec> fmtspec +%error-verbose + %% input : list @@ -234,14 +236,28 @@ funcall : function argument EOFN } else if (arg == NULL) { - if (($1->optarg & MHA_LITERAL) - && $1->argtype == mhtype_str) + if ($1->optarg & MHA_OPTARG_NIL) { - arg = new_node (fmtnode_literal, mhtype_str); - arg->v.str = ""; + switch ($1->argtype) + { + case mhtype_str: + arg = new_node (fmtnode_literal, mhtype_str); + arg->v.str = ""; + break; + + case mhtype_num: + arg = new_node (fmtnode_number, mhtype_num); + arg->v.num = 0; + break; + + default: + abort (); + } } else if ($1->optarg & MHA_OPTARG) - /* ok - ignore */; + { + /* ok - ignore */; + } else { yyerror ("required argument missing"); @@ -535,11 +551,16 @@ yyerror (const char *s) mu_stream_write (mu_strerr, bol + i, 1, NULL); } mu_stream_write (mu_strerr, "\n", 1, NULL); - mu_error ("%*.*s^%*.*s^", - b + yylloc.beg.mu_col - 1, - b + yylloc.beg.mu_col - 1, "", - e + yylloc.end.mu_col - yylloc.beg.mu_col - b - 1, - e + yylloc.end.mu_col - yylloc.beg.mu_col - b - 1, ""); + if (mu_locus_point_eq (&yylloc.beg, &yylloc.end)) + mu_error ("%*.*s^", + b + yylloc.beg.mu_col - 1, + b + yylloc.beg.mu_col - 1, ""); + else + mu_error ("%*.*s^%*.*s^", + b + yylloc.beg.mu_col - 1, + b + yylloc.beg.mu_col - 1, "", + e + yylloc.end.mu_col - yylloc.beg.mu_col - b - 1, + e + yylloc.end.mu_col - yylloc.beg.mu_col - b - 1, ""); } return 0; } @@ -666,7 +687,9 @@ yylex_initial (void) case '<': return IF; case '%': - return '%'; + unput (c); + unput (c); + break; case '(': unput (c); return token_function (); diff --git a/mh/mh_format.c b/mh/mh_format.c index 50f84f239..9b19686e3 100644 --- a/mh/mh_format.c +++ b/mh/mh_format.c @@ -97,7 +97,7 @@ mh_string_load (struct mh_string *s, char const *str) } static void -mh_string_move (struct mh_fvm *mach, enum regid dst, enum regid src) +mh_string_copy (struct mh_fvm *mach, enum regid dst, enum regid src) { mh_string_load (&mach->str[dst], mach->str[src].ptr); } @@ -546,7 +546,7 @@ mh_fvm_run (mh_fvm_t mach, mu_message_t msg, size_t msgno) { long dst = MHI_NUM (mach->prog[mach->pc++]); long src = MHI_NUM (mach->prog[mach->pc++]); - mh_string_move (mach, dst, src); + mh_string_copy (mach, dst, src); /* FIXME: perhaps copy, not move? */ } break; @@ -696,7 +696,8 @@ static void builtin_msg (struct mh_fvm *mach) { size_t msgno = mach->msgno; - mh_message_number (mach->message, &msgno); + if (msgno == 0) + mh_message_number (mach->message, &msgno); mach->num[R_REG] = msgno; } @@ -714,7 +715,8 @@ builtin_cur (struct mh_fvm *mach) mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_mailbox", NULL, rc); exit (1); } - mh_message_number (mach->message, &msgno); + if (msgno == 0) + mh_message_number (mach->message, &msgno); mh_mailbox_get_cur (mbox, &cur); /* FIXME: Cache this */ mach->num[R_REG] = msgno == cur; } @@ -795,7 +797,8 @@ builtin_amatch (struct mh_fvm *mach) { char const *arg = mh_string_value (&mach->str[R_ARG]); size_t len = strlen (arg); - mach->num[R_REG] = strncmp (mh_string_value (&mach->str[R_REG]), arg, len); + mach->num[R_REG] = + strncmp (mh_string_value (&mach->str[R_REG]), arg, len) == 0; } static void @@ -844,7 +847,7 @@ builtin_num (struct mh_fvm *mach) static void builtin_lit (struct mh_fvm *mach) { - mh_string_move (mach, R_REG, R_ARG); + mh_string_copy (mach, R_REG, R_ARG); } static void @@ -891,7 +894,7 @@ static void builtin_comp (struct mh_fvm *mach) { /* FIXME: Check this */ - mh_string_move (mach, R_REG, R_ARG); + mh_string_copy (mach, R_REG, R_ARG); } /* compval comp integer num set to "atoi(comp)"*/ @@ -1198,7 +1201,7 @@ builtin_szone (struct mh_fvm *mach) static void builtin_str_noop (struct mh_fvm *mach) { - mh_string_move (mach, R_REG, R_ARG); + mh_string_copy (mach, R_REG, R_ARG); } /* date2local date coerce date to local timezone*/ @@ -1830,15 +1833,15 @@ mh_builtin_t builtin_tab[] = { { "minus", builtin_minus, mhtype_num, mhtype_num, MHA_LITERAL }, { "divide", builtin_divide, mhtype_num, mhtype_num, MHA_LITERAL }, { "modulo", builtin_modulo, mhtype_num, mhtype_num, MHA_LITERAL }, - { "num", builtin_num, mhtype_num, mhtype_num, MHA_LITERAL }, - { "lit", builtin_lit, mhtype_str, mhtype_str, MHA_LITERAL }, + { "num", builtin_num, mhtype_num, mhtype_num, MHA_LITERAL|MHA_OPTARG|MHA_OPTARG_NIL }, + { "lit", builtin_lit, mhtype_str, mhtype_str, MHA_LITERAL|MHA_OPTARG|MHA_OPTARG_NIL }, { "getenv", builtin_getenv, mhtype_str, mhtype_str, MHA_LITERAL }, { "profile", builtin_profile, mhtype_str, mhtype_str, MHA_LITERAL }, { "nonzero", builtin_nonzero, mhtype_num, mhtype_num, MHA_OPTARG }, { "zero", builtin_zero, mhtype_num, mhtype_num, MHA_OPTARG }, { "null", builtin_null, mhtype_num, mhtype_str, MHA_OPTARG }, { "nonnull", builtin_nonnull, mhtype_num, mhtype_str, MHA_OPTARG }, - { "comp", builtin_comp, mhtype_num, mhtype_str, MHA_OPTARG }, + { "comp", builtin_comp, mhtype_str, mhtype_str }, { "compval", builtin_compval, mhtype_num, mhtype_str }, { "trim", builtin_trim, mhtype_none, mhtype_str, MHA_OPTARG }, { "putstr", builtin_putstr, mhtype_none, mhtype_str, MHA_OPTARG }, @@ -2055,6 +2058,7 @@ mh_format_dump_disass (mh_format_t fmt) int fmtspec = MHI_NUM (prog[pc++]); printf ("fmtspec "); mh_print_fmtspec (fmtspec); + printf(", %d", fmtspec & MH_WIDTH_MASK); } break; diff --git a/mh/mh_format.h b/mh/mh_format.h index d0de79f8d..afa94a2eb 100644 --- a/mh/mh_format.h +++ b/mh/mh_format.h @@ -126,6 +126,7 @@ struct mh_format #define MHA_OPTARG 0x1 #define MHA_LITERAL 0x2 #define MHA_VOID 0x4 +#define MHA_OPTARG_NIL 0x8 typedef struct mh_builtin mh_builtin_t; diff --git a/mh/tests/Makefile.am b/mh/tests/Makefile.am index 27e5dfa9c..df74d2089 100644 --- a/mh/tests/Makefile.am +++ b/mh/tests/Makefile.am @@ -50,6 +50,8 @@ TESTSUITE_AT = \ anno.at\ burst.at\ comp.at\ + fmtcomp.at\ + fmtfunc.at\ folder.at\ forw.at\ inc.at\ diff --git a/mh/tests/atlocal.in b/mh/tests/atlocal.in index 6a7f40528..086ed8939 100644 --- a/mh/tests/atlocal.in +++ b/mh/tests/atlocal.in @@ -4,6 +4,7 @@ # Inc. PATH=@abs_builddir@:@abs_top_builddir@/testsuite:@abs_top_builddir@/mh:$top_srcdir:$srcdir:$PATH +MHETCDIR=@abs_top_srcdir@/mh/etc # mimeflt [FILE] # Filter out all variable information from a MIME message in FILE. diff --git a/mh/tests/fmtcomp.at b/mh/tests/fmtcomp.at new file mode 100644 index 000000000..eb21a290c --- /dev/null +++ b/mh/tests/fmtcomp.at @@ -0,0 +1,318 @@ +# This file is part of GNU Mailutils. -*- Autotest -*- +# Copyright (C) 2010-2012, 2014-2017 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. + +AT_BANNER(Format compilation) + +dnl ------------------------------------------------------------ +dnl fmtcheck([NAME], [INPUT], [STDOUT = `'], [STDERR = `']) +dnl +m4_pushdef([FMTCOMP],[ +AT_SETUP([$1]) +AT_KEYWORDS([format fmtcomp]) +AT_CHECK([fmtcheck -disass -dump -format '$2' +], +[m4_if([$4],[],[0],[1])], +[$3],[$4]) +AT_CLEANUP]) + +FMTCOMP([literal], +[text], +[PRINT("text") + 0001: sets reg, "text" + 0007: prints + 0008: stop +]) + +FMTCOMP([component], +[%{from}], +[PRINT(COMPONENT.from) + 0001: ldcomp reg, "from" + 0007: prints + 0008: stop +]) + +FMTCOMP([component formatted], +[%-40{from}], +[FORMAT(RALIGN|NOZEROPAD|NOCOMPWS, 40, COMPONENT.from) + 0001: ldcomp reg, "from" + 0007: fmtspec RALIGN|NOZEROPAD|NOCOMPWS, 40 + 0009: prints + 0010: stop +]) + +FMTCOMP([function call], +[%(msg)], +[PRINT(msg()) + 0001: call msg + 0003: printn + 0004: stop +]) + +FMTCOMP([function call formatted], +[%08(msg)], +[FORMAT(NORALIGN|ZEROPAD|NOCOMPWS, 8, msg()) + 0001: call msg + 0003: fmtspec NORALIGN|ZEROPAD|NOCOMPWS, 8 + 0005: printn + 0006: stop +]) + +FMTCOMP([function call with argument], +[%(lit text: )], +[PRINT(lit("text: ")) + 0001: sets arg, "text: " + 0007: call lit + 0009: prints + 0010: stop +]) + +FMTCOMP([function call with numeric argument], +[%(num 10)], +[PRINT(num(10)) + 0001: setn arg, 10 + 0004: call num + 0006: printn + 0007: stop +]) + +FMTCOMP([function call with numeric argument and format spec], +[%08(num 10)], +[FORMAT(NORALIGN|ZEROPAD|NOCOMPWS, 8, num(10)) + 0001: setn arg, 10 + 0004: call num + 0006: fmtspec NORALIGN|ZEROPAD|NOCOMPWS, 8 + 0008: printn + 0009: stop +]) + +FMTCOMP([function call with component argument], +[%(decode{subject})], +[PRINT(decode(COMPONENT.subject)) + 0001: ldcomp reg, "subject" + 0008: movs arg, reg + 0011: call decode + 0013: prints + 0014: stop +]) + +FMTCOMP([nested function calls], +[%(null(decode{subject}))], +[PRINT(null(decode(COMPONENT.subject))) + 0001: ldcomp reg, "subject" + 0008: movs arg, reg + 0011: call decode + 0013: movs arg, reg + 0016: call null + 0018: printn + 0019: stop +]) + +FMTCOMP([nested function calls with typecast], +[%(zero(decode{subject}))], +[PRINT(zero(NUM(decode(COMPONENT.subject)))) + 0001: ldcomp reg, "subject" + 0008: movs arg, reg + 0011: call decode + 0013: atoi + 0014: movn arg, reg + 0017: call zero + 0019: printn + 0020: stop +]) + +FMTCOMP([simple conditional], +[%<{replied}-%>], +[IF (COMPONENT.replied) THEN + PRINT("-") +FI + 0001: ldcomp reg, "replied" + 0008: brzs 18 + 0010: sets reg, "-" + 0015: prints + 0016: branch 26 + 0018: setn reg, 0 + 0021: sets reg, "" + 0026: stop +],[],[-format]) + +FMTCOMP([if-else], +[%<{replied}-%|+%>], +[IF (COMPONENT.replied) THEN + PRINT("-") +ELSE + PRINT("+") +FI + 0001: ldcomp reg, "replied" + 0008: brzs 18 + 0010: sets reg, "-" + 0015: prints + 0016: branch 24 + 0018: sets reg, "+" + 0023: prints + 0024: stop +]) + +FMTCOMP([if-elsif-else], +[%<{replied}-%?{encrypted}E%| %>], +[IF (COMPONENT.replied) THEN + PRINT("-") +ELSE + IF (COMPONENT.encrypted) THEN + PRINT("E") + ELSE + PRINT(" ") + FI +FI + 0001: ldcomp reg, "replied" + 0008: brzs 18 + 0010: sets reg, "-" + 0015: prints + 0016: branch 41 + 0018: ldcomp reg, "encrypted" + 0025: brzs 35 + 0027: sets reg, "E" + 0032: prints + 0033: branch 41 + 0035: sets reg, " " + 0040: prints + 0041: stop +]) + +# The example below is taken from mh-format(1), subsection +# "Other Hints and Tips". +# It issues a spurious PRINT instruction, which is intended. The following +# testcase uses a fixed version. +FMTCOMP([inline conditional], +[%(formataddr %<{reply-to}%|%{from}%>)], +[formataddr(IF (COMPONENT.reply-to) THEN; ; ELSE PRINT(COMPONENT.from); FI) + 0001: ldcomp reg, "reply-to" + 0008: brzs 12 + 0010: branch 19 + 0012: ldcomp reg, "from" + 0018: prints + 0019: movs arg, reg + 0022: call formataddr + 0024: stop +]) + +FMTCOMP([inline conditional (2)], +[%(formataddr %<{reply-to}%|%(void{from})%>)], +[formataddr(IF (COMPONENT.reply-to) THEN; ; ELSE COMPONENT.from; FI) + 0001: ldcomp reg, "reply-to" + 0008: brzs 12 + 0010: branch 18 + 0012: ldcomp reg, "from" + 0018: movs arg, reg + 0021: call formataddr + 0023: stop +]) + +FMTCOMP([statement list], +[%(formataddr %<{reply-to}%|%(void{from})%>)%(void(width))%(putaddr To: )], +[formataddr(IF (COMPONENT.reply-to) THEN; ; ELSE COMPONENT.from; FI) +width() +putaddr("To: ") + 0001: ldcomp reg, "reply-to" + 0008: brzs 12 + 0010: branch 18 + 0012: ldcomp reg, "from" + 0018: movs arg, reg + 0021: call formataddr + 0023: call width + 0025: sets arg, "To: " + 0031: call putaddr + 0033: stop +]) + +m4_popdef[FMTCOMP]) + +# FMTCOMP(NAME,INPUT,ERR) +m4_pushdef([FMTCOMP],[ +AT_SETUP([$1]) +AT_KEYWORDS([format fmtdiag]) +AT_DATA([input.fmt],[$2]) +AT_CHECK([fmtcheck -form input.fmt +], +[1], +[], +[$3]) +AT_CLEANUP]) + +AT_BANNER(Format error diagnostics) + +FMTCOMP([unknown function], +[%; comment +test %(function) +], +[fmtcheck: input.fmt:2.8-15: unknown function +fmtcheck: test %(function) +fmtcheck: ^ ^ +]) + +FMTCOMP([condition syntax], +[%<%{reply-to}%|%{from}%> +], +[[fmtcheck: input.fmt:1.1-2: '(' or '{' expected] +fmtcheck: %<%{reply-to}%|%{from}%> +fmtcheck: ^^ +]) + +FMTCOMP([unclosed control], +[%<{reply-to}%|%{from}> +], +[fmtcheck: input.fmt:1.22: syntax error, unexpected $end, expecting %> +fmtcheck: %<{reply-to}%|%{from} +fmtcheck: ^ +]) + +FMTCOMP([extra ELSE], +[%<{reply-to}%|test%|test%> +], +[fmtcheck: input.fmt:1.19-20: syntax error, unexpected %|, expecting %> +fmtcheck: %<{reply-to}%|test%|test%> +fmtcheck: ^^ +]) + +# FIXME: Error locations in the following tests could be improved, if +# %locations were enabled. + +FMTCOMP([unwanted argument], +[%(msg 10) +], +[fmtcheck: input.fmt:1.9: function doesn't take arguments +fmtcheck: %(msg 10) +fmtcheck: ^ +]) + +FMTCOMP([missing argument], +[%(decode) +], +[fmtcheck: input.fmt:1.9: required argument missing +fmtcheck: %(decode) +fmtcheck: ^ +]) + +FMTCOMP([argument type mismatch], +[%(lit{comp}) +], +[fmtcheck: input.fmt:1.12: argument must be literal +fmtcheck: %(lit{comp}) +fmtcheck: ^ +]) + +m4_popdef[FMTCOMP]) + +# End of fmtcomp.at diff --git a/mh/tests/fmtfunc.at b/mh/tests/fmtfunc.at new file mode 100644 index 000000000..65107f3ed --- /dev/null +++ b/mh/tests/fmtfunc.at @@ -0,0 +1,313 @@ +# This file is part of GNU Mailutils. -*- Autotest -*- +# Copyright (C) 2010-2012, 2014-2017 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. + +AT_BANNER(Format functions) + +dnl ------------------------------------------------------------ +dnl fmtrun([NAME], [FORMAT], [MSG], [STDOUT = `'], [STDERR = `']) +dnl +m4_pushdef([FMTFUNC],[ +AT_SETUP([$1]) +AT_KEYWORDS([fmtfunc format]) +AT_DATA([input.fmt],[$2]) +AT_DATA([message],[$3]) +AT_CHECK([fmtcheck -form input.fmt -msgno 1 -width 80 message +], +[m4_if([$5],[],[0],[1])], +[$4],[$5]) +AT_CLEANUP]) + +FMTFUNC([msg], +[%(msg) +], +[ + +], +[1 +]) + +# FIXME: cur +# FIXME: unseen + +FMTFUNC([size], +[%(size) +], +[From: gray@example.net +To: root@example.com +Subject: Test + +test message +], +[72 +]) + +FMTFUNC([num], +[%(num 10) +%(num) +], +[ + +], +[10 +0 +]) + +FMTFUNC([lit], +[%(lit string) +%(lit) +], +[ + +], +[string +]) + +FMTFUNC([void], +[%(void(num 10)) +], +[ + +], +[]) + +FMTFUNC([strlen], +[%(lit string) +%(strlen) +], +[ + +], +[string +6 +]) + +# FIXME: Not quite sure: perhaps it should report 80 +FMTFUNC([width], +[%(width) +], +[ + +], +[79 +]) + +FMTFUNC([charleft], +[input %(charleft) +], +[ + +], +[input 73 +]) + +# FIXME: timenow +# FIXME: ne +# FIXME: myhost +# FIXME: myname +# FIXME: localmbox + +FMTFUNC([eq], +[%(void(num 10))%(eq 5):%(void(num 5))%(eq 5) +], +[ + +], +[0:1 +]) + +FMTFUNC([ne], +[%(void(num 10))%(ne 5):%(void(num 5))%(ne 5) +], +[ + +], +[1:0 +]) + +FMTFUNC([gt], +[%(void(num 10))%(gt 5):%(void(num 3))%(gt 5) +], +[ + +], +[1:0 +]) + +FMTFUNC([match], +[%(void(lit a stringent test))%(match string) +%(void(lit one more test))%(match string) +], +[ + +], +[1 +0 +]) + +FMTFUNC([amatch], +[%(void(lit stringent test))%(amatch string) +%(void(lit a stringent test))%(amatch string) +], +[ + +], +[1 +0 +]) + +FMTFUNC([plus], +[%(void(num 10))%(plus 15) +], +[ + +], +[25 +]) + +FMTFUNC([minus], +[%(void(num 10))%(minus 15) +], +[ + +], +[-5 +]) + +FMTFUNC([divide], +[%(void(num 10))%(divide 2) +], +[ + +], +[5 +]) + +FMTFUNC([modulo], +[%(void(num 10))%(modulo 2) +%(void(num 5))%(modulo 2) +], +[ + +], +[0 +1 +]) + +AT_SETUP([getenv]) +AT_KEYWORDS([fmtfunc format]) +AT_DATA([input.fmt],[%(getenv MH_TEST) +]) +AT_DATA([message],[ + +]) +AT_CHECK([MH_TEST=defined fmtcheck -form input.fmt -width 80 message +], +[0], +[defined +]) +AT_CLEANUP + +AT_SETUP([profile]) +AT_KEYWORDS([fmtfunc format]) +AT_DATA([input.fmt],[%(profile Local-Mailbox) +%(profile undefined) +%(profile moreproc) +]) +AT_DATA([message],[ + +]) +AT_DATA([mh_profile],[Local-Mailbox: foo@example.org +moreproc: simple-more +]) +AT_CHECK([MH=`pwd`/mh_profile fmtcheck -form input.fmt -width 80 message +], +[0], +[foo@example.org + +simple-more +]) +AT_CLEANUP + +FMTFUNC([nonzero], +[%(nonzero(num 10)) +%(nonzero(num)) +%(void(width))%(nonzero) +], +[ + +], +[1 +0 +1 +]) + +FMTFUNC([zero], +[%(zero(num 10)) +%(zero(num)) +%(void(width))%(zero) +], +[ + +], +[0 +1 +0 +]) + +FMTFUNC([null], +[%(lit input)%(null) +%(lit)%(null) +], +[ + +], +[input0 +1 +]) + +FMTFUNC([nonnull], +[%(lit input)%(nonnull) +%(lit)%(nonnull) +], +[ + +], +[input1 +0 +]) + +FMTFUNC([comp], +[%(comp{From}) +], +[From: foo@example.com + +], +[foo@example.com +]) + +FMTFUNC([compval], +[%(comp{X-Level}) +], +[From: foo@example.com +X-Level: 8 + +], +[8 +]) + + + +m4_popdef([FMTFUNC])
\ No newline at end of file diff --git a/mh/tests/scan.at b/mh/tests/scan.at index 118a51b8b..062356be6 100644 --- a/mh/tests/scan.at +++ b/mh/tests/scan.at @@ -93,5 +93,65 @@ scan | sed 's/ *$//' 5 07/13 To:Foo Bar Empty MIME Parts<<------- =_aaaaaaaaaa0 Content- ]) +MH_CHECK([default format],[scan06 scan.default],[ +MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox],[700]) +scan -form $MHETCDIR/scan.default| sed 's/ *$//' +], +[0], +[ 1 12/28 Foo Bar Jabberwocky<<`Twas brillig, and the slithy toves + 2 12/28 Bar Re: Jabberwocky<<It seems very pretty, but it's + 3 07/13 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type: + 4 07/13 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type: + 5 07/13 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Content- +]) + +MH_CHECK([mailx format],[scan07 scan.mailx],[ +MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox],[700]) +scan -form $MHETCDIR/scan.mailx| sed 's/ *$//' +], +[0], +[ N 1 Foo Bar Fri Dec 28 22:18 Jabberwocky + N 2 Bar Fri Dec 28 23:28 Re: Jabberwocky + N 3 Sergey Poznyakoff Sat Jul 13 00:43 Simple MIME + N 4 Sergey Poznyakoff Sat Jul 13 00:50 Nested MIME + N 5 Sergey Poznyakoff Sat Jul 13 00:43 Empty MIME Parts +]) + +MH_CHECK([size format],[scan08 scan.size],[ +MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox],[700]) +scan -form $MHETCDIR/scan.size| sed 's/ *$//' +], +[0], +[ 1 12/28 1354 Foo Bar Jabberwocky<<`Twas brillig, and the slithy + 2 12/28 614 Bar Re: Jabberwocky<<It seems very pretty, but + 3 07/13 1647 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content + 4 07/13 3477 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content + 5 07/13 935 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Co +]) + +MH_CHECK([time format],[scan08 scan.time],[ +MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox],[700]) +scan -form $MHETCDIR/scan.time| sed 's/ *$//' +], +[0], +[ 1 12/28 22:18+02 Foo Bar Jabberwocky<<`Twas brillig, and the sli + 2 12/28 23:28+02 Bar Re: Jabberwocky<<It seems very pretty, + 3 07/13 00:43+03 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Cont + 4 07/13 00:50+03 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Cont + 5 07/13 00:43+03 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 +]) + +MH_CHECK([timely format],[scan09 scan.timely],[ +MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox],[700]) +scan -form $MHETCDIR/scan.timely| sed 's/ *$//' +], +[0], +[ 1 Dec01 Foo Bar Jabberwocky<<`Twas brillig, and the slithy toves + 2 Dec01 Bar Re: Jabberwocky<<It seems very pretty, but it's + 3 Jul02 Sergey Poznyakoff Simple MIME<<------- =_aaaaaaaaaa0 Content-Type: + 4 Jul02 Sergey Poznyakoff Nested MIME<<------- =_aaaaaaaaaa0 Content-Type: + 5 Jul02 Sergey Poznyakoff Empty MIME Parts<<------- =_aaaaaaaaaa0 Content- +]) + m4_popdef[MH_KEYWORDS]) # End of scan.at diff --git a/mh/tests/testsuite.at b/mh/tests/testsuite.at index b1d7a7338..c6820843c 100644 --- a/mh/tests/testsuite.at +++ b/mh/tests/testsuite.at @@ -63,6 +63,8 @@ AT_CLEANUP AT_INIT m4_include([install-mh.at]) +m4_include([fmtcomp.at]) +m4_include([fmtfunc.at]) m4_include([mhseq.at]) m4_include([ali.at]) m4_include([folder.at]) |