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/gram.y | |
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/gram.y')
-rw-r--r-- | mfd/gram.y | 131 |
1 files changed, 92 insertions, 39 deletions
@@ -299,7 +299,7 @@ _create_alias(void *item, void *data) %} %error-verbose -%expect 29 +%expect 28 %union { struct literal *literal; @@ -360,7 +360,7 @@ _create_alias(void *item, void *data) %token <locus> WHEN PASS SET CATCH THROW KW_ECHO RETURNS RETURN FUNC %token <locus> SWITCH CASE DEFAULT CONST %token <locus> FOR LOOP WHILE BREAK NEXT ARGCOUNT ALIAS DOTS ARGX VAPTR -%token <literal> STRING CODE XCODE +%token <literal> STRING %token <literal> SYMBOL IDENTIFIER %token <number> ARG NUMBER BACKREF %token <builtin> BUILTIN BUILTIN_PROC BUILTIN_P @@ -386,7 +386,8 @@ _create_alias(void *item, void *data) %type <node> decl stmt condition action sendmail_action header_action if_cond else_cond on_cond atom argref paren_argref - funcall proccall expr common_expr simp_expr atom_expr + funcall proccall expr maybe_expr maybe_xcode_expr + common_expr simp_expr atom_expr asgn catch throw return case_cond autodcl constdecl loopstmt opt_while jumpstmt %type <stmtlist> stmtlist decllist @@ -394,10 +395,9 @@ _create_alias(void *item, void *data) %type <poll> pollstmt pollarglist %type <pollarg> pollarg loop_parm %type <loop> opt_loop_parms loop_parm_list -%type <number> number %type <arglist> arglist %type <var> variable -%type <literal> string opt_ident loop_ident alias +%type <literal> string opt_ident loop_ident alias code xcode %type <state> state_ident %type <matchtype> matches fnmatches %type <type> retdecl @@ -892,24 +892,32 @@ sendmail_action: } | ACT_REJECT maybe_triplet { - if ($2.code && $2.code->text[0] != '5') - parse_error(_("Reject code should be 5xx")); - if ($2.xcode && $2.xcode->text[0] != '5') - parse_error(_("Reject extended code should be 5.x.x")); $$ = alloc_node(node_type_result, &$1); $$->v.ret = $2; $$->v.ret.stat = SMFIS_REJECT; } + | ACT_REJECT '(' maybe_expr ',' maybe_xcode_expr ',' maybe_expr ')' + { + $$ = alloc_node(node_type_result, &$1); + $$->v.ret.stat = SMFIS_REJECT; + $$->v.ret.code = $3 ? cast_to(dtype_string, $3) : NULL; + $$->v.ret.xcode = $5 ? cast_to(dtype_string, $5) : NULL; + $$->v.ret.message = $7 ? cast_to(dtype_string, $7) : NULL; + } | ACT_TEMPFAIL maybe_triplet { - if ($2.code && $2.code->text[0] != '4') - parse_error(_("Tempfail code should be 4xx")); - if ($2.xcode && $2.xcode->text[0] != '4') - parse_error(_("Tempfail extended code should be 4.x.x")); $$ = alloc_node(node_type_result, &$1); $$->v.ret = $2; $$->v.ret.stat = SMFIS_TEMPFAIL; } + | ACT_TEMPFAIL '(' maybe_expr ',' maybe_xcode_expr ',' maybe_expr ')' + { + $$ = alloc_node(node_type_result, &$1); + $$->v.ret.stat = SMFIS_TEMPFAIL; + $$->v.ret.code = $3 ? cast_to(dtype_string, $3) : NULL; + $$->v.ret.xcode = $5 ? cast_to(dtype_string, $5) : NULL; + $$->v.ret.message = $7 ? cast_to(dtype_string, $7) : NULL; + } | ACT_CONTINUE { $$ = alloc_node(node_type_result, &$1); @@ -924,6 +932,15 @@ sendmail_action: } ; +maybe_xcode_expr: maybe_expr + | xcode + { + $$ = alloc_node(node_type_string, get_locus()); + $$->v.literal = $1; + } + ; + + header_action: ADD string expr { @@ -955,32 +972,74 @@ maybe_triplet: /* empty */ | triplet ; -triplet : CODE +triplet : code { - $$.code = $1; + $$.code = alloc_node(node_type_string, get_locus()); + $$.code->v.literal = $1; $$.xcode = NULL; $$.message = NULL; } - | CODE XCODE + | code xcode { - $$.code = $1; - $$.xcode = $2; + $$.code = alloc_node(node_type_string, get_locus()); + $$.code->v.literal = $1; + $$.xcode = alloc_node(node_type_string, get_locus()); + $$.xcode->v.literal = $2; $$.message = NULL; } - | CODE XCODE expr + | code xcode expr { - $$.code = $1; - $$.xcode = $2; + $$.code = alloc_node(node_type_string, get_locus()); + $$.code->v.literal = $1; + $$.xcode = alloc_node(node_type_string, get_locus()); + $$.xcode->v.literal = $2; $$.message = cast_to(dtype_string, $3); } - | CODE expr + | code expr { - $$.code = $1; + $$.code = alloc_node(node_type_string, get_locus()); + $$.code->v.literal = $1; $$.xcode = NULL; $$.message = cast_to(dtype_string, $2); } ; +code : NUMBER + { + char buf[4]; + + if ($1 < 200 || $1 > 599) { + yyerror(_("Invalid SMTP reply code")); + buf[0] = 0; + } else + snprintf(buf, sizeof(buf), "%lu", $1); + $$ = string_alloc(buf, strlen(buf)); + } + ; + +xcode : NUMBER '.' NUMBER '.' NUMBER + { + char buf[sizeof("5.999.999")]; + + /* RFC 1893: + The syntax of the new status codes is defined as: + + status-code = class "." subject "." detail + class = "2"/"4"/"5" + subject = 1*3digit + detail = 1*3digit + */ + if (($1 != 2 && $1 != 4 && $1 !=5) + || $3 > 999 || $5 > 999) { + yyerror(_("Invalid extended reply code")); + buf[0] = 0; + } else + snprintf(buf, sizeof(buf), "%lu.%lu.%lu", + $1, $3, $5); + $$ = string_alloc(buf, strlen(buf)); + } + ; + condition : if_cond | case_cond | on_cond @@ -1121,7 +1180,7 @@ value : STRING $$.v.literal = $1; } } - | number + | NUMBER { $$.type = dtype_number; $$.v.number = $1; @@ -1164,19 +1223,6 @@ fnmatches : FNMATCHES } ; -number : NUMBER - | CODE - { - char *p; - $$ = strtol($1->text, &p, 10); - if (*p) { - /* should not happen */ - parse_error(_("Invalid number (near `%s')"), p); - YYERROR; - } - } - ; - /* Loop statements */ @@ -1402,6 +1448,13 @@ expr : NOT expr | common_expr ; +maybe_expr : /* empty */ + { + $$ = NULL; + } + | expr + ; + common_expr: simp_expr | common_expr simp_expr %prec CONCAT { @@ -1950,13 +2003,13 @@ on_cond : on pollstmt do branches DONE on : ON { - onblock(1); + tie_in_onblock(1); } ; do : DO { - onblock(0); + tie_in_onblock(0); } ; |