diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-11 21:48:14 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-11 21:48:14 +0300 |
commit | f8323650568b0031f0ec4c50cde417cb10a48c56 (patch) | |
tree | b0007c30366860dc079a7bf8828d254b7486630f /mfd/drivers.c | |
parent | ffd2cf189d926abe00de0a79f292f1ea69d02aac (diff) | |
download | mailfromd-f8323650568b0031f0ec4c50cde417cb10a48c56.tar.gz mailfromd-f8323650568b0031f0ec4c50cde417cb10a48c56.tar.bz2 |
Implement functional notation for reply actions
* NEWS, doc/mailfromd.texi: Update.
* mfd/drivers.c (print_type_result, mark_type_result)
(optimize_type_result, code_type_result): Rewrite.
* mfd/gram.y: Rewrite action rules.
* mfd/lex.l (CODE,XCODE): Remove.
* mfd/opcodes (RESULT): Takes one immediate parameter.
(instr_result): Get arguments from stack.
Diffstat (limited to 'mfd/drivers.c')
-rw-r--r-- | mfd/drivers.c | 113 |
1 files changed, 78 insertions, 35 deletions
diff --git a/mfd/drivers.c b/mfd/drivers.c index d8dfb4b2..ed8a288a 100644 --- a/mfd/drivers.c +++ b/mfd/drivers.c @@ -890,27 +890,26 @@ void print_type_result(NODE *node, int level) { - if (node->v.ret.code) { - const char *s = NULL; - int expr = 0; + NODE *code, *xcode; + + code = node->v.ret.code; + xcode = node->v.ret.xcode; print_level(level); - if (node->v.ret.message) { - if (node->v.ret.message->type == node_type_string) - s = node->v.ret.message->v.literal->text; - else { - expr = 1; - s = "(expression)"; - } - } - dbg_setreply(NULL, - (char*) LITERAL_TEXT(node->v.ret.code), - (char*) LITERAL_TEXT(node->v.ret.xcode), - (char*) s); - if (expr) - print_node(node->v.ret.message, level+1); - } - print_level(level); + printf("SET REPLY "); print_stat(node->v.ret.stat); printf("\n"); + print_level(level); + printf("CODE:\n"); + if (code) + print_node(code, level+1); + print_level(level); + printf("XCODE:\n"); + if (xcode) + print_node(xcode, level+1); + print_level(level); + printf("MESSAGE:\n"); + if (node->v.ret.message) + print_node(node->v.ret.message, level+1); + printf("\n"); } @@ -918,8 +917,6 @@ void mark_type_result(NODE *node) { - if (node->v.ret.code) - node->v.ret.code->flags |= VAR_REFERENCED; - if (node->v.ret.xcode) - node->v.ret.xcode->flags |= VAR_REFERENCED; + mark(node->v.ret.code); + mark(node->v.ret.xcode); mark(node->v.ret.message); } @@ -928,22 +925,70 @@ void optimize_type_result(NODE *node) { + optimize(node->v.ret.code); + optimize(node->v.ret.xcode); optimize(node->v.ret.message); } -void -code_type_result(NODE *node, struct locus **old_locus) +static void +code_result_arg(NODE *node) { - MARK_LOCUS(); - if (node->v.ret.message) - code_node(node->v.ret.message); + if (node) + code_node(node); else { code_op(opcode_push); code_immediate(NULL); } +} + +static NODE * +result_argptr(NODE *arg) +{ + if (arg && arg->type == node_type_string + && arg->v.literal->text[0] == 0) + arg = NULL; + return arg; +} + +void +code_type_result(NODE *node, struct locus **old_locus) +{ + NODE *code, *xcode; + + code = result_argptr(node->v.ret.code); + xcode = result_argptr(node->v.ret.xcode); + + switch (node->v.ret.stat) { + case SMFIS_REJECT: + if (code && code->type == node_type_string + && code->v.literal->text[0] != '5') + parse_error_locus(&node->locus, + _("Reject code should be 5xx")); + if (xcode && xcode->type == node_type_string + && xcode->v.literal->text[0] != '5') + parse_error_locus(&node->locus, + _("Reject extended code should be 5.x.x")); + break; + + case SMFIS_TEMPFAIL: + if (code && code->type == node_type_string + && code->v.literal->text[0] != '4') + parse_error_locus(&node->locus, + _("Tempfail code should be 4xx")); + if (xcode && xcode->type == node_type_string + && xcode->v.literal->text[0] != '4') + parse_error_locus(&node->locus, + _("Tempfail extended code should be 4.x.x")); + break; + default: + break; + } + + code_result_arg(node->v.ret.message); + code_result_arg(xcode); + code_result_arg(code); + MARK_LOCUS(); code_op(opcode_result); code_immediate((void*)node->v.ret.stat); - code_immediate((void*)LITERAL_OFF(node->v.ret.code)); - code_immediate((void*)LITERAL_OFF(node->v.ret.xcode)); code_op(opcode_nil); } @@ -1483,11 +1528,9 @@ code_type_catch(NODE *node, struct locus **old_locus) jump_pc = code_immediate((void*)jump_pc); } else { - code_op(opcode_push); - code_immediate(NULL); + code_result_arg(NULL); + code_result_arg(NULL); + code_result_arg(NULL); code_op(opcode_result); code_immediate(SMFIS_CONTINUE); - code_immediate(NULL); - code_immediate(NULL); - code_immediate(NULL); } |