diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-07-01 02:11:16 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-07-01 02:18:21 +0300 |
commit | c2e631e78f3259ff189f6cfc9e2c28b371aba361 (patch) | |
tree | c90c7ebde0b6a5504efe9380e175f5211f91e876 | |
parent | 6b16ba1983922772ad47c5feec286e9c940de705 (diff) | |
download | mailutils-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.
-rw-r--r-- | mh/mh_fmtgram.y | 34 | ||||
-rw-r--r-- | mh/mh_format.c | 20 | ||||
-rw-r--r-- | mh/mh_format.h | 4 | ||||
-rw-r--r-- | mh/tests/fmtcomp.at | 51 | ||||
-rw-r--r-- | mh/tests/fmtfunc.at | 70 |
5 files changed, 135 insertions, 44 deletions
diff --git a/mh/mh_fmtgram.y b/mh/mh_fmtgram.y index 523bc5c7f..04a890e3d 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 9b19686e3..914a85b1e 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 afa94a2eb..8e2578683 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 eb21a290c..253ecd9a5 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 65107f3ed..a7d72bce5 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 |