aboutsummaryrefslogtreecommitdiff
path: root/mfd/gram.y
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-05-11 21:48:14 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-05-11 21:48:14 +0300
commitf8323650568b0031f0ec4c50cde417cb10a48c56 (patch)
treeb0007c30366860dc079a7bf8828d254b7486630f /mfd/gram.y
parentffd2cf189d926abe00de0a79f292f1ea69d02aac (diff)
downloadmailfromd-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.y131
1 files changed, 92 insertions, 39 deletions
diff --git a/mfd/gram.y b/mfd/gram.y
index 332a748a..15ee9602 100644
--- a/mfd/gram.y
+++ b/mfd/gram.y
@@ -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);
}
;

Return to:

Send suggestions and report system problems to the System administrator.