Browse code

script: lvalue = rvalue expression support

- lvalue = rvalue op rvalue ...

Andrei Pelinescu-Onciul authored on 04/12/2008 00:10:12
Showing 1 changed files
... ...
@@ -89,6 +89,8 @@
89 89
  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
90 90
  * 2008-01-24  added cfg_var definition (Miklos)
91 91
  * 2008-11-18  support for variable parameter module functions (andrei)
92
+ * 2007-12-03  support for generalised lvalues and rvalues:
93
+ *               lval=rval_expr, where lval=avp|pvar  (andrei)
92 94
 */
93 95
 
94 96
 %{
... ...
@@ -118,6 +120,10 @@
118 120
 #include "tcp_init.h"
119 121
 #include "tcp_options.h"
120 122
 #include "sctp_options.h"
123
+#include "pvar.h"
124
+#include "lvalue.h"
125
+#include "rvalue.h"
126
+#include "sr_compat.h"
121 127
 
122 128
 #include "config.h"
123 129
 #include "cfg_core.h"
... ...
@@ -187,14 +193,7 @@ static select_t sel;
187 193
 static select_t* sel_ptr;
188 194
 static pv_spec_t* pv_spec;
189 195
 static struct action *mod_func_action;
190
-
191
-static struct avp_pvar_spec{
192
-	int type;
193
-	union{
194
-		struct avp_spec avp;
195
-		pv_spec_t pv;
196
-	}u;
197
-} *apv_spec;
196
+static struct lvalue* lval_tmp;
198 197
 
199 198
 static void warn(char* s);
200 199
 static struct socket_id* mk_listen_id(char*, int, int);
... ...
@@ -216,8 +215,10 @@ static void free_socket_id_lst(struct socket_id* i);
216 215
 	struct socket_id* sockid;
217 216
 	struct name_lst* name_l;
218 217
 	struct avp_spec* attr;
219
-	struct pv_spec_t* pvar;
220
-	struct avp_pvar_spec* avp_pvar_s;
218
+	struct _pv_spec* pvar;
219
+	struct lvalue* lval;
220
+	struct rvalue* rval;
221
+	struct rval_expr* rv_expr;
221 222
 	select_t* select;
222 223
 }
223 224
 
... ...
@@ -508,13 +509,17 @@ static void free_socket_id_lst(struct socket_id* i);
508 509
 %type <attr> attr_id_any
509 510
 %type <attr> attr_id_any_str
510 511
 %type <pvar> pvar
511
-%type <avp_pvar_s> avp_pvar
512
+%type <lval> lval
513
+%type <rv_expr> rval rval_expr
514
+%type <lval> avp_pvar
512 515
 /* %type <intval> class_id */
513 516
 %type <intval> assign_op
514 517
 %type <select> select_id
515 518
 %type <strval>	flag_name;
516 519
 %type <strval>	route_name;
517 520
 %type <intval> avpflag_oper
521
+%type <intval> rve_un_op
522
+%type <intval> rve_op
518 523
 
