Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

- 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
  • Loading branch information...
commit 43f88e4ff45dfaa001fbb686a9b33ad54bd3f834 1 parent 5b1455d
Michal Matyska authored
Showing with 104 additions and 93 deletions.
  1. +1 −1  cfg.y
  2. +51 −15 select.c
  3. +41 −14 select.h
  4. +7 −60 select_core.c
  5. +4 −3 select_core.h
2  cfg.y
View
@@ -1263,7 +1263,7 @@ select_params:
| select_param
;
select_id:
- SELECT_MARK { sel.n = 0; sel.f = 0; } select_params {
+ SELECT_MARK { sel.n = 0; sel.f[0] = 0; } select_params {
sel_ptr = (select_t*)pkg_malloc(sizeof(select_t));
if (!sel_ptr) {
yyerror("No memory left to allocate select structure\n");
66 select.c
View
@@ -27,6 +27,8 @@
* History:
* --------
* 2005-12-19 select framework (mma)
+ * 2006-01-19 multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
+ * DIVERSION flag checked
*/
@@ -44,13 +46,16 @@ static select_table_t *select_list = &select_core_table;
int resolve_select(select_t* s)
{
- select_f f, pf;
+ select_f f;
+ int nested;
int param_idx = 0;
int table_idx = 0;
select_table_t* t = NULL;;
int accept = 0;
- f = pf = NULL;
+ f = NULL;
+ nested = 0;
+ s->f[0] = NULL;
while (param_idx<s->n) {
accept = 0;
for (t=select_list; t; t=t->next) {
@@ -58,12 +63,14 @@ int resolve_select(select_t* s)
if (!t->table) continue;
while (t->table[table_idx].curr_f || t->table[table_idx].new_f) {
if (t->table[table_idx].curr_f == f) {
- if (t->table[table_idx].type == s->params[param_idx].type) {
+ if (t->table[table_idx].flags & NESTED) {
+ accept = 1;
+ } else if (t->table[table_idx].type == s->params[param_idx].type) {
switch (t->table[table_idx].type) {
case SEL_PARAM_INT:
accept = 1;
break;
- case SEL_PARAM_STR:
+ case SEL_PARAM_STR:
accept = (((t->table[table_idx].name.len == s->params[param_idx].v.s.len) || !t->table[table_idx].name.len)
&& (!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)));
break;
@@ -71,21 +78,26 @@ int resolve_select(select_t* s)
break;
}
};
- if ((t->table[table_idx].flags & IS_ALIAS)&&(!pf)) {
- accept = 1;
- }
}
if (accept) goto accepted;
table_idx++;
}
}
+ BUG ("Unable to resolve select at level %d\n", param_idx);
goto not_found;
accepted:
+ if (t->table[table_idx].flags & DIVERSION) {
+ if (s->params[param_idx].type == SEL_PARAM_STR) pkg_free(s->params[param_idx].v.s.s);
+ s->params[param_idx].type = SEL_PARAM_DIV;
+ s->params[param_idx].v.i = t->table[table_idx].flags & DIVERSION_MASK;
+
+ }
if (t->table[table_idx].flags & CONSUME_NEXT_STR) {
if ((param_idx<s->n-1) && (s->params[param_idx+1].type == SEL_PARAM_STR)) {
param_idx++;
} else if (!(t->table[table_idx].flags & OPTIONAL)) {
+ BUG ("Mandatory STR parameter not found\n");
goto not_found;
}
}
@@ -93,20 +105,37 @@ int resolve_select(select_t* s)
if ((param_idx<s->n-1) && (s->params[param_idx+1].type == SEL_PARAM_INT)) {
param_idx++;
} else if (!(t->table[table_idx].flags & OPTIONAL)) {
+ BUG ("Mandatory INT parameter not found\n");
goto not_found;
}
}
- if (t->table[table_idx].flags & IS_ALIAS) {
- pf = f;
+ if (t->table[table_idx].flags & NESTED) {
+ if (nested < MAX_NESTED_CALLS-1) { /* need space for final function */
+ s->f[nested++] = f;
+ s->f[nested] = NULL;
+ } else {
+ BUG("MAX_NESTED_CALLS too small to resolve select\n");
+ goto not_found;
+ }
} else {
param_idx++;
}
f = t->table[table_idx].new_f;
}
- if (t->table[table_idx].flags & SEL_PARAM_EXPECTED) goto not_found;
- s->f = f;
- s->parent_f = pf;
+ if (t->table[table_idx].flags & SEL_PARAM_EXPECTED) {
+ BUG ("final node has SEL_PARAM_EXPECTED set (no more parameters available)\n");
+ goto not_found;
+ }
+ if (nested >= MAX_NESTED_CALLS) {
+ BUG("MAX_NESTED_CALLS too small, no space for finally resolved function\n");
+ goto not_found;
+ }
+ if ((nested>0) && (s->f[nested-1] == f)) {
+ BUG("Topmost nested function equals to final function, won't call it twice\n");
+ } else {
+ s->f[nested] = f;
+ }
return 0;
not_found:
@@ -115,6 +144,8 @@ int resolve_select(select_t* s)
int run_select(str* res, select_t* s, struct sip_msg* msg)
{
+ int ret, i;
+
if (res == NULL) {
BUG("Select unprepared result space\n");
return -1;
@@ -123,12 +154,17 @@ int run_select(str* res, select_t* s, struct sip_msg* msg)
BUG("Select structure is NULL\n");
return -1;
}
- if (s->f == 0) {
+ if (s->f[0] == 0) {
BUG("Select structure has not been resolved\n");
return -1;
}
-DBG("Calling SELECT %p \n", s->f);
- return s->f(res, s, msg);
+ DBG("Calling SELECT %p \n", s->f);
+
+ ret = 0;
+ for (i=0; (ret == 0) && (s->f[i] !=0 ) && (i<MAX_NESTED_CALLS); i++) {
+ ret = s->f[i](res, s, msg);
+ }
+ return ret;
}
void print_select(select_t* s)
55 select.h
View
@@ -27,6 +27,7 @@
* History:
* --------
* 2005-12-19 select framework (mma)
+ * 2006-01-19 multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
*/
@@ -37,25 +38,52 @@
#include "parser/msg_parser.h"
#define MAX_SELECT_PARAMS 32
+#define MAX_NESTED_CALLS 4
-// Flags for parser table FLAG bitfiels
+/* Flags for parser table FLAG bitfiels
+ */
#define DIVERSION_MASK 0x00FF
-// if DIVERSION is set and the function is accepted and has STR param
-// the param is changed into SEL_PARAM_DIV and the value is set to (flags & DIVERSION_MASK)
+
+/* if DIVERSION is set and the function is accepted
+ * the param is changed into SEL_PARAM_DIV and the value is set to (flags & DIVERSION_MASK)
+ * - it is valuable for STR params (saves parsing time)
+ * - does not release the memory occupied by the parameter
+ */
#define DIVERSION 1<<8
-// if any parameter is expected at this stage
+
+/* set if any parameter is expected at this stage
+ * (the function must be resolved further)
+ */
#define SEL_PARAM_EXPECTED 1<<9
-// accept if following parameter is STR (any)
+
+/* accept if following parameter is STR (any)
+ * consume that extra parameter in one step
+ */
#define CONSUME_NEXT_STR 1<<10
-// accept if following parameter is INT
+
+/* accept if following parameter is INT
+ * consume that extra parameter in one ste
+ */
#define CONSUME_NEXT_INT 1<<11
-// next parameter is optional (use with CONSUME_NEXT_STR or CONSUME_NEXT_INT
+
+/* next parameter is optional (use with CONSUME_NEXT_STR or CONSUME_NEXT_INT
+ * resolution is accepted even if there is no other parameter
+ * or the parameter is of wrong type
+ */
#define OPTIONAL 1<<12
-// if conversion to common alias is needed
-// up-to now parsed function would be stored in parent_f
-// NOTE: the parameter is not consumed for ALIAS,
-// so you can leave it as ..,SEL_PARAM_INT, STR_NULL,..
-#define IS_ALIAS 1<<13
+
+/* left function is noted to be called
+ * rigth function continues in resolution
+ * NOTE: the parameter is not consumed for PARENT,
+ * so you can leave it as ..,SEL_PARAM_INT, 0,..
+ *
+ * run_select then calls all functions with PARENT flag
+ * in the order of resolution until the final call or
+ * the result is != 0 (<0 error, 1 null str)
+ * the only one parameter passed between nested calls
+ * is the result str*
+ */
+#define NESTED 1<<13
/*
* Selector call parameter
@@ -81,8 +109,7 @@ struct select;
typedef int (*select_f)(str* res, struct select* s, struct sip_msg* msg);
typedef struct select {
- select_f f;
- select_f parent_f;
+ select_f f[MAX_NESTED_CALLS];
select_param_t params[MAX_SELECT_PARAMS];
int n;
} select_t;
67 select_core.c
View
@@ -27,6 +27,7 @@
* History:
* --------
* 2005-12-19 select framework, basic core functions (mma)
+ * 2006-01-19 multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
*/
@@ -499,17 +500,8 @@ ABSTRACT_F(select_any_uri)
int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
{
- if (!s->parent_f) {
- ERR("BUG: no parent fuction defined\n");
- return -1;
- }
-
- int ret;
- ret = s->parent_f(res, s, msg);
- if (ret != 0)
- return ret;
-
struct sip_uri uri;
+
trim(res);
if (parse_uri(res->s, res->len, &uri)<0)
return -1;
@@ -531,17 +523,8 @@ int select_uri_type(str* res, select_t* s, struct sip_msg* msg)
int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
{
- if (!s->parent_f) {
- ERR("BUG: no parent fuction defined\n");
- return -1;
- }
-
- int ret;
- ret = s->parent_f(res, s, msg);
- if (ret != 0)
- return ret;
-
struct sip_uri uri;
+
if (parse_uri(res->s, res->len, &uri)<0)
return -1;
@@ -550,17 +533,8 @@ int select_uri_user(str* res, select_t* s, struct sip_msg* msg)
int select_uri_pwd(str* res, select_t* s, struct sip_msg* msg)
{
- if (!s->parent_f) {
- ERR("BUG: no parent fuction defined\n");
- return -1;
- }
-
- int ret;
- ret = s->parent_f(res, s, msg);
- if (ret != 0)
- return ret;
-
struct sip_uri uri;
+
if (parse_uri(res->s, res->len, &uri)<0)
return -1;
@@ -569,17 +543,8 @@ int select_uri_pwd(str* res, select_t* s, struct sip_msg* msg)
int select_uri_host(str* res, select_t* s, struct sip_msg* msg)
{
- if (!s->parent_f) {
- ERR("BUG: no parent fuction defined\n");
- return -1;
- }
-
- int ret;
- ret = s->parent_f(res, s, msg);
- if (ret != 0)
- return ret;
-
struct sip_uri uri;
+
if (parse_uri(res->s, res->len, &uri)<0)
return -1;
@@ -588,17 +553,8 @@ int select_uri_host(str* res, select_t* s, struct sip_msg* msg)
int select_uri_port(str* res, select_t* s, struct sip_msg* msg)
{
- if (!s->parent_f) {
- ERR("BUG: no parent fuction defined\n");
- return -1;
- }
-
- int ret;
- ret = s->parent_f(res, s, msg);
- if (ret != 0)
- return ret;
-
struct sip_uri uri;
+
if (parse_uri(res->s, res->len, &uri)<0)
return -1;
@@ -607,17 +563,8 @@ int select_uri_port(str* res, select_t* s, struct sip_msg* msg)
int select_uri_params(str* res, select_t* s, struct sip_msg* msg)
{
- if (!s->parent_f) {
- ERR("BUG: no parent fuction defined\n");
- return -1;
- }
-
- int ret;
- ret = s->parent_f(res, s, msg);
- if (ret != 0)
- return ret;
-
struct sip_uri uri;
+
if (parse_uri(res->s, res->len, &uri)<0)
return -1;
7 select_core.h
View
@@ -27,6 +27,7 @@
* History:
* --------
* 2005-12-19 select framework, basic core functions (mma)
+ * 2006-01-19 multiple nested calls, IS_ALIAS -> NESTED flag renamed (mma)
*/
@@ -117,9 +118,9 @@ static select_row_t select_core[] = {
{ select_via, SEL_PARAM_STR, STR_STATIC_INIT("alias"), select_via_params_spec, DIVERSION | SEL_PARAM_ALIAS},
{ select_via, SEL_PARAM_STR, STR_STATIC_INIT("params"), select_via_params, CONSUME_NEXT_STR},
- { select_from_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, IS_ALIAS},
- { select_to_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, IS_ALIAS},
- { select_contact_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, IS_ALIAS},
+ { select_from_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, NESTED},
+ { select_to_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, NESTED},
+ { select_contact_uri, SEL_PARAM_INT, STR_NULL, select_any_uri, NESTED},
{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("type"), select_uri_type, 0},
{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("user"), select_uri_user, 0},
{ select_any_uri, SEL_PARAM_STR, STR_STATIC_INIT("pwd"), select_uri_pwd, 0},
Please sign in to comment.
Something went wrong with that request. Please try again.