* 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
... | ... |
@@ -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); |