519 524
 /*%type <route_el> rules;
520 525
   %type <route_el> rule;
... ...
@@ -1986,42 +1991,38 @@ pvar:	PVAR {
1986 1991
 				yyerror("Not enough memory");
1987 1992
 				YYABORT;
1988 1993
 			}
1989
-			s.s=$1; s.len=strlen(s.s);
1990
-			if (pv_parse_spec(&s, pv_spec)==0){
1994
+			memset(pv_spec, 0, sizeof(*pv_spec));
1995
+			s_tmp.s=$1; s_tmp.len=strlen($1);
1996
+			if (pv_parse_spec(&s_tmp, pv_spec)==0){
1991 1997
 				yyerror("unknown script pseudo variable");
1992 1998
 				pkg_free(pv_spec);
1993 1999
 				YYABORT;
1994 2000
 			}
1995 2001
 			$$=pv_spec;
1996
-			BUG("parsed pvar \"%.*s\"\n", s.len, s.s);
1997 2002
 		}
1998 2003
 	;
1999 2004
 
2000 2005
 avp_pvar:	AVP_OR_PVAR {
2001
-			apv=pkg_malloc(sizeof(*apv));
2002
-			if (!apv) {
2003
-				yyerror("Not enough memory");
2004
-				YYABORT;
2005
-			}
2006
-			s.s=$1; s.len=strlen(s.s);
2007
-			if (pv_parse_spec(&s, &apv_spec->u.pv)==0){
2008
-				/* not a pvar, try avps */
2009
-				/* TODO: test if in ser or k mode */
2010
-				if (parse_avp_name(&s, &type, &apv_spec->u.avp.name, &idx)) {
2011
-					yyerror("error when parsing AVP");
2012
-					pkg_free(apv_spec);
2006
+				lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2007
+				if (!lval_tmp) {
2008
+					yyerror("Not enough memory");
2013 2009
 					YYABORT;
2014 2010
 				}
2015
-				apv_spec->u.avp.type = type;
2016
-				apv_spec->u.avp.index = idx;
2017
-				apv_spec.type=APV_AVP_T;
2018
-			}else{
2019
-				apv_spec.type=APV_PVAR_T;
2011
+				memset(lval_tmp, 0, sizeof(*lval_tmp));
2012
+				s_tmp.s=$1; s_tmp.len=strlen(s_tmp.s);
2013
+				if (pv_parse_spec(&s_tmp, &lval_tmp->lv.pvs)==0){
2014
+					/* not a pvar, try avps */
2015
+					lval_tmp->lv.avps.type|= AVP_NAME_STR;
2016
+					lval_tmp->lv.avps.name.s.s = s_tmp.s+1;
2017
+					lval_tmp->lv.avps.name.s.len = s_tmp.len-1;
2018
+					lval_tmp->type=LV_AVP;
2019
+				}else{
2020
+					lval_tmp->type=LV_PVAR;
2021
+				}
2022
+				$$ = lval_tmp;
2023
+				DBG("parsed ambigous avp/pvar \"%.*s\" to %d\n",
2024
+							s_tmp.len, s_tmp.s, lval_tmp->type);
2020 2025
 			}
2021
-			$$ = apv_spec;
2022
-			BUG("parsed ambigous avp/pvar \"%.*s\" to %d\n", s.len, s.s,
2023
-					apv_spec.type);
2024
-		}
2025 2026
 	;
2026 2027
 
2027 2028
 
... ...
@@ -2034,6 +2035,98 @@ assign_op:
2034 2035
 assign_op:
2035 2036
 	EQUAL { $$ = ASSIGN_T; }
2036 2037
 	;
