Browse code

script: basic support for parsing pvar names

- parse pvar names and try to guess on ambiguous pvar/avps identifiers
(e.g.: $foo)

Andrei Pelinescu-Onciul authored on 28/11/2008 19:24:04
Showing 2 changed files
... ...
@@ -75,6 +75,7 @@
75 75
  *  2007-11-28  added TCP_OPT_{FD_CACHE, DEFER_ACCEPT, DELAYED_ACK, SYNCNT,
76 76
  *              LINGER2, KEEPALIVE, KEEPIDLE, KEEPINTVL, KEEPCNT} (andrei)
77 77
  *  2008-01-24  added CFG_DESCRIPTION used by cfg_var (Miklos)
78
+ *  2008-11-28  added support for kamailio pvars and avp/pvar guessing (andrei)
78 79
 */
79 80
 
80 81
 
... ...
@@ -94,8 +95,10 @@
94 95
 	#define COMMENT_S		1
95 96
 	#define COMMENT_LN_S	        2
96 97
 	#define STRING_S		3
97
-	#define ATTR_S                  4
98
-        #define SELECT_S                5
98
+	#define ATTR_S                  4  /* avp/attr */
99
+	#define SELECT_S                5
100
+	#define AVP_PVAR_S              6  /* avp or pvar */
101
+	#define PVAR_P_S                7  /* pvar: $(...)  or $foo(...)*/
99 102
 
100 103
 	#define STR_BUF_ALLOC_UNIT	128
101 104
 	struct str_buf{
... ...
@@ -106,6 +109,7 @@
106 109
 
107 110
 
108 111
 	static int comment_nest=0;
112
+	static int p_nest=0;
109 113
 	static int state=0, old_state=0, old_initial=0;
110 114
 	static struct str_buf s_buf;
111 115
 	int line=1;
... ...
@@ -120,7 +124,7 @@
120 124
 %}
121 125
 
122 126
 /* start conditions */
123
-%x STRING1 STRING2 COMMENT COMMENT_LN ATTR SELECT
127
+%x STRING1 STRING2 COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P
124 128
 
125 129
 /* action keywords */
126 130
 FORWARD	forward
... ...
@@ -219,7 +223,8 @@ PLUS	"+"
219 223
 MINUS	"-"
220 224
 
221 225
 /* Attribute specification */
222
-ATTR_MARK   "$"|"%"
226
+ATTR_MARK   "%"
227
+VAR_MARK    "$"
223 228
 SELECT_MARK  "@"
224 229
 ATTR_FROM         "f"
225 230
 ATTR_TO           "t"
... ...
@@ -231,6 +236,9 @@ ATTR_FROMDOMAIN   "fd"
231 236
 ATTR_TODOMAIN     "td"
232 237
 ATTR_GLOBAL       "g"
233 238
 
239
+/* avp prefix */
240
+AVP_PREF	(([ft][rud]?)|g)\.
241
+
234 242
 /* config vars. */
235 243
 DEBUG	debug
236 244
 FORK	fork
... ...
@@ -729,7 +737,8 @@ EAT_ABLE	[\ \t\b\r]
729 737
 <SELECT>{BINNUMBER}     { count(); yylval.intval=(int)strtol(yytext, 0, 2); return NUMBER; }
730 738
 
731 739
 
732
-<INITIAL>{ATTR_MARK}    { count(); state = ATTR_S; BEGIN(ATTR); return ATTR_MARK; }
740
+<INITIAL>{ATTR_MARK}    { count(); state = ATTR_S; BEGIN(ATTR);
741
+							return ATTR_MARK; }
733 742
 <ATTR>{ATTR_FROM}       { count(); return ATTR_FROM; }
734 743
 <ATTR>{ATTR_TO}         { count(); return ATTR_TO; }
735 744
 <ATTR>{ATTR_FROMURI}    { count(); return ATTR_FROMURI; }
... ...
@@ -742,15 +751,48 @@ EAT_ABLE	[\ \t\b\r]
742 751
 <ATTR>{DOT}             { count(); return DOT; }
