New script element, Jan's select function framework (@xxx), extended for
[sip-router] / select.c
1 #include "select.h"
2 #include "dprint.h"
3 #include "select_core.h"
4 #include "mem/mem.h"
5
6 /*
7  * The main parser table list placeholder
8  * at startup use core table, modules can
9  * add their own via register_select_table call
10  */
11 static select_table_t *select_list = &select_core_table;
12
13 int resolve_select(select_t* s)
14 {
15         select_f f, pf;
16         int param_idx = 0;
17         int table_idx = 0;
18         select_table_t* t = NULL;;
19         int accept = 0;
20         
21         f = pf = NULL;
22         while (param_idx<s->n) {
23                 accept = 0;
24                 for (t=select_list; t; t=t->next) {
25                         table_idx = 0;  
26                         if (!t->table) continue;
27                         while (t->table[table_idx].curr_f || t->table[table_idx].new_f) {
28                                 if (t->table[table_idx].curr_f == f) {
29                                         if (t->table[table_idx].type == s->params[param_idx].type) {
30                                                 switch (t->table[table_idx].type) {
31                                                 case PARAM_INT:
32                                                         accept = 1;
33                                                         break;
34                                                         case PARAM_STR:
35                                                         accept = (((t->table[table_idx].name.len == s->params[param_idx].v.s.len) || !t->table[table_idx].name.len)
36                                                                    && (!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)));
37                                                         break;
38                                                 default:
39                                                         break;
40                                                 }
41                                         };
42                                         if ((t->table[table_idx].flags & IS_ALIAS)&&(!pf)) {
43                                                 accept = 1;
44                                         }
45                                 }
46                                 if (accept) goto accepted;
47                                 table_idx++;
48                         }
49                 }
50                 goto not_found;
51
52                 accepted:
53                 if (t->table[table_idx].flags & CONSUME_NEXT_STR) {
54                         if ((param_idx<s->n-1) && (s->params[param_idx+1].type == PARAM_STR)) {
55                                 param_idx++;
56                         } else if (!(t->table[table_idx].flags & OPTIONAL)) {
57                                 goto not_found;
58                         }
59                 }
60                 if (t->table[table_idx].flags & CONSUME_NEXT_INT) {
61                         if ((param_idx<s->n-1) && (s->params[param_idx+1].type == PARAM_INT)) {
62                                 param_idx++;
63                         } else if (!(t->table[table_idx].flags & OPTIONAL)) {
64                                 goto not_found;
65                         }
66                 }
67                 if (t->table[table_idx].flags & IS_ALIAS) {
68                         pf = f;
69                 } else {
70                         param_idx++;
71                 }
72                 f = t->table[table_idx].new_f;
73         }
74
75         if (t->table[table_idx].flags & PARAM_EXPECTED) goto not_found;
76         s->f = f;
77         s->parent_f = pf;
78         return 0;
79         
80 not_found:
81         return -1;
82 }
83
84 int run_select(str* res, select_t* s, struct sip_msg* msg)
85 {
86         if (res == NULL) {
87                 BUG("Select unprepared result space\n");
88                 return -1;
89         }
90         if (s == 0) {
91                 BUG("Select structure is NULL\n");
92                 return -1;
93         }
94         if (s->f == 0) {
95                 BUG("Select structure has not been resolved\n");
96                 return -1;
97         }
98 DBG("Calling SELECT %p \n", s->f);
99         return s->f(res, s, msg);
100 }
101
102 void print_select(select_t* s)
103 {
104         int i;
105         DBG("select(");
106         for(i = 0; i < s->n; i++) {
107                 if (s->params[i].type == PARAM_INT) {
108                         DBG("%d,", s->params[i].v.i);
109                 } else {
110                         DBG("%.*s,", s->params[i].v.s.len, s->params[i].v.s.s);
111                 }
112         }
113         DBG(")\n");
114 }
115
116 int register_select_table(select_row_t* mod_tab)
117 {
118         select_table_t* t;
119         t=(select_table_t*)pkg_malloc(sizeof(select_table_t));
120         if (!t) {
121                 ERR("No memory for new select_table structure\n");
122                 return -1;
123         }
124         
125         t->table=mod_tab;
126         t->next=select_list;
127         select_list=t;
128         return 0;
129 }