2038
+
2039
+
2040
+lval: attr_id_ass {
2041
+					lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2042
+					if (!lval_tmp) {
2043
+						yyerror("Not enough memory");
2044
+						YYABORT;
2045
+					}
2046
+					lval_tmp->type=LV_AVP; lval_tmp->lv.avps=*$1;
2047
+					pkg_free($1); /* free the avp spec we just copied */
2048
+					$$=lval_tmp;
2049
+				}
2050
+	| pvar        {
2051
+					if (!pv_is_w($1))
2052
+						yyerror("read only pvar in assignment left side");
2053
+					if ($1->trans!=0)
2054
+						yyerror("pvar with transformations in assignment"
2055
+								" left side");
2056
+					lval_tmp=pkg_malloc(sizeof(*lval_tmp));
2057
+					if (!lval_tmp) {
2058
+						yyerror("Not enough memory");
2059
+						YYABORT;
2060
+					}
2061
+					lval_tmp->type=LV_PVAR; lval_tmp->lv.pvs=*($1);
2062
+					pkg_free($1); /* free the pvar spec we just copied */
2063
+					$$=lval_tmp;
2064
+				}
2065
+	| avp_pvar    {
2066
+					if (($1)->type==LV_PVAR){
2067
+						if (!pv_is_w(&($1)->lv.pvs))
2068
+							yyerror("read only pvar in assignment left side");
2069
+						if ($1->lv.pvs.trans!=0)
2070
+							yyerror("pvar with transformations in assignment"
2071
+									" left side");
2072
+					}
2073
+					$$=$1;
2074
+				}
2075
+	;
2076
+
2077
+rval: NUMBER			{$$=mk_rval_expr_v(RV_INT, (void*)$1); }
2078
+	| STRING			{	s_tmp.s=$1; s_tmp.len=strlen($1);
2079
+							$$=mk_rval_expr_v(RV_STR, &s_tmp); }
2080
+	| attr_id_any		{$$=mk_rval_expr_v(RV_AVP, $1); pkg_free($1); }
2081
+	| pvar				{$$=mk_rval_expr_v(RV_PVAR, $1); pkg_free($1); }
2082
+	| avp_pvar			{
2083
+							switch($1->type){
2084
+								case LV_AVP:
2085
+									$$=mk_rval_expr_v(RV_AVP, &$1->lv.avps);
2086
+									break;
2087
+								case LV_PVAR:
2088
+									$$=mk_rval_expr_v(RV_PVAR, &$1->lv.pvs);
2089
+									break;
2090
+								default:
2091
+									yyerror("BUG: invalid lvalue type ");
2092
+									YYABORT;
2093
+							}
2094
+							pkg_free($1); /* not needed anymore */
2095
+						}
2096
+	| select_id			{$$=mk_rval_expr_v(RV_SEL, $1); pkg_free($1); }
2097
+	| fcmd				{$$=mk_rval_expr_v(RV_ACTION_ST, $1); }
2098
+	//| exp 				{$$=mk_rval_expr_v(RV_BEXPR, $1);}
2099
+	/* missing/TODO: RV_ACTION_ST */
2100
+	;
2101
+
2102
+
2103
+rve_un_op: MINUS	{ $$=RVE_UMINUS_OP; }
2104
+		/* TODO: RVE_BOOL_OP, RVE_NOT_OP? */
2105
+	;
2106
+
2107
+rve_op:		PLUS		{ $$=RVE_PLUS_OP; }
2108
+		|	MINUS		{ $$=RVE_MINUS_OP; }
2109
+		|	STAR		{ $$=RVE_MUL_OP; }
2110
+		/* TODO: RVE_DIV_OP */
2111
+	;
2112
+	
2113
+rval_expr: rval							{ $$=$1;
2114
+											if ($$==0){
2115
+												yyerror("out of memory\n");
2116
+												YYABORT;
2117
+											}
2118
+										}
2119
+		| LPAREN rval_expr RPAREN		{ $$=$2; }
2120
+		| rve_un_op rval_expr			{$$=mk_rval_expr1($1, $2); }
2121
+		| rval_expr rve_op rval_expr	{$$=mk_rval_expr2($2, $1, $3); }
2122
+	;
2123
+
2124
+assign_action: lval assign_op rval_expr	{ $$=mk_action($2, 2, LVAL_ST, $1, 
2125
+														 	  RVE_ST, $3);
2126
+										}
2127
+	;
2128
+
2129
+/*
2037 2130
 assign_action:
2038 2131
 	attr_id_ass assign_op STRING  { $$=mk_action($2, 2, AVP_ST, $1, STRING_ST, $3); }
2039 2132
 	| attr_id_ass assign_op NUMBER  { $$=mk_action($2, 2, AVP_ST, $1, NUMBER_ST, (void*)$3); }
... ...
@@ -2042,7 +2135,7 @@ assign_action:
2042 2135
 	| attr_id_ass assign_op select_id { $$=mk_action($2, 2, AVP_ST, (void*)$1, SELECT_ST, (void*)$3); }
2043 2136
 	| attr_id_ass assign_op LPAREN exp RPAREN { $$ = mk_action($2, 2, AVP_ST, $1, EXPR_ST, $4); }
2044 2137
 	;
2045
-
2138
+*/
2046 2139
 
2047 2140
 avpflag_oper:
2048 2141
 	SETAVPFLAG { $$ = 1; }