743 752
 <ATTR>{LBRACK}          { count(); return LBRACK; }
744 753
 <ATTR>{RBRACK}          { count(); return RBRACK; }
745
-<ATTR>{STAR}		{ count(); return STAR; }
746
-<ATTR>{DECNUMBER}	{ count(); yylval.intval=atoi(yytext);return NUMBER; }
747
-<ATTR>{ID}		{ count(); addstr(&s_buf, yytext, yyleng);
748
-                           yylval.strval=s_buf.s;
749
-			   memset(&s_buf, 0, sizeof(s_buf));
750
-                           state = INITIAL_S;
751
-                           BEGIN(INITIAL);
752
-			   return ID;
753
-                        }
754
+<ATTR>{STAR}			{ count(); return STAR; }
755
+<ATTR>{DECNUMBER}		{ count(); yylval.intval=atoi(yytext);return NUMBER; }
756
+<ATTR>{ID}				{ count(); addstr(&s_buf, yytext, yyleng);
757
+							yylval.strval=s_buf.s;
758
+							memset(&s_buf, 0, sizeof(s_buf));
759
+							state = INITIAL_S;
760
+							BEGIN(INITIAL);
761
+							return ID;
762
+						}
763
+
764
+<INITIAL>{VAR_MARK}{LPAREN}	{ state = PVAR_P_S; BEGIN(PVAR_P); p_nest=1; 
765
+								yymore();}
766
+	/* eat everything between 2 () and return PVAR token and a string
767
+	   containing everything (including $ and ()) */
768
+<PVAR_P>{RPAREN}			{	p_nest--;
769
+								if (p_nest==0){
770
+									count();
771
+									addstr(&s_buf, yytext, yyleng);
772
+									yylval.strval=s_buf.s;
773
+									memset(&s_buf, 0, sizeof(s_buf));
774
+									state=INITIAL_S;
775
+									BEGIN(INITIAL);
776
+									return PVAR;
777
+								}
778
+								yymore();
779
+							}
780
+<PVAR_P>.					{ yymore(); }
781
+
782
+
783
+<INITIAL>{VAR_MARK}			{  state=AVP_PVAR_S; BEGIN(AVP_PVAR); yymore(); }
784
+	/* avp prefix detected -> go to avp mode */
785
+<AVP_PVAR>{AVP_PREF}		|
786
+<AVP_PVAR>{ID}{LBRACK}		{ state = ATTR_S; BEGIN(ATTR); yyless(1); 
787
+							  return ATTR_MARK; }
788
+<AVP_PVAR>{ID}{LPAREN}		{ state = PVAR_P_S; BEGIN(PVAR_P); yymore(); }
789
+<AVP_PVAR>{ID}				{ count(); addstr(&s_buf, yytext, yyleng);
790
+								yylval.strval=s_buf.s;
791
+								memset(&s_buf, 0, sizeof(s_buf));
792
+								state = INITIAL_S;
793
+								BEGIN(INITIAL);
794
+								return AVP_OR_PVAR;
795
+							}
754 796
 
755 797
 <INITIAL>{IPV6ADDR}		{ count(); yylval.strval=yytext; return IPV6ADDR; }
756 798
 <INITIAL>{DECNUMBER}		{ count(); yylval.intval=atoi(yytext);return NUMBER; }
... ...
@@ -185,8 +185,17 @@ static struct ip_addr* ip_tmp;
185 185
 static struct avp_spec* s_attr;
186 186
 static select_t sel;
187 187
 static select_t* sel_ptr;
188
+static pv_spec_t* pv_spec;
188 189
 static struct action *mod_func_action;
189 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;
198
+
190 199
 static void warn(char* s);
191 200
 static struct socket_id* mk_listen_id(char*, int, int);
192 201
 static struct name_lst* mk_name_lst(char* name, int flags);
... ...
@@ -207,6 +216,8 @@ static void free_socket_id_lst(struct socket_id* i);
207 216
 	struct socket_id* sockid;
208 217
 	struct name_lst* name_l;
