Browse code

Kamailio compatibility: parse_repl

* Move the replace parser into a separate function called parse_repl
* Declare the function in the header file
* Add support for PV_MARKER (pseudo-variable marker $) to the parser

Jan Janak authored on 08/03/2009 03:16:08
Showing 2 changed files
... ...
@@ -64,12 +64,143 @@ void replace_lst_free(struct replace_lst* l)
64 64
 	}
65 65
 }
66 66
 
67
+int parse_repl(struct replace_with * rw, char ** begin, 
68
+				char * end, int *max_token_nb, int with_sep)
69
+{
70
+
71
+	char* p0;
72
+	char * repl;
73
+	str s;
74
+	int token_nb;
75
+	int escape;
76
+	int max_pmatch;
77
+	char *p, c;
78
+
79
+	/* parse replacement */
80
+	p = *begin;
81
+	c = *p;
82
+	if(with_sep)
83
+		p++;
84
+	repl= p;
85
+	token_nb=0;
86
+	max_pmatch=0;
87
+	escape=0;
88
+	for(;p<end; p++){
89
+		if (escape){
90
+			escape=0;
91
+			switch (*p){
92
+				/* special char escapes */
93
+				case '\\':
94
+					rw[token_nb].size=2;
95
+					rw[token_nb].offset=(p-1)-repl;
96
+					rw[token_nb].type=REPLACE_CHAR;
97
+					rw[token_nb].u.c='\\';
98
+					break;
99
+				case 'n':
100
+					rw[token_nb].size=2;
101
+					rw[token_nb].offset=(p-1)-repl;
102
+					rw[token_nb].type=REPLACE_CHAR;
103
+					rw[token_nb].u.c='\n';
104
+					break;
105
+				case 'r':
106
+					rw[token_nb].size=2;
107
+					rw[token_nb].offset=(p-1)-repl;
108
+					rw[token_nb].type=REPLACE_CHAR;
109
+					rw[token_nb].u.c='\r';
110
+					break;
111
+				case 't':
112
+					rw[token_nb].size=2;
113
+					rw[token_nb].offset=(p-1)-repl;
114
+					rw[token_nb].type=REPLACE_CHAR;
115
+					rw[token_nb].u.c='\t';
116
+					break;
117
+				case PV_MARKER:
118
+					rw[token_nb].size=2;
119
+					rw[token_nb].offset=(p-1)-repl;
120
+					rw[token_nb].type=REPLACE_CHAR;
121
+					rw[token_nb].u.c=PV_MARKER;
122
+					break;
123
+				/* special sip msg parts escapes */
124
+				case 'u':
125
+					rw[token_nb].size=2;
126
+					rw[token_nb].offset=(p-1)-repl;
127
+					rw[token_nb].type=REPLACE_URI;
128
+					break;
129
+				/* re matches */
130
+				case '0': /* allow 0, too, reference to the whole match */
131
+				case '1':
132
+				case '2':
133
+				case '3':
134
+				case '4':
135
+				case '5':
136
+				case '6':
137
+				case '7':
138
+				case '8':
139
+				case '9':
140
+					rw[token_nb].size=2;
141
+					rw[token_nb].offset=(p-1)-repl;
142
+					rw[token_nb].type=REPLACE_NMATCH;
143
+					rw[token_nb].u.nmatch=(*p)-'0';
144
+								/* 0 is the whole matched str*/
145
+					if (max_pmatch<rw[token_nb].u.nmatch) 
146
+						max_pmatch=rw[token_nb].u.nmatch;
147
+					break;
148
+				default: /* just print current char */
149
+					if (*p!=c){
150
+						WARN("subst_parser:\\%c unknown escape in %s\n", *p, *begin);
151
+					}
152
+					rw[token_nb].size=2;
153
+					rw[token_nb].offset=(p-1)-repl;
154
+					rw[token_nb].type=REPLACE_CHAR;
155
+					rw[token_nb].u.c=*p;
156
+					break;
157
+			}
158
+
159
+			token_nb++;
160
+
161
+			if (token_nb>=MAX_REPLACE_WITH){
162
+				ERR("subst_parser: too many escapes in the replace part %s\n", *begin);
163
+				goto error;
164
+			}
165
+		}else if (*p=='\\') {
166
+			escape=1;
167
+		}else if (*p==PV_MARKER) {
168
+			s.s = p;
169
+			s.len = end - s.s;
170
+			p0 = pv_parse_spec(&s, &rw[token_nb].u.spec);
171
+			if(p0==NULL)
172
+			{
173
+				ERR("subst_parser: bad specifier in replace part %s\n", *begin);
174
+				goto error;
175
+			}
176
+			rw[token_nb].size=p0-p;
177
+			rw[token_nb].offset=p-repl;
178
+			rw[token_nb].type=REPLACE_SPEC;
179
+			token_nb++;
180
+			p=p0-1;
181
+		}else  if (*p==c && with_sep){
182
+				goto found_repl;
183
+		}
184
+	}
185
+	if(with_sep){
186
+		ERR("subst_parser: missing separator: %s\n", *begin);
187
+		goto error;
188
+	}
189
+
190
+found_repl:
191
+
192
+	*max_token_nb = max_pmatch;
193
+	*begin = p;
194
+	return token_nb;
195
+
196
+error:
197
+	return -1;
198
+}
67 199
 
68 200
 
69 201
 /* parse a /regular expression/replacement/flags into a subst_expr structure */
70 202
 struct subst_expr* subst_parser(str* subst)
71 203
 {
72
-#define MAX_REPLACE_WITH 100
73 204
 	char c;
74 205
 	char* end;
75 206
 	char* p;
... ...
@@ -79,6 +79,8 @@ struct replace_lst{
79 79
 
80 80
 void subst_expr_free(struct subst_expr* se);
81 81
 void replace_lst_free(struct replace_lst* l);
82
+int parse_repl(struct replace_with * rw, char ** begin, 
83
+				char * end, int *max_token_nb, int flag);
82 84
 struct subst_expr*  subst_parser(str* subst);
83 85
 struct replace_lst* subst_run( struct subst_expr* se, const char* input, 
84 86
 		                       struct sip_msg* msg, int *count);