diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-03 15:47:06 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-03 15:47:06 +0300 |
commit | 1026a8cc51d8c72a2237ce06467fd84fe3c303f9 (patch) | |
tree | 4b8b122a8387ae048fc5a778f4eb3c940b579a2b | |
parent | ec9b2d3c5dd6c6ea9d3569c358746d00c053d03a (diff) | |
download | mailfromd-1026a8cc51d8c72a2237ce06467fd84fe3c303f9.tar.gz mailfromd-1026a8cc51d8c72a2237ce06467fd84fe3c303f9.tar.bz2 |
Implement explicit concatenation operator (.)
* mfd/drivers.c (type strcat): A synonym for concat, used
for implicit string concatenation.
* mfd/gram.y: Expect 53 shift/reduces.
(alloc_node, cast_to): extern
(T_COMPOSE): New token.
(concat_expr): New %type.
(concat_expr): New rule.
(node_type): handle node_type_strcat.
(create_node_variable, create_node_argcount)
(create_node_arg, create_node_symbol)
(create_node_backref): New functions.
* mfd/lex.l: Rewrite string handling. Strings with
variable and/or constant substitutions within them are
handled in one run and a corresponding NODE* is composed
out of them. That node is then returned as T_COMPOSE
token.
* mfd/prog.h (alloc_node, cast_to)
(create_node_variable, create_node_argcount)
(create_node_arg, create_node_symbol)
(create_node_backref): New protos.
* mflib/sa.mf, mflib/spf.mf, tests/alias.at,
tests/curmsg.at, tests/etc/ack.rc, tests/etc/catch.rc,
tests/etc/catch01.rc, tests/etc/public.mf,
tests/hdr-all.at, tests/hdr-cap.at, tests/hdr-count.at,
tests/hdr-get.at, tests/hdr-gete.at, tests/hdr-getn.at,
tests/hdr-itr.at, tests/hdr-mul.at, tests/macros.at,
tests/next01.at, tests/next02.at, tests/prec.at,
tests/public.at, tests/shadow.at,
tests/static01.at: Use explicit concatenation.
* tests/prec01.at: New testcase.
* tests/Makefile.am, tests/testsuite.at: Add prec01.at
-rw-r--r-- | mfd/drivers.c | 26 | ||||
-rw-r--r-- | mfd/gram.y | 144 | ||||
-rw-r--r-- | mfd/lex.l | 255 | ||||
-rw-r--r-- | mfd/prog.h | 8 | ||||
-rw-r--r-- | mflib/sa.mf | 10 | ||||
-rw-r--r-- | mflib/spf.mf | 12 | ||||
-rw-r--r-- | mflib/strip_domain_part.mf | 2 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/alias.at | 4 | ||||
-rw-r--r-- | tests/curmsg.at | 2 | ||||
-rw-r--r-- | tests/etc/ack.rc | 2 | ||||
-rw-r--r-- | tests/etc/catch.rc | 2 | ||||
-rw-r--r-- | tests/etc/catch01.rc | 2 | ||||
-rw-r--r-- | tests/etc/public.mf | 2 | ||||
-rw-r--r-- | tests/hdr-all.at | 2 | ||||
-rw-r--r-- | tests/hdr-cap.at | 6 | ||||
-rw-r--r-- | tests/hdr-count.at | 2 | ||||
-rw-r--r-- | tests/hdr-get.at | 4 | ||||
-rw-r--r-- | tests/hdr-gete.at | 2 | ||||
-rw-r--r-- | tests/hdr-getn.at | 6 | ||||
-rw-r--r-- | tests/hdr-itr.at | 2 | ||||
-rw-r--r-- | tests/hdr-mul.at | 6 | ||||
-rw-r--r-- | tests/macros.at | 2 | ||||
-rw-r--r-- | tests/next01.at | 2 | ||||
-rw-r--r-- | tests/next02.at | 2 | ||||
-rw-r--r-- | tests/prec.at | 10 | ||||
-rw-r--r-- | tests/public.at | 4 | ||||
-rw-r--r-- | tests/shadow.at | 2 | ||||
-rw-r--r-- | tests/static01.at | 4 | ||||
-rw-r--r-- | tests/testsuite.at | 1 |
30 files changed, 384 insertions, 145 deletions
diff --git a/mfd/drivers.c b/mfd/drivers.c index 5dc594b1..fbd8a88c 100644 --- a/mfd/drivers.c +++ b/mfd/drivers.c @@ -1165,6 +1165,32 @@ code_type_concat(NODE *node, struct locus **old_locus) code_node(node->v.concat.arg[1]); code_op(opcode_concat); } + +/* type strcat */ + +void +print_type_strcat(NODE *node, int level) +{ + print_type_concat(node, level); +} + +void +mark_type_strcat(NODE *node) +{ + mark_type_concat(node); +} + +void +optimize_type_strcat(NODE *node) +{ + optimize_type_concat(node); +} + +void +code_type_strcat(NODE *node, struct locus **old_locus) +{ + code_type_concat(node, old_locus); +} /* type variable */ @@ -27,7 +27,6 @@ #include "prog.h" #include "optab.h" -static NODE *alloc_node(enum node_type type, const struct locus *locus); static void free_node(NODE *node); static void set_poll_arg(struct poll_data *poll, int kw, NODE *expr); static int codegen(prog_counter_t *pc, NODE *node, unsigned exmask, @@ -43,7 +42,6 @@ static NODE *function_call(struct function *function, size_t count, static NODE *declare_function(struct function *func, struct locus *loc, size_t nautos); static data_type_t node_type(NODE *node); -static NODE *cast_to(data_type_t type, NODE *node); static NODE *cast_arg_list(NODE *args, size_t parmc, data_type_t *parmtype, int disable_prom); static void add_xref(struct variable *var, const struct locus *locus); @@ -288,7 +286,7 @@ _create_alias(void *item, void *data) %} %error-verbose -%expect 28 +%expect 53 %union { struct literal *literal; @@ -409,6 +407,7 @@ _create_alias(void *item, void *data) T_PUBLIC "public" T_MODULE "module" T_BYE "bye" +%token <node> T_COMPOSE "composed string" %token T_MODBEG T_MODEND %token <literal> T_STRING "string" %token <literal> T_SYMBOL "MTA macro" T_IDENTIFIER "identifier" @@ -420,7 +419,7 @@ _create_alias(void *item, void *data) %token <string> T_SHARPREQR %token T_BOGUS -%left T_CONCAT +%left '.' %left T_OR %left T_AND %left T_NOT @@ -437,7 +436,7 @@ _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 maybe_expr maybe_xcode_expr - common_expr simp_expr atom_expr + common_expr concat_expr simp_expr atom_expr asgn catch throw return case_cond autodcl constdecl loopstmt opt_while jumpstmt %type <stmtlist> program stmtlist decllist modcntl @@ -1676,11 +1675,29 @@ maybe_expr : /* empty */ | expr ; -common_expr: simp_expr - | common_expr simp_expr %prec T_CONCAT +common_expr: concat_expr + | common_expr '.' concat_expr { $$ = alloc_node(node_type_concat, get_locus()); $$->v.concat.arg[0] = cast_to(dtype_string, $1); + $$->v.concat.arg[1] = cast_to(dtype_string, $3); + } + ; + +concat_expr: simp_expr + | concat_expr simp_expr + { + if (($1->type == node_type_string + || $1->type == node_type_strcat) + && ($2->type == node_type_string + || $2->type == node_type_strcat)) + $$ = alloc_node(node_type_strcat, get_locus()); + else { + deprecation_warning(_("implicit concatenation is deprecated")); + deprecation_warning(_("use `.' operator")); + $$ = alloc_node(node_type_concat, get_locus()); + } + $$->v.concat.arg[0] = cast_to(dtype_string, $1); $$->v.concat.arg[1] = cast_to(dtype_string, $2); } ; @@ -1692,7 +1709,15 @@ simp_expr : atom_expr $$->v.bin.opcode = bin_add; $$->v.bin.arg[0] = cast_to(dtype_number, $1); $$->v.bin.arg[1] = cast_to(dtype_number, $3); - } + } +/* + | simp_expr '.' simp_expr + { + $$ = alloc_node(node_type_concat, get_locus()); + $$->v.concat.arg[0] = cast_to(dtype_string, $1); + $$->v.concat.arg[1] = cast_to(dtype_string, $3); + } +*/ | simp_expr '-' simp_expr { $$ = alloc_node(node_type_bin, get_locus()); @@ -1763,9 +1788,7 @@ atom_expr : funcall atom : T_SYMBOL { - register_macro(state_tag, $1->text); - $$ = alloc_node(node_type_symbol, get_locus()); - $$->v.literal = $1; + $$ = create_node_symbol($1, get_locus()); } | value { @@ -1786,25 +1809,12 @@ atom : T_SYMBOL } | T_BACKREF { - $$ = alloc_node(node_type_backref, get_locus()); - $$->v.number = $1; + $$ = create_node_backref($1, get_locus()); } | argref | T_ARGCOUNT { - if (outer_context == context_function) { - if (func->optcount || func->varargs) { - $$ = alloc_node(node_type_arg, &$1); - $$->v.arg.data_type = dtype_number; - $$->v.arg.number = 1; - } else { - $$ = alloc_node(node_type_number, &$1); - $$->v.number = parminfo[outer_context].parmcount(); - } - } else { - $$ = alloc_node(node_type_number, &$1); - $$->v.number = parminfo[outer_context].parmcount(); - } + $$ = create_node_argcount(&$1); } | '@' T_IDENTIFIER { @@ -1823,26 +1833,16 @@ atom : T_SYMBOL $$ = alloc_node(node_type_vaptr, get_locus()); $$->v.node = $2; } + | T_COMPOSE ; argref : variable { - $$ = alloc_node(node_type_variable, get_locus()); - $$->v.var_ref.variable = $1; - $$->v.var_ref.nframes = catch_nesting; + $$ = create_node_variable($1, get_locus()); } | T_ARG { - if (inner_context == context_function - && func->varargs) - ; - else if ($1 > PARMCOUNT()) - parse_error(_("argument number too high")); - $$ = alloc_node(node_type_arg, get_locus()); - $$->v.arg.data_type = PARMTYPE($1); - $$->v.arg.number = $1; - if (inner_context == context_function) - $$->v.arg.number += FUNC_HIDDEN_ARGS(func); + $$ = create_node_arg($1, get_locus()); } | T_ARGX '(' expr ')' { @@ -3838,6 +3838,7 @@ node_type(NODE *node) return node->v.builtin.builtin->rettype; case node_type_concat: + case node_type_strcat: return dtype_string; case node_type_variable: @@ -4521,3 +4522,68 @@ declare_function(struct function *func, struct locus *loc, size_t nautos) return node; } + +NODE * +create_node_variable(struct variable *var, const struct locus *locus) +{ + NODE *node = alloc_node(node_type_variable, locus); + node->v.var_ref.variable = var; + node->v.var_ref.nframes = catch_nesting; + return node; +} + +NODE * +create_node_argcount(const struct locus *locus) +{ + NODE *node; + + if (outer_context == context_function) { + if (func->optcount || func->varargs) { + node = alloc_node(node_type_arg, locus); + node->v.arg.data_type = dtype_number; + node->v.arg.number = 1; + } else { + node = alloc_node(node_type_number, locus); + node->v.number = parminfo[outer_context].parmcount(); + } + } else { + node = alloc_node(node_type_number, locus); + node->v.number = parminfo[outer_context].parmcount(); + } + return node; +} + +NODE * +create_node_arg(long num, const struct locus *locus) +{ + NODE *node; + + if (inner_context == context_function && func->varargs) + ; + else if (num > PARMCOUNT()) + parse_error(_("argument number too high")); + node = alloc_node(node_type_arg, locus); + node->v.arg.data_type = PARMTYPE(num); + node->v.arg.number = num; + if (inner_context == context_function) + node->v.arg.number += FUNC_HIDDEN_ARGS(func); + return node; +} + +NODE * +create_node_symbol(struct literal *lit, const struct locus *locus) +{ + NODE *node; + register_macro(state_tag, lit->text); + node = alloc_node(node_type_symbol, locus); + node->v.literal = lit; + return node; +} + +NODE * +create_node_backref(long num, const struct locus *locus) +{ + NODE *node = alloc_node(node_type_backref, locus); + node->v.number = num; + return node; +} @@ -297,6 +297,114 @@ advance_line() /* Redeclare main entry point. Actual yylex is defined in the code section below. */ #define YY_DECL static int lexscan(void) + + +/* String composer */ +static NODE *string_head, *string_tail; + +static void +compose_add_node(NODE *node) +{ + if (string_tail) + string_tail->next = node; + else + string_head = node; + string_tail = node; +} + +static void +compose_start(int state) +{ + if (string_head) { + parse_error("INTERNAL ERROR: previous composition has not " + "finished when a new one started"); + abort(); + } + BEGIN_X(state); +} + +static int +compose_finish() +{ + if (string_tail != string_head) { + while (string_head->next) { + NODE *cat = alloc_node(node_type_strcat, + &string_head->locus); + NODE *next = string_head->next; + cat->next = next->next; + cat->v.concat.arg[0] = cast_to(dtype_string, + string_head); + cat->v.concat.arg[1] = cast_to(dtype_string, next); + string_head->next = next->next = NULL; + string_head = cat; + } + } + yylval.node = string_head; + string_head = string_tail = NULL; + return T_COMPOSE; +} + +static void +compose_add_literal(struct literal *lit) +{ + NODE *node = alloc_node(node_type_string, &locus); + node->v.literal = lit; + compose_add_node(node); + if (yy_flex_debug) + fprintf(stderr, "--add literal: '%s'\n", lit->text); +} + +static void +compose_add_string(const char *text, size_t length) +{ + compose_add_literal(string_alloc(text, length)); +} + +static void +compose_add_number(long num) +{ + NODE *node = alloc_node(node_type_number, &locus); + node->v.number = num; + compose_add_node(node); +} + +void +compose_add_builtin_const(const char *s, size_t len) +{ + const char *sval; + long nval; + + switch (builtin_const_value(s, len, &sval, &nval)) { + case dtype_number: + compose_add_number(nval); + break; + + case dtype_string: + compose_add_string(sval, strlen(sval)); + break; + + default: + abort(); + } +} + +void +compose_add_variable_or_const(int what) +{ + switch (what) { + case T_NUMBER: + compose_add_number(yylval.number); + break; + + case T_STRING: + compose_add_literal(yylval.literal); + break; + + case T_VARIABLE: + compose_add_node(create_node_variable(yylval.var, &locus)); + } +} + %} /* Exclusive states: @@ -453,31 +561,50 @@ bye return keyword(T_BYE); <ONBLOCK>host return keyword(T_HOST); <ONBLOCK>as return keyword(T_AS); /* Variables */ -<INITIAL,ONBLOCK,ML,CML,STR>\%({ICONST}) { +<INITIAL,ONBLOCK>\%({ICONST}) { return builtin_const(yytext + 1, yyleng - 1); } -<INITIAL,ONBLOCK,ML,CML,STR>\%\{({ICONST})\} { +<ML,CML,STR>\%({ICONST}) { + compose_add_builtin_const(yytext + 1, yyleng - 1); +} +<INITIAL,ONBLOCK>\%\{({ICONST})\} { return builtin_const(yytext + 2, yyleng - 3); } -<INITIAL,ONBLOCK,ML,CML,STR>\%{IDENT} { +<ML,CML,STR>\%\{({ICONST})\} { + compose_add_builtin_const(yytext + 2, yyleng - 3); +} +<INITIAL,ONBLOCK>\%{IDENT} { string(yytext + 1, yyleng - 1); return variable_or_const(); } -<INITIAL,ONBLOCK,ML,CML,STR>\%\{{IDENT}\} { +<ML,CML,STR>\%{IDENT} { + string(yytext + 1, yyleng - 1); + compose_add_variable_or_const(variable_or_const()); +} +<INITIAL,ONBLOCK>\%\{{IDENT}\} { string(yytext + 2, yyleng - 3); return variable_or_const(); } - +<ML,CML,STR>\%\{{IDENT}\} { + string(yytext + 2, yyleng - 3); + compose_add_variable_or_const(variable_or_const()); +} /* Positional arguments */ -<INITIAL,ONBLOCK,ML,CML,STR>\$# { +<INITIAL,ONBLOCK>\$# { return T_ARGCOUNT; } -<INITIAL,ONBLOCK,ML,CML,STR>\${P} { +<ML,CML,STR>\$# { + compose_add_node(create_node_argcount(&locus)); +} +<INITIAL,ONBLOCK>\${P} { yylval.number = strtol(yytext + 1, NULL, 0); return T_ARG; } +<ML,CML,STR>\${P} { + compose_add_node(create_node_arg(strtol(yytext + 1, NULL, 0), &locus)); + } <INITIAL,ONBLOCK>\$/"(" { return keyword(T_ARGX); } /* Sendmail variables */ -<INITIAL,ONBLOCK,ML,CML,STR>\${IDENT} { +<INITIAL,ONBLOCK>\${IDENT} { if (yyleng == 2) string(yytext + 1, 1); else { @@ -489,17 +616,35 @@ bye return keyword(T_BYE); } return T_SYMBOL; } -<INITIAL,ONBLOCK,ML,CML,STR>\$\{{IDENT}\} { +<ML,CML,STR>\${IDENT} { + if (yyleng == 2) + string(yytext + 1, 1); + else { + line_begin(); + line_add("{", 1); + line_add(yytext + 1, yyleng - 1); + line_add("}", 1); + line_finish(); + } + compose_add_node(create_node_symbol(yylval.literal, &locus)); + } +<INITIAL,ONBLOCK>\$\{{IDENT}\} { string(yytext+1, yyleng - 1); return T_SYMBOL; } +<ML,CML,STR>\$\{{IDENT}\} { + string(yytext+1, yyleng - 1); + compose_add_node(create_node_symbol(yylval.literal, &locus)); } /* Back-references */ -<INITIAL,ONBLOCK,ML,CML,STR>\\{P} { +<INITIAL,ONBLOCK>\\{P} { yylval.number = strtoul(yytext+1, NULL, 0); return T_BACKREF; } +<ML,CML,STR>\\{P} { + compose_add_node(create_node_backref(strtoul(yytext+1, NULL, 10), + &locus)); } /* Numeric strings */ 0[xX]{X}{X}* { yylval.number = strtoul(yytext, NULL, 16); return T_NUMBER; }; 0{O}{O}* { yylval.number = strtoul(yytext, NULL, 8); return T_NUMBER; }; 0|{P} { yylval.number = strtoul(yytext, NULL, 10); return T_NUMBER; }; - /* Strings */ + /* Identifiers */ {IDENT} { int paren_follows = 0; enum { is_ident, is_builtin, is_func } state; @@ -535,83 +680,74 @@ bye return keyword(T_BYE); return T_IDENTIFIER; } } + /* Strings */ '[^\n']*' { string(yytext+1, yyleng-2); return T_STRING; } \"[^\\\"$%\n]*\" { string(yytext+1, yyleng-2); return T_STRING; } \"[^\\\"$%\n]*\\\n { advance_line(); - BEGIN_X(STR); - line_begin(); - line_add(yytext + 1, yyleng - 3); } -\"[^\\\"$%\n]*/[\\$%] { BEGIN_X(STR); - string(yytext+1, yyleng-1); - line_begin(); - return T_STRING; } + compose_start(STR); + compose_add_string(yytext + 1, yyleng - 3); } +\"[^\\\"$%\n]*/[\\$%] { compose_start(STR); + compose_add_string(yytext+1, yyleng-1); } \"\\x{X}{X}/[\\$%] { - BEGIN_X(STR); + compose_start(STR); line_add_char(strtoul(yytext + 3, NULL, 16)); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); } \"\\x{X}{X} { - BEGIN_X(STR); + compose_start(STR); line_add_char(strtoul(yytext + 3, NULL, 16)); } \"\\0{O}{1,3}/[\\$%] { - BEGIN_X(STR); + compose_start(STR); line_add_char(strtoul(yytext + 3, NULL, 8)); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); } \"\\0{O}{1,3} { - BEGIN_X(STR); + compose_start(STR); line_add_char(strtoul(yytext + 3, NULL, 8)); } \"\\[^1-9]/[\\$%] { - BEGIN_X(STR); + compose_start(STR); line_add_char(mu_argcv_unquote_char(yytext[2])); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); } \"\\[^1-9] { - BEGIN_X(STR); + compose_start(STR); line_add_char(mu_argcv_unquote_char(yytext[2])); } <STR>[^\\\"$%\n]*\\\n { advance_line(); line_add(yytext, yyleng - 2); } <STR>[^\\\"$%\n]*\" { BEGIN(INITIAL); - if (yyleng > 1) - line_add(yytext, yyleng - 1); - line_finish(); - return T_STRING; } + if (yyleng > 1) + line_add(yytext, yyleng - 1); + compose_add_literal(string_finish()); + return compose_finish(); } <STR>[^\\\"$%\n]+/[\\$%] { line_add(yytext, yyleng); - line_finish(); + compose_add_literal(string_finish()); line_begin(); - return T_STRING; } <STR,ML,CML>\\x{X}{X}/[\\$%] { line_add_char(strtoul(yytext + 2, NULL, 16)); - line_finish(); + compose_add_literal(string_finish()); line_begin(); - return T_STRING; } <STR,ML,CML>\\x{X}{X} { line_add_char(strtoul(yytext + 2, NULL, 16)); } <STR,ML,CML>\\0{O}{1,3}/[\\$%] { line_add_char(strtoul(yytext + 2, NULL, 8)); - line_finish(); + compose_add_literal(string_finish()); line_begin(); - return T_STRING; } <STR,ML,CML>\\0{O}{1,3} { line_add_char(strtoul(yytext + 2, NULL, 8)); } <STR,ML,CML>\\[^1-9]/[\\$%] { line_add_char(mu_argcv_unquote_char(yytext[1])); - line_finish(); + compose_add_literal(string_finish()); line_begin(); - return T_STRING; } <STR,ML,CML>\\[^1-9] { line_add_char(mu_argcv_unquote_char(yytext[1])); @@ -655,9 +791,9 @@ bye return keyword(T_BYE); memcpy(multiline_delimiter, p, multiline_delimiter_len); multiline_delimiter[multiline_delimiter_len] = 0; if (multiline_unescape) - BEGIN_X(ML); + compose_start(ML); else - BEGIN_X(QML); + compose_start(QML); } /* Quoted multilines */ <QML>[^\\\n]*\n { @@ -676,8 +812,8 @@ bye return keyword(T_BYE); multiline_delimiter = NULL; multiline_delimiter_len = 0; BEGIN(INITIAL); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); + return compose_finish(); } line_add(p, strlen(p)); } @@ -689,20 +825,18 @@ bye return keyword(T_BYE); for (; char_to_strip (*p); p++) ; line_add(p, strlen(p)); - line_finish(); - BEGIN(CML); - return T_STRING; + compose_add_literal(string_finish()); + BEGIN_X(CML); } <CML>[^\\$%\n]+/[\\$%] { line_add(yytext, yyleng); - line_finish(); + compose_add_literal(string_finish()); line_begin(); - return T_STRING; } <CML,STR>"%%"|"$$" { line_add(yytext, 1); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); + line_begin(); } <ML,CML,STR>[$%] { line_add(yytext, yyleng); @@ -723,12 +857,11 @@ bye return keyword(T_BYE); multiline_delimiter = NULL; multiline_delimiter_len = 0; BEGIN(INITIAL); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); + return compose_finish(); } line_add(p, strlen(p)); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); } <ML>[^\\$%\n]*\n { char *p; @@ -746,8 +879,8 @@ bye return keyword(T_BYE); multiline_delimiter = NULL; multiline_delimiter_len = 0; BEGIN(INITIAL); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); + return compose_finish(); } line_add(p, strlen(p)); } @@ -761,8 +894,8 @@ bye return keyword(T_BYE); multiline_delimiter = NULL; multiline_delimiter_len = 0; BEGIN(INITIAL); - line_finish(); - return T_STRING; + compose_add_literal(string_finish()); + return compose_finish(); } line_add(yytext, yyleng); BEGIN_X(ML); @@ -72,6 +72,14 @@ void enter_loop(struct literal *lit, prog_counter_t *begptr, prog_counter_t *endptr); void leave_loop(void); +NODE *alloc_node(enum node_type type, const struct locus *locus); +NODE *create_node_variable(struct variable *var, const struct locus *locus); +NODE *create_node_argcount(const struct locus *locus); +NODE *create_node_arg(long num, const struct locus *locus); +NODE *create_node_symbol(struct literal *lit, const struct locus *loc); +NODE *create_node_backref(long num, const struct locus *locus); +NODE *cast_to(data_type_t type, NODE *node); + extern instr_t *prog; extern unsigned error_count; extern unsigned long prog_trace_option; diff --git a/mflib/sa.mf b/mflib/sa.mf index 89fb850f..7e5266b5 100644 --- a/mflib/sa.mf +++ b/mflib/sa.mf @@ -23,10 +23,10 @@ static func __sa_format_score0(string code, number prec) do number len length(%code) if %len > %prec - return substring(%code, 0, %len - %prec-1) '.' + return substring(%code, 0, %len - %prec-1) . '.' . substring(%code, %len - %prec, -1) else - return "0." replstr("0", %prec - %len) %code + return "0." . replstr("0", %prec - %len) . %code fi done @@ -40,7 +40,7 @@ func sa_format_score(number code, number prec) returns string do if %code < 0 - return "-" __sa_format_score0(- %code, %prec) + return "-" . __sa_format_score0(- %code, %prec) else return __sa_format_score0(%code, %prec) fi @@ -80,10 +80,10 @@ do fi number n index(%text, "\n", %i) if %n >= 0 - set ret %ret %pfx substring(%text, %i, %n) + set ret %ret . %pfx . substring(%text, %i, %n) set i %n + 1 else - set ret %ret %pfx substr(%text, %i) + set ret %ret . %pfx . substr(%text, %i) break fi done diff --git a/mflib/spf.mf b/mflib/spf.mf index be6343bf..889d09da 100644 --- a/mflib/spf.mf +++ b/mflib/spf.mf @@ -42,7 +42,7 @@ do case TempError: return "TempError" case PermError: return "PermError" done - return "UNKNOWN (" %code ")" + return "UNKNOWN (%code)" done static func __spf_get_cache(string ip, string domain, string sender) @@ -76,22 +76,22 @@ static func __spf_put_cache(number result, string ip, string domain, string sender) do safedbput(%spf_database, "%ip-%domain-%sender", - (time() + %spf_ttl) + (time() + %spf_ttl) . " %result <%spf_mechanism> <%spf_explanation>") done static func __spf_log(number result, string ip, string domain, string sender) do - string logmsg "SPF check_host(%ip, %domain, %sender) = " + string logmsg "SPF check_host(%ip, %domain, %sender) = " . spf_status_string(%result) if %spf_cached - set logmsg %logmsg " [CACHED]" + set logmsg "%logmsg [CACHED]" fi if %spf_mechanism != "" - set logmsg %logmsg "; matching mechanism \"%spf_mechanism\"" + set logmsg "%logmsg; matching mechanism \"%spf_mechanism\"" fi if %spf_explanation != "" - set logmsg %logmsg "; %spf_explanation" + set logmsg "%logmsg; %spf_explanation" fi echo "$i: %logmsg" done diff --git a/mflib/strip_domain_part.mf b/mflib/strip_domain_part.mf index 1de92fe1..4be44dc5 100644 --- a/mflib/strip_domain_part.mf +++ b/mflib/strip_domain_part.mf @@ -22,7 +22,7 @@ func strip_domain_part(string domain, number n) do if %n = 0 return domainpart %domain - elif domainpart(%domain) matches '.*((\.[^.]+){' %n '})' + elif domainpart(%domain) matches '.*((\.[^.]+){' . %n . '})' return substring(\1, 1, -1) else return %domain diff --git a/tests/Makefile.am b/tests/Makefile.am index e6d3b960..19a0d720 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -101,6 +101,7 @@ TESTSUITE_AT = \ poll04.at\ public.at\ prec.at\ + prec01.at\ rcptargs |