209 218
 	struct avp_spec* attr;
219
+	struct pv_spec_t* pvar;
220
+	struct avp_pvar_spec* avp_pvar_s;
210 221
 	select_t* select;
211 222
 }
212 223
 
... ...
@@ -426,6 +437,7 @@ static void free_socket_id_lst(struct socket_id* i);
426 437
 %token ATTR_GLOBAL
427 438
 %token ADDEQ
428 439
 
440
+
429 441
 %token STUN_REFRESH_INTERVAL
430 442
 %token STUN_ALLOW_STUN
431 443
 %token STUN_ALLOW_FP
... ...
@@ -452,6 +464,9 @@ static void free_socket_id_lst(struct socket_id* i);
452 464
 %token <strval> ID
453 465
 %token <strval> STRING
454 466
 %token <strval> IPV6ADDR
467
+%token <strval> PVAR
468
+/* not clear yet if this is an avp or pvar */
469
+%token <strval> AVP_OR_PVAR
455 470
 
456 471
 /* other */
457 472
 %token COMMA
... ...
@@ -492,6 +507,8 @@ static void free_socket_id_lst(struct socket_id* i);
492 507
 %type <attr> attr_id_val
493 508
 %type <attr> attr_id_any
494 509
 %type <attr> attr_id_any_str
510
+%type <pvar> pvar
511
+%type <avp_pvar_s> avp_pvar
495 512
 /* %type <intval> class_id */
496 513
 %type <intval> assign_op
497 514
 %type <select> select_id
... ...
@@ -1954,7 +1971,7 @@ attr_id_any_str:
1954 1971
 		s.len = strlen(s.s);
1955 1972
 		if (parse_avp_name(&s, &type, &avp_spec->name, &idx)) {
1956 1973
 			yyerror("error when parsing AVP");
1957
-		        pkg_free(avp_spec);
1974
+			pkg_free(avp_spec);
1958 1975
 			YYABORT;
1959 1976
 		}
1960 1977
 		avp_spec->type = type;
... ...
@@ -1962,6 +1979,52 @@ attr_id_any_str:
1962 1979
 		$$ = avp_spec;
1963 1980
 	}
1964 1981
 	;
1982
+
1983
+pvar:	PVAR {
1984
+			pv_spec=pkg_malloc(sizeof(*pv_spec));
1985
+			if (!pv_spec) {
1986
+				yyerror("Not enough memory");
1987
+				YYABORT;
1988
+			}
1989
+			s.s=$1; s.len=strlen(s.s);
1990
+			if (pv_parse_spec(&s, pv_spec)==0){
1991
+				yyerror("unknown script pseudo variable");
1992
+				pkg_free(pv_spec);
1993
+				YYABORT;
1994
+			}
1995
+			$$=pv_spec;
1996
+			BUG("parsed pvar \"%.*s\"\n", s.len, s.s);
1997
+		}
1998
+	;
1999
+
2000
+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);
2013
+					YYABORT;
2014
+				}
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;
2020
+			}
2021
+			$$ = apv_spec;
2022
+			BUG("parsed ambigous avp/pvar \"%.*s\" to %d\n", s.len, s.s,
2023
+					apv_spec.type);
2024
+		}
2025
+	;
2026
+
2027
+
1965 2028
 /*
1966 2029
 assign_op:
1967 2030
 	ADDEQ { $$ = ADD_T; }
... ...
@@ -1979,6 +2042,8 @@ assign_action:
1979 2042
 	| attr_id_ass assign_op select_id { $$=mk_action($2, 2, AVP_ST, (void*)$1, SELECT_ST, (void*)$3); }
1980 2043
 	| attr_id_ass assign_op LPAREN exp RPAREN { $$ = mk_action($2, 2, AVP_ST, $1, EXPR_ST, $4); }
1981 2044
 	;
2045
+
2046
+
1982 2047
 avpflag_oper:
1983 2048
 	SETAVPFLAG { $$ = 1; }
1984 2049
 	| RESETAVPFLAG { $$ = 0; }