Browse code

- multiple nested calls allowed - default MAX_NESTED_CALLS set to 4 (select was supposed to be fast :-) - IS_ALIAS renamed to NESTED flag - DIVERSION flag is processed at resolve_select

Michal Matyska authored on 19/01/2006 19:44:40
Showing 5 changed files
... ...
@@ -1263,7 +1263,7 @@ select_params:
1263 1263
 	| select_param
1264 1264
 	;
1265 1265
 select_id:
1266
-	SELECT_MARK { sel.n = 0; sel.f = 0; } select_params {
1266
+	SELECT_MARK { sel.n = 0; sel.f[0] = 0; } select_params {
1267 1267
 		sel_ptr = (select_t*)pkg_malloc(sizeof(select_t));
1268 1268
 		if (!sel_ptr) {
1269 1269
 			yyerror("No memory left to allocate select structure\n");
... ...
@@ -27,6 +27,8 @@
27 27
  * History:
28 28
  * --------
29 29
  *  2005-12-19  select framework (mma)
30
+ *  2006-01-19  multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
31
+ *              DIVERSION flag checked
30 32
  */
31 33
 
32 34
 
... ...
@@ -44,13 +46,16 @@ static select_table_t *select_list = &select_core_table;
44 46
 
45 47
 int resolve_select(select_t* s)
46 48
 {
47
-	select_f f, pf;
49
+	select_f f;
50
+	int nested;
48 51
 	int param_idx = 0;
49 52
 	int table_idx = 0;
50 53
 	select_table_t* t = NULL;;
51 54
 	int accept = 0;
52 55
 	
53
-	f = pf = NULL;
56
+	f = NULL;
57
+	nested = 0;
58
+	s->f[0] = NULL;
54 59
 	while (param_idx<s->n) {
55 60
 		accept = 0;
56 61
 		for (t=select_list; t; t=t->next) {
... ...
@@ -58,12 +63,14 @@ int resolve_select(select_t* s)
58 63
 			if (!t->table) continue;
59 64
 			while (t->table[table_idx].curr_f || t->table[table_idx].new_f) {
60 65
 				if (t->table[table_idx].curr_f == f) {
61
-					if (t->table[table_idx].type == s->params[param_idx].type) {
66
+					if (t->table[table_idx].flags & NESTED) {
67
+						accept = 1;
68
+					} else if (t->table[table_idx].type == s->params[param_idx].type) {
62 69
 						switch (t->table[table_idx].type) {
63 70
 						case SEL_PARAM_INT:
64 71
 							accept = 1;
65 72
 							break;
66
-							case SEL_PARAM_STR:
73
+						case SEL_PARAM_STR:
67 74
 							accept = (((t->table[table_idx].name.len == s->params[param_idx].v.s.len) || !t->table[table_idx].name.len)
68 75
 								   && (!t->table[table_idx].name.s || !strncasecmp(t->table[table_idx].name.s, s->params[param_idx].v.s.s, s->params[param_idx].v.s.len)));
69 76
 							break;
... ...
@@ -71,21 +78,26 @@ int resolve_select(select_t* s)
71 78
 							break;
72 79
 						}
73 80
 					};
74
-					if ((t->table[table_idx].flags & IS_ALIAS)&&(!pf)) {
75
-						accept = 1;
76
-					}
77 81
 				}
78 82
 				if (accept) goto accepted;
79 83
 				table_idx++;
80 84
 			}
81 85
 		}
86
+		BUG ("Unable to resolve select at level %d\n", param_idx);
82 87
 		goto not_found;
83 88
 
84 89
 		accepted:
90
+		if (t->table[table_idx].flags & DIVERSION) {
91
+			if (s->params[param_idx].type == SEL_PARAM_STR) pkg_free(s->params[param_idx].v.s.s);
92
+			s->params[param_idx].type = SEL_PARAM_DIV;
93
+			s->params[param_idx].v.i = t->table[table_idx].flags & DIVERSION_MASK;
94
+			
95
+		}
85 96
 		if (t->table[table_idx].flags & CONSUME_NEXT_STR) {
86 97
 			if ((param_idx<s->n-1) && (s->params[param_idx+1].type == SEL_PARAM_STR)) {
87 98
 				param_idx++;
88 99
 			} else if (!(t->table[table_idx].flags & OPTIONAL)) {
100
+				BUG ("Mandatory STR parameter not found\n");
89 101
 				goto not_found;
90 102
 			}
91 103
 		}
... ...
@@ -93,20 +105,37 @@ int resolve_select(select_t* s)
93 105
 			if ((param_idx<s->n-1) && (s->params[param_idx+1].type == SEL_PARAM_INT)) {
94 106
 				param_idx++;
95 107
 			} else if (!(t->table[table_idx].flags & OPTIONAL)) {
108
+				BUG ("Mandatory INT parameter not found\n");
96 109
 				goto not_found;
97 110
 			}
98 111
 		}
99
-		if (t->table[table_idx].flags & IS_ALIAS) {
100
-			pf = f;
112
+		if (t->table[table_idx].flags & NESTED) {
113
+			if (nested < MAX_NESTED_CALLS-1) { /* need space for final function */
114
+				s->f[nested++] = f;
115
+				s->f[nested] = NULL;
116
+			} else {
117
+				BUG("MAX_NESTED_CALLS too small to resolve select\n");
118
+				goto not_found;
119
+			}
101 120
 		} else {
102 121
 			param_idx++;
103 122
 		}
104 123
 		f = t->table[table_idx].new_f;
105 124
 	}
106 125
 
107
-	if (t->table[table_idx].flags & SEL_PARAM_EXPECTED) goto not_found;
108
-	s->f = f;
109
-	s->parent_f = pf;
126
+	if (t->table[table_idx].flags & SEL_PARAM_EXPECTED) {
127
+		BUG ("final node has SEL_PARAM_EXPECTED set (no more parameters available)\n");
128
+		goto not_found;
129
+	}
130
+	if (nested >= MAX_NESTED_CALLS) {
131
+		BUG("MAX_NESTED_CALLS too small, no space for finally resolved function\n");
132
+		goto not_found;
133
+	}
134
+	if ((nested>0) && (s->f[nested-1] == f)) {
135
+		BUG("Topmost nested function equals to final function, won't call it twice\n");
136
+	} else {
137
+		s->f[nested] = f;
138
+	}
110 139
 	return 0;
111 140
 	
112 141
 not_found:
... ...
@@ -115,6 +144,8 @@ not_found:
115 144
 
116 145
 int run_select(str* res, select_t* s, struct sip_msg* msg)
117 146
 {
147
+	int ret, i;
148
+	
118 149
 	if (res == NULL) {
119 150
 		BUG("Select unprepared result space\n");
120 151
 		return -1;
... ...
@@ -123,12 +154,17 @@ int run_select(str* res, select_t* s, struct sip_msg* msg)
123 154
 		BUG("Select structure is NULL\n");
124 155
 		return -1;
125 156
 	}
126
-	if (s->f == 0) {
157
+	if (s->f[0] == 0) {
127 158
 		BUG("Select structure has not been resolved\n");
128 159
 		return -1;
129 160
 	}
130
-DBG("Calling SELECT %p \n", s->f);
131
-	return s->f(res, s, msg);
161
+	DBG("Calling SELECT %p \n", s->f);
162
+
163
+	ret = 0;
164
+	for (i=0; (ret == 0) && (s->f[i] !=0 ) && (i<MAX_NESTED_CALLS); i++)	{
165
+		ret = s->f[i](res, s, msg);
166
+	}
167
+	return ret;
132 168
 }
133 169
 
134 170
 void print_select(select_t* s)
... ...
@@ -27,6 +27,7 @@
27 27
  * History:
28 28
  * --------
29 29
  *  2005-12-19  select framework (mma)
30
+ *  2006-01-19  multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
30 31
  */
31 32
 
32 33
  
... ...
@@ -37,25 +38,52 @@
37 38
 #include "parser/msg_parser.h"
38 39
 
39 40
 #define MAX_SELECT_PARAMS 32
41
+#define MAX_NESTED_CALLS  4
40 42
 
41
-// Flags for parser table FLAG bitfiels
43
+/* Flags for parser table FLAG bitfiels 
44
+ */
42 45
 #define DIVERSION_MASK   0x00FF
43
-// if DIVERSION is set and the function is accepted and has STR param
44
-// the param is changed into SEL_PARAM_DIV and the value is set to (flags & DIVERSION_MASK)
46
+
47
+/* if DIVERSION is set and the function is accepted
48
+ * the param is changed into SEL_PARAM_DIV and the value is set to (flags & DIVERSION_MASK)
49
+ *  - it is valuable for STR params (saves parsing time)
50
+ *  - does not release the memory occupied by the parameter
51
+ */
45 52
 #define DIVERSION        1<<8
46
-// if any parameter is expected at this stage
53
+
54
+/* set if any parameter is expected at this stage
55
+ * (the function must be resolved further)
56
+ */
47 57
 #define SEL_PARAM_EXPECTED   1<<9
48
-// accept if following parameter is STR (any)
58
+
59
+/* accept if following parameter is STR (any)
60
+ * consume that extra parameter in one step
61
+ */
49 62
 #define CONSUME_NEXT_STR 1<<10
50
-// accept if following parameter is INT
63
+
64
+/* accept if following parameter is INT
65
+ * consume that extra parameter in one ste
66
+ */
51 67
 #define CONSUME_NEXT_INT 1<<11
52
-// next parameter is optional (use with CONSUME_NEXT_STR or CONSUME_NEXT_INT
68
+
69
+/* next parameter is optional (use with CONSUME_NEXT_STR or CONSUME_NEXT_INT
70
+ * resolution is accepted even if there is no other parameter
71
+ * or the parameter is of wrong type
72
+ */
53 73
 #define OPTIONAL         1<<12
54
-// if conversion to common alias is needed
55
-// up-to now parsed function would be stored in parent_f
56
-// NOTE: the parameter is not consumed for ALIAS, 
57
-// so you can leave it as ..,SEL_PARAM_INT, STR_NULL,..
58
-#define IS_ALIAS         1<<13
74
+
75
+/* left function is noted to be called
76
+ * rigth function continues in resolution
77
+ * NOTE: the parameter is not consumed for PARENT, 
78
+ * so you can leave it as ..,SEL_PARAM_INT, 0,..
79
+ *
80
+ * run_select then calls all functions with PARENT flag
81
+ * in the order of resolution until the final call or 
82
+ * the result is != 0 (<0 error, 1 null str) 
83
+ * the only one parameter passed between nested calls
84
+ * is the result str*
85
+ */
86
+#define NESTED		1<<13
59 87
 
60 88
 /*
61 89
  * Selector call parameter
... ...
@@ -81,8 +109,7 @@ struct select;
81 109
 typedef int (*select_f)(str* res, struct select* s, struct sip_msg* msg);
82 110
 
83 111
 typedef struct select {
84
-	select_f f;
85
-	select_f parent_f;
112
+	select_f f[MAX_NESTED_CALLS];
86 113
 	select_param_t params[MAX_SELECT_PARAMS];
87 114
 	int n;
88 115
 } select_t;
... ...
@@ -27,6 +27,7 @@
27 27
  * History:
28 28
  * --------
29 29
  *  2005-12-19  select framework, basic core functions (mma)
30
+ *  2006-01-19  multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
30 31
  */
31 32
 
32 33
  
... ...
@@ -499,17 +500,8 @@ ABSTRACT_F(select_any_uri)
499 500
 
500 501
 int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
501 502
 {
502
-	if (!s->parent_f) {
503
-		ERR("BUG: no parent fuction defined\n");
504
-		return -1;
505
-	}
506
-
507
-	int ret;
508
-	ret = s->parent_f(res, s, msg);
509
-	if (ret != 0)
510
-		return ret;
511
-
512 503
 	struct sip_uri uri;
504
+	
513 505
 	trim(res);
514 506
 	if (parse_uri(res->s, res->len, &uri)<0)
515 507
 		return -1;
... ...
@@ -531,17 +523,8 @@ int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
531 523
 
532 524
 int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
533 525
 {
534
-	if (!s->parent_f) {
535
-		ERR("BUG: no parent fuction defined\n");
536
-		return -1;
537
-	}
538
-
539
-	int ret;
540
-	ret = s->parent_f(res, s, msg);
541
-	if (ret != 0)
542
-		return ret;
543
-
544 526
 	struct sip_uri uri;
527
+
545 528
 	if (parse_uri(res->s, res->len, &uri)<0)
546 529
 		return -1;
547 530
 
... ...
@@ -550,17 +533,8 @@ int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
550 533
 
551 534
 int select_uri_pwd(str* res, select_t* s, struct sip_msg* msg)
552 535
 {
553
-	if (!s->parent_f) {
554
-		ERR("BUG: no parent fuction defined\n");
555
-		return -1;
556
-	}
557
-
558
-	int ret;
559
-	ret = s->parent_f(res, s, msg);
560
-	if (ret != 0)
561
-		return ret;
562
-
563 536
 	struct sip_uri uri;
537
+
564 538
 	if (parse_uri(res->s, res->len, &uri)<0)
565 539
 		return -1;
566 540
 
... ...
@@ -569,17 +543,8 @@ int select_uri_pwd(str* res, select_t* s, struct sip_msg* msg)
569 543
 
570 544
 int select_uri_host(str* res, select_t* s, struct sip_msg* msg)
571 545
 {
572
-	if (!s->parent_f) {
573
-		ERR("BUG: no parent fuction defined\n");
574
-		return -1;
575
-	}
576
-
577
-	int ret;
578
-	ret = s->parent_f(res, s, msg);
579
-	if (ret != 0)
580
-		return ret;
581
-
582 546
 	struct sip_uri uri;
547
+
583 548
 	if (parse_uri(res->s, res->len, &uri)<0)
584 549
 		return -1;
585 550
 
... ...
@@ -588,17 +553,8 @@ int select_uri_host(str* res, select_t* s, struct sip_msg* msg)
588 553
 
589 554
 int select_uri_port(str* res, select_t* s, struct sip_msg* msg)
590 555
 {
591
-	if (!s->parent_f) {
592
-		ERR("BUG: no parent fuction defined\n");
593
-		return -1;
594
-	}
595
-
596
-	int ret;
597
-	ret = s->parent_f(res, s, msg);
598
-	if (ret != 0)
599
-		return ret;
600
-
601 556
 	struct sip_uri uri;
557
+	
602 558
 	if (parse_uri(res->s, res->len, &uri)<0)
603 559
 		return -1;
604 560
 
... ...
@@ -607,17 +563,8 @@ int select_uri_port(str* res, select_t* s, struct sip_msg* msg)
607 563
 
608 564
 int select_uri_params(str* res, select_t* s, struct sip_msg* msg)
609 565
 {
610
-	if (!s->parent_f) {
611
-		ERR("BUG: no parent fuction defined\n");
612
-		return -1;
613
-	}
614
-
615
-	int ret;
616
-	ret = s->parent_f(res, s, msg);
617
-	if (ret != 0)
618
-		return ret;
619
-
620 566
 	struct sip_uri uri;
567
+
621 568
 	if (parse_uri(res->s, res->len, &uri)<0)
622 569
 		return -1;
623 570
 		
... ...
@@ -27,6 +27,7 @@
27 27
  * History:
28 28
  * --------
29 29
  *  2005-12-19  select framework, basic core functions (mma)
30
+ *  2006-01-19  multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
30 31
  */
31 32
 
32 33
  
... ...
@@ -117,9 +118,9 @@ static select_row_t select_core[] = {
117 118
 	{ select_via, SEL_PARAM_STR, STR_STATIC_INIT("alias"), select_via_params_spec, DIVERSION | SEL_PARAM_ALIAS},
118 119
 	{ select_via, SEL_PARAM_STR, STR_STATIC_INIT("params"), select_via_params, CONSUME_NEXT_STR},
119 120
 	
120
-	{ select_from_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, IS_ALIAS},
121
-	{ select_to_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, IS_ALIAS},
122
-	{ select_contact_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, IS_ALIAS},
121
+	{ select_from_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, NESTED},
122
+	{ select_to_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, NESTED},
123
+	{ select_contact_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, NESTED},
123 124
 	{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("type"), select_uri_type, 0},
124 125
 	{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("user"), select_uri_user, 0},
125 126
 	{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("pwd"), select_uri_pwd, 0},