summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2017-06-30 23:11:16 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2017-06-30 23:18:21 (GMT)
commitc2e631e78f3259ff189f6cfc9e2c28b371aba361 (patch) (side-by-side diff)
treec90c7ebde0b6a5504efe9380e175f5211f91e876
parent6b16ba1983922772ad47c5feec286e9c940de705 (diff)
downloadmailutils-c2e631e78f3259ff189f6cfc9e2c28b371aba361.tar.gz
mailutils-c2e631e78f3259ff189f6cfc9e2c28b371aba361.tar.bz2
More fixes in MH format parser
* mh/mh_fmtgram.y (codegen_node): Generate mhop_printlit instruction for fmtnode_print node with a literal or number argument. * mh/mh_format.c (mh_fvm_run): Handle mhop_printlit * mh/mh_format.h (mhop_printlit): New opcode. * mh/tests/fmtcomp.at: Update. * mh/tests/fmtfunc.at: Add more tests.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--mh/mh_fmtgram.y34
-rw-r--r--mh/mh_format.c20
-rw-r--r--mh/mh_format.h4
-rw-r--r--mh/tests/fmtcomp.at51
-rw-r--r--mh/tests/fmtfunc.at70
5 files changed, 135 insertions, 44 deletions
diff --git a/mh/mh_fmtgram.y b/mh/mh_fmtgram.y
index 523bc5c..04a890e 100644
--- a/mh/mh_fmtgram.y
+++ b/mh/mh_fmtgram.y
@@ -706,7 +706,7 @@ yylex_initial (void)
return bogus ("component or function name expected");
}
}
-
+
c = peek ();
if (c == 0)
@@ -1392,16 +1392,32 @@ codegen_node (struct mh_format *fmt, struct node *node)
switch (node->nodetype)
{
case fmtnode_print:
- codegen_node (fmt, node->v.prt.arg);
- if (node->v.prt.fmtspec)
+ if (node->v.prt.arg->nodetype == fmtnode_literal)
{
- emit_opcode (fmt, mhop_fmtspec);
- emit_instr (fmt, (mh_instr_t) (long) node->v.prt.fmtspec);
+ emit_opcode (fmt, mhop_printlit);
+ emit_string (fmt, node->v.prt.arg->v.str);
+ }
+ else if (node->v.prt.arg->nodetype == fmtnode_number)
+ {
+ char *s;
+ emit_opcode (fmt, mhop_printlit);
+ mu_asprintf (&s, "%ld", node->v.prt.arg->v.num);
+ emit_string (fmt, s);
+ free (s);
+ }
+ else
+ {
+ codegen_node (fmt, node->v.prt.arg);
+ if (node->v.prt.fmtspec)
+ {
+ emit_opcode (fmt, mhop_fmtspec);
+ emit_instr (fmt, (mh_instr_t) (long) node->v.prt.fmtspec);
+ }
+
+ if (node->v.prt.arg->datatype != mhtype_none)
+ emit_opcode_typed (fmt, node->v.prt.arg->datatype,
+ mhop_printn, mhop_prints);
}
-
- if (node->v.prt.arg->datatype != mhtype_none)
- emit_opcode_typed (fmt, node->v.prt.arg->datatype,
- mhop_printn, mhop_prints);
break;
case fmtnode_literal:
diff --git a/mh/mh_format.c b/mh/mh_format.c
index 9b19686..914a85b 100644
--- a/mh/mh_format.c
+++ b/mh/mh_format.c
@@ -633,6 +633,15 @@ mh_fvm_run (mh_fvm_t mach, mu_message_t msg, size_t msgno)
format_str (mach, mach->str[R_REG].ptr);
break;
+ case mhop_printlit:
+ {
+ size_t skip = MHI_NUM (mach->prog[mach->pc++]);
+ char const *str = MHI_STR (mach->prog[mach->pc]);
+ format_str (mach, str);
+ mach->pc += skip;
+ }
+ break;
+
case mhop_fmtspec:
mach->fmtflags = MHI_NUM (mach->prog[mach->pc++]);
break;
@@ -734,7 +743,7 @@ builtin_size (struct mh_fvm *mach)
static void
builtin_strlen (struct mh_fvm *mach)
{
- mach->num[R_REG] = mh_string_length (&mach->str[R_ARG]);
+ mach->num[R_REG] = mh_string_length (&mach->str[R_REG]);
}
static void
@@ -2052,6 +2061,15 @@ mh_format_dump_disass (mh_format_t fmt)
case mhop_prints:
printf ("prints");
break;
+
+ case mhop_printlit:
+ {
+ size_t skip = MHI_NUM (prog[pc++]);
+ char const *str = MHI_STR (prog[pc]);
+ pc += skip;
+ printf ("printlit \"%s\"", str);
+ }
+ break;
case mhop_fmtspec:
{
diff --git a/mh/mh_format.h b/mh/mh_format.h
index afa94a2..8e25786 100644
--- a/mh/mh_format.h
+++ b/mh/mh_format.h
@@ -78,6 +78,10 @@ enum mh_opcode
/* Print str reg */
mhop_prints,
+ /* Print literal
+ Format: mhop_printlit length string */
+ mhop_printlit,
+
/* Set format specification.
Format: mhop_fmtspec number */
mhop_fmtspec,
diff --git a/mh/tests/fmtcomp.at b/mh/tests/fmtcomp.at
index eb21a29..253ecd9 100644
--- a/mh/tests/fmtcomp.at
+++ b/mh/tests/fmtcomp.at
@@ -31,9 +31,8 @@ AT_CLEANUP])
FMTCOMP([literal],
[text],
[PRINT("text")
- 0001: sets reg, "text"
- 0007: prints
- 0008: stop
+ 0001: printlit "text"
+ 0006: stop
])
FMTCOMP([component],
@@ -139,13 +138,12 @@ FMTCOMP([simple conditional],
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
+ 0008: brzs 16
+ 0010: printlit "-"
+ 0014: branch 24
+ 0016: setn reg, 0
+ 0019: sets reg, ""
+ 0024: stop
],[],[-format])
FMTCOMP([if-else],
@@ -156,13 +154,11 @@ 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
+ 0008: brzs 16
+ 0010: printlit "-"
+ 0014: branch 20
+ 0016: printlit "+"
+ 0020: stop
])
FMTCOMP([if-elsif-else],
@@ -177,18 +173,15 @@ ELSE
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
+ 0008: brzs 16
+ 0010: printlit "-"
+ 0014: branch 35
+ 0016: ldcomp reg, "encrypted"
+ 0023: brzs 31
+ 0025: printlit "E"
+ 0029: branch 35
+ 0031: printlit " "
+ 0035: stop
])
# The example below is taken from mh-format(1), subsection
diff --git a/mh/tests/fmtfunc.at b/mh/tests/fmtfunc.at
index 65107f3..a7d72bc 100644
--- a/mh/tests/fmtfunc.at
+++ b/mh/tests/fmtfunc.at
@@ -84,14 +84,12 @@ FMTFUNC([void],
[])
FMTFUNC([strlen],
-[%(lit string)
-%(strlen)
+[%(lit string)=%(strlen)
],
[
],
-[string
-6
+[string=6
])
# FIXME: Not quite sure: perhaps it should report 80
@@ -221,7 +219,7 @@ AT_CHECK([MH_TEST=defined fmtcheck -form input.fmt -width 80 message
AT_CLEANUP
AT_SETUP([profile])
-AT_KEYWORDS([fmtfunc format])
+AT_KEYWORDS([fmtfunc format])xo
AT_DATA([input.fmt],[%(profile Local-Mailbox)
%(profile undefined)
%(profile moreproc)
@@ -308,6 +306,68 @@ X-Level: 8
[8
])
+# FIXME: This relies on LC_ALL=C
+FMTFUNC([decode],
+[%(decode{Subject})
+],
+[Subject: =?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= ... =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=
+
+body
+],
+[If you can read this yo ... u understand the example.
+])
+
+# FIXME: unquote
+
+FMTFUNC([trim],
+[%(void(lit trailing ))%(strlen)
+%(trim)%(strlen)
+],
+[
+
+],
+[12
+8
+])
+
+FMTFUNC([putstr],
+[%(void(lit string))%(putstr)
+%(putstr test)
+%(putstr{from})
+%(putstr(msg))
+],
+[From: foo@example.org
+
+],
+[string
+test
+foo@example.org
+1
+])
+
+# FIXME: putstrf
+
+FMTFUNC([putnum],
+[%(void(num 10))%(putnum)
+%(putnum 15)
+%(putnum{X-Number})
+%(putstr(msg))
+],
+[From: foo@example.org
+X-Number: 8
+
+body
+],
+[10
+15
+8
+1
+])
+
+# FIXME: putnumf
+
+# FIXME: putlit
+
m4_popdef([FMTFUNC]) \ No newline at end of file

Return to:

Send suggestions and report system problems to the System administrator.