Merge commit 'origin/andrei/type_conversion'
[sip-router] / cfg.y
diff --git a/cfg.y b/cfg.y
index 622e880..18b69e1 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -485,7 +485,7 @@ static int case_check_default(struct case_stms* stms);
 %left LOG_AND
 %left BIN_OR
 %left BIN_AND
-%left EQUAL_T DIFF MATCH
+%left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
 %left GT LT GTE LTE
 %left PLUS MINUS
 %left STAR SLASH
@@ -1568,7 +1568,10 @@ send_route_stm: ROUTE_SEND LBRACE actions RBRACE {
 
 exp:   rval_expr
                {
-                       if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
+                       if ($1==0){
+                               yyerror("invalid expression");
+                               $$=0;
+                       }else if (!rve_check_type((enum rval_type*)&i_tmp, $1, 0, 0 ,0)){
                                yyerror("invalid expression");
                                $$=0;
                        }else if (i_tmp!=RV_INT && i_tmp!=RV_NONE){
@@ -1583,6 +1586,8 @@ exp:      rval_expr
 equalop:
        EQUAL_T {$$=EQUAL_OP; }
        | DIFF  {$$=DIFF_OP; }
+       | STREQ {$$=EQUAL_OP; }  /* for expr. elems equiv. to EQUAL_T*/
+       | STRDIFF {$$=DIFF_OP; } /* for expr. elems. equiv. to DIFF */
        ;
 cmpop:
          GT    {$$=GT_OP; }
@@ -1600,6 +1605,10 @@ strop:
 rve_equalop:
        EQUAL_T {$$=RVE_EQ_OP; }
        | DIFF  {$$=RVE_DIFF_OP; }
+       | INTEQ {$$=RVE_IEQ_OP; }
+       | INTDIFF {$$=RVE_IDIFF_OP; }
+       | STREQ {$$=RVE_STREQ_OP; }
+       | STRDIFF {$$=RVE_STRDIFF_OP; }
        ;
 rve_cmpop:
          GT    {$$=RVE_GT_OP; }
@@ -2217,9 +2226,9 @@ rval: intno                       {$$=mk_rve_rval(RV_INT, (void*)$1); }
        | fcmd                          {$$=mk_rve_rval(RV_ACTION_ST, $1); }
        | exp_elem { $$=mk_rve_rval(RV_BEXPR, $1); }
        | LBRACE actions RBRACE {$$=mk_rve_rval(RV_ACTION_ST, $2); }
-       | LBRACE error RBRACE   { yyerror("bad command block"); }
+       | LBRACE error RBRACE   { $$=0; yyerror("bad command block"); }
        | LPAREN assign_action RPAREN   {$$=mk_rve_rval(RV_ACTION_ST, $2); }
-       | LPAREN error RPAREN   { yyerror("bad expression"); }
+       | LPAREN error RPAREN   { $$=0; yyerror("bad expression"); }
        ;
 
 
@@ -2237,10 +2246,11 @@ rve_op:         PLUS            { $$=RVE_PLUS_OP; }
 */
 
 rval_expr: rval                                                { $$=$1;
-                                                                                       if ($$==0){
+                                                                               /*      if ($$==0){
                                                                                                yyerror("out of memory\n");
                                                                                                YYABORT;
                                                                                        }
+                                                                                       */
                                                                        }
                | rve_un_op %prec NOT rval_expr {$$=mk_rve1($1, $2); }
                | rval_expr PLUS rval_expr              {$$=mk_rve2(RVE_PLUS_OP, $1, $3); }
@@ -2258,7 +2268,7 @@ rval_expr: rval                                           { $$=$1;
                | STRLEN LPAREN rval_expr RPAREN { $$=mk_rve1(RVE_STRLEN_OP, $3);}
                | STREMPTY LPAREN rval_expr RPAREN {$$=mk_rve1(RVE_STREMPTY_OP, $3);}
                | DEFINED rval_expr                             { $$=mk_rve1(RVE_DEFINED_OP, $2);}
-               | rve_un_op %prec NOT error             { yyerror("bad expression"); }
+               | rve_un_op %prec NOT error             { $$=0; yyerror("bad expression"); }
                | rval_expr PLUS error                  { yyerror("bad expression"); }
                | rval_expr MINUS error                 { yyerror("bad expression"); }
                | rval_expr STAR error                  { yyerror("bad expression"); }
@@ -2271,9 +2281,9 @@ rval_expr: rval                                           { $$=$1;
                        { yyerror("bad expression"); }
                | rval_expr LOG_AND error               { yyerror("bad expression"); }
                | rval_expr LOG_OR error                { yyerror("bad expression"); }
-               | STRLEN LPAREN error RPAREN    { yyerror("bad expression"); }
-               | STREMPTY LPAREN error RPAREN  { yyerror("bad expression"); }
-               | DEFINED error                                 { yyerror("bad expression"); }
+               | STRLEN LPAREN error RPAREN    { $$=0; yyerror("bad expression"); }
+               | STREMPTY LPAREN error RPAREN  { $$=0; yyerror("bad expression"); }
+               | DEFINED error                                 { $$=0; yyerror("bad expression"); }
                ;
 
 assign_action: lval assign_op  rval_expr       { $$=mk_action($2, 2, LVAL_ST, $1, 
@@ -2901,13 +2911,19 @@ static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
        
        if ((rve1==0) || (rve2==0))
                return 0;
+       bad_rve=0;
+       bad_t=0;
+       exp_t=0;
        cfg_pos_join(&pos, &rve1->fpos, &rve2->fpos);
        ret=mk_rval_expr2(op, rve1, rve2, &pos);
        if (ret && (rve_check_type(&type, ret, &bad_rve, &bad_t, &exp_t)!=1)){
-               yyerror_at(&pos, "bad expression: type mismatch:"
+               if (bad_rve)
+                       yyerror_at(&pos, "bad expression: type mismatch:"
                                                " %s instead of %s at (%d,%d)",
                                                rval_type_name(bad_t), rval_type_name(exp_t),
                                                bad_rve->fpos.s_line, bad_rve->fpos.s_col);
+               else
+                       yyerror("BUG: unexpected null \"bad\" expression\n");
        }
        return ret;
 }