summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-02 21:40:43 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-07-02 21:40:43 +0300
commitace54abd2ddae8facfce059d9442866517fc4b58 (patch)
tree137c6eba1cfcaf720766dfeb455de6c9813b5a9e
parent1c5b3cd3999a19b4ef404d7aafa557ae55461a48 (diff)
downloadmailutils-ace54abd2ddae8facfce059d9442866517fc4b58.tar.gz
mailutils-ace54abd2ddae8facfce059d9442866517fc4b58.tar.bz2
MH: fix formataddr.
* mh/mh_fmtgram.y (emit_funcall): Emit mhop_movs acc, reg if MHA_ACC flag is set. * mh/mh_format.c (mh_fvm_run): Clear all registers. (builtin_formataddr): Get previously accumulated addresses from R_ACC (builtin_tab): Mark formataddr with MHA_ACC, remove MHA_OPTARG (mh_format_dump_disass): Account for the new register. (mh_fvm_destroy): Free all registers. * mh/mh_format.h: New register R_ACC. It is needed to implement proper formataddr and concataddr functionality. * mh/tests/fmtcomp.at: Update. * mh/tests/fmtfunc.at: Update.
-rw-r--r--mh/mh_fmtgram.y7
-rw-r--r--mh/mh_format.c11
-rw-r--r--mh/mh_format.h5
-rw-r--r--mh/tests/fmtcomp.at53
-rw-r--r--mh/tests/fmtfunc.at12
5 files changed, 57 insertions, 31 deletions
diff --git a/mh/mh_fmtgram.y b/mh/mh_fmtgram.y
index 328a7a66b..8f00167c1 100644
--- a/mh/mh_fmtgram.y
+++ b/mh/mh_fmtgram.y
@@ -1433,6 +1433,13 @@ emit_special (struct mh_format *fmt, mh_builtin_t *builtin, struct node *arg)
static void
emit_funcall (struct mh_format *fmt, mh_builtin_t *builtin, struct node *arg)
{
+ if (builtin->flags & MHA_ACC)
+ {
+ emit_opcode (fmt, mhop_movs);
+ emit_instr (fmt, (mh_instr_t) (long) R_ACC);
+ emit_instr (fmt, (mh_instr_t) (long) R_REG);
+ }
+
if (builtin->flags & MHA_SPECIAL)
{
emit_special (fmt, builtin, arg);
diff --git a/mh/mh_format.c b/mh/mh_format.c
index 89a9b686e..86eeb4ff3 100644
--- a/mh/mh_format.c
+++ b/mh/mh_format.c
@@ -483,6 +483,7 @@ mh_fvm_run (mh_fvm_t mach, mu_message_t msg, size_t msgno)
mu_list_clear (mach->addrlist);
mh_string_clear (&mach->str[R_REG]);
mh_string_clear (&mach->str[R_ARG]);
+ mh_string_clear (&mach->str[R_ACC]);
mach->pc = 1;
mach->stop = 0;
@@ -1569,9 +1570,9 @@ builtin_formataddr (struct mh_fvm *mach)
size_t num;
const char *buf;
- if (mh_string_is_null (&mach->str[R_REG]))
+ if (mh_string_is_null (&mach->str[R_ACC]))
dest = NULL;
- else if (mu_address_create (&dest, mh_string_value (&mach->str[R_REG])))
+ else if (mu_address_create (&dest, mh_string_value (&mach->str[R_ACC])))
return;
if (mu_address_create (&addr, mh_string_value (&mach->str[R_ARG])))
@@ -1854,7 +1855,7 @@ mh_builtin_t builtin_tab[] = {
{ "path", builtin_path, mhtype_str, mhtype_str },
{ "ingrp", builtin_ingrp, mhtype_num, mhtype_str },
{ "gname", builtin_gname, mhtype_str, mhtype_str},
- { "formataddr", builtin_formataddr, mhtype_none, mhtype_str, MHA_OPTARG },
+ { "formataddr", builtin_formataddr, mhtype_none, mhtype_str, MHA_ACC },
{ "putaddr", builtin_putaddr, mhtype_none, mhtype_str, MHA_LITERAL },
{ "unre", builtin_unre, mhtype_str, mhtype_str },
{ "rcpt", builtin_rcpt, mhtype_num, mhtype_str },
@@ -1903,7 +1904,8 @@ mh_format_dump_disass (mh_format_t fmt)
int stop = 0;
static char *regname[] = {
[R_REG] = "reg",
- [R_ARG] = "arg"
+ [R_ARG] = "arg",
+ [R_ACC] = "acc"
};
static char c_trans[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
@@ -2104,6 +2106,7 @@ mh_fvm_destroy (mh_fvm_t *fvmp)
free (fvm->prog);
mh_string_free (&fvm->str[R_REG]);
mh_string_free (&fvm->str[R_ARG]);
+ mh_string_free (&fvm->str[R_ACC]);
addrlist_destroy (&fvm->addrlist);
mu_stream_unref (fvm->output);
diff --git a/mh/mh_format.h b/mh/mh_format.h
index ce537153c..4d8dafaba 100644
--- a/mh/mh_format.h
+++ b/mh/mh_format.h
@@ -87,7 +87,7 @@ enum mh_opcode
mhop_fmtspec,
};
-enum regid { R_REG, R_ARG };
+enum regid { R_REG, R_ARG, R_ACC };
enum mh_type
{
@@ -136,6 +136,7 @@ struct mh_format
#define MHA_LITERAL 0x010
#define MHA_VOID 0x020
#define MHA_SPECIAL 0x040
+#define MHA_ACC 0x080
typedef struct mh_builtin mh_builtin_t;
@@ -157,7 +158,7 @@ struct mh_string
struct mh_fvm
{
long num[2]; /* numeric registers */
- struct mh_string str[2]; /* string registers */
+ struct mh_string str[3]; /* string registers */
size_t pc; /* Program counter */
size_t progcnt; /* Size of allocated program*/
diff --git a/mh/tests/fmtcomp.at b/mh/tests/fmtcomp.at
index ca937866a..687f54bfc 100644
--- a/mh/tests/fmtcomp.at
+++ b/mh/tests/fmtcomp.at
@@ -221,26 +221,28 @@ FI
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
+ 0001: movs acc, reg
+ 0004: ldcomp reg, "reply-to"
+ 0011: brzs 15
+ 0013: branch 22
+ 0015: ldcomp reg, "from"
+ 0021: prints
+ 0022: movs arg, reg
+ 0025: call formataddr
+ 0027: 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
+ 0001: movs acc, reg
+ 0004: ldcomp reg, "reply-to"
+ 0011: brzs 15
+ 0013: branch 21
+ 0015: ldcomp reg, "from"
+ 0021: movs arg, reg
+ 0024: call formataddr
+ 0026: stop
])
FMTCOMP([statement list],
@@ -248,16 +250,17 @@ FMTCOMP([statement list],
[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
+ 0001: movs acc, reg
+ 0004: ldcomp reg, "reply-to"
+ 0011: brzs 15
+ 0013: branch 21
+ 0015: ldcomp reg, "from"
+ 0021: movs arg, reg
+ 0024: call formataddr
+ 0026: call width
+ 0028: sets arg, "To: "
+ 0034: call putaddr
+ 0036: stop
])
m4_popdef[FMTCOMP])
diff --git a/mh/tests/fmtfunc.at b/mh/tests/fmtfunc.at
index 28c109a8f..2abda39b1 100644
--- a/mh/tests/fmtfunc.at
+++ b/mh/tests/fmtfunc.at
@@ -399,4 +399,16 @@ body
1
])
+FMTFUNC([formataddr],
+[%(formataddr{From})%(formataddr{To})%(formataddr{Reply-To})%(putstr)
+],
+[From: root@example.com
+To: gray@example.org
+Reply-To: root@example.com
+
+data
+],
+[<root@example.com>,<gray@example.org>
+])
+
m4_popdef([FMTFUNC]) \ No newline at end of file

Return to:

Send suggestions and report system problems to the System administrator.