1 /*
2 * testRegexp.c: simple module for testing regular expressions
3 *
4 * See Copyright for the status of this software.
5 *
6 * Daniel Veillard <veillard@redhat.com>
7 */
8
9 #include "libxml.h"
10 #ifdef LIBXML_AUTOMATA_ENABLED
11 #include <string.h>
12
13 #include <libxml/tree.h>
14 #include <libxml/xmlautomata.h>
15
scanNumber(char ** ptr)16 static int scanNumber(char **ptr) {
17 int ret = 0;
18 char *cur;
19
20 cur = *ptr;
21 while ((*cur >= '0') && (*cur <= '9')) {
22 ret = ret * 10 + (*cur - '0');
23 cur++;
24 }
25 *ptr = cur;
26 return(ret);
27 }
28
29 static void
testRegexpFile(const char * filename)30 testRegexpFile(const char *filename) {
31 FILE *input;
32 char expr[5000];
33 int len;
34 int ret;
35 int i;
36 xmlAutomataPtr am;
37 xmlAutomataStatePtr states[1000];
38 xmlRegexpPtr regexp = NULL;
39 xmlRegExecCtxtPtr exec = NULL;
40
41 for (i = 0;i<1000;i++)
42 states[i] = NULL;
43
44 input = fopen(filename, "r");
45 if (input == NULL) {
46 xmlGenericError(xmlGenericErrorContext,
47 "Cannot open %s for reading\n", filename);
48 return;
49 }
50
51 am = xmlNewAutomata();
52 if (am == NULL) {
53 xmlGenericError(xmlGenericErrorContext,
54 "Cannot create automata\n");
55 fclose(input);
56 return;
57 }
58 states[0] = xmlAutomataGetInitState(am);
59 if (states[0] == NULL) {
60 xmlGenericError(xmlGenericErrorContext,
61 "Cannot get start state\n");
62 xmlFreeAutomata(am);
63 fclose(input);
64 return;
65 }
66 ret = 0;
67
68 while (fgets(expr, 4500, input) != NULL) {
69 if (expr[0] == '#')
70 continue;
71 len = strlen(expr);
72 len--;
73 while ((len >= 0) &&
74 ((expr[len] == '\n') || (expr[len] == '\t') ||
75 (expr[len] == '\r') || (expr[len] == ' '))) len--;
76 expr[len + 1] = 0;
77 if (len >= 0) {
78 if ((am != NULL) && (expr[0] == 't') && (expr[1] == ' ')) {
79 char *ptr = &expr[2];
80 int from, to;
81
82 from = scanNumber(&ptr);
83 if (*ptr != ' ') {
84 xmlGenericError(xmlGenericErrorContext,
85 "Bad line %s\n", expr);
86 break;
87 }
88 if (states[from] == NULL)
89 states[from] = xmlAutomataNewState(am);
90 ptr++;
91 to = scanNumber(&ptr);
92 if (*ptr != ' ') {
93 xmlGenericError(xmlGenericErrorContext,
94 "Bad line %s\n", expr);
95 break;
96 }
97 if (states[to] == NULL)
98 states[to] = xmlAutomataNewState(am);
99 ptr++;
100 xmlAutomataNewTransition(am, states[from], states[to],
101 BAD_CAST ptr, NULL);
102 } else if ((am != NULL) && (expr[0] == 'e') && (expr[1] == ' ')) {
103 char *ptr = &expr[2];
104 int from, to;
105
106 from = scanNumber(&ptr);
107 if (*ptr != ' ') {
108 xmlGenericError(xmlGenericErrorContext,
109 "Bad line %s\n", expr);
110 break;
111 }
112 if (states[from] == NULL)
113 states[from] = xmlAutomataNewState(am);
114 ptr++;
115 to = scanNumber(&ptr);
116 if (states[to] == NULL)
117 states[to] = xmlAutomataNewState(am);
118 xmlAutomataNewEpsilon(am, states[from], states[to]);
119 } else if ((am != NULL) && (expr[0] == 'f') && (expr[1] == ' ')) {
120 char *ptr = &expr[2];
121 int state;
122
123 state = scanNumber(&ptr);
124 if (states[state] == NULL) {
125 xmlGenericError(xmlGenericErrorContext,
126 "Bad state %d : %s\n", state, expr);
127 break;
128 }
129 xmlAutomataSetFinalState(am, states[state]);
130 } else if ((am != NULL) && (expr[0] == 'c') && (expr[1] == ' ')) {
131 char *ptr = &expr[2];
132 int from, to;
133 int min, max;
134
135 from = scanNumber(&ptr);
136 if (*ptr != ' ') {
137 xmlGenericError(xmlGenericErrorContext,
138 "Bad line %s\n", expr);
139 break;
140 }
141 if (states[from] == NULL)
142 states[from] = xmlAutomataNewState(am);
143 ptr++;
144 to = scanNumber(&ptr);
145 if (*ptr != ' ') {
146 xmlGenericError(xmlGenericErrorContext,
147 "Bad line %s\n", expr);
148 break;
149 }
150 if (states[to] == NULL)
151 states[to] = xmlAutomataNewState(am);
152 ptr++;
153 min = scanNumber(&ptr);
154 if (*ptr != ' ') {
155 xmlGenericError(xmlGenericErrorContext,
156 "Bad line %s\n", expr);
157 break;
158 }
159 ptr++;
160 max = scanNumber(&ptr);
161 if (*ptr != ' ') {
162 xmlGenericError(xmlGenericErrorContext,
163 "Bad line %s\n", expr);
164 break;
165 }
166 ptr++;
167 xmlAutomataNewCountTrans(am, states[from], states[to],
168 BAD_CAST ptr, min, max, NULL);
169 } else if ((am != NULL) && (expr[0] == '-') && (expr[1] == '-')) {
170 /* end of the automata */
171 regexp = xmlAutomataCompile(am);
172 xmlFreeAutomata(am);
173 am = NULL;
174 if (regexp == NULL) {
175 xmlGenericError(xmlGenericErrorContext,
176 "Failed to compile the automata");
177 break;
178 }
179 } else if ((expr[0] == '=') && (expr[1] == '>')) {
180 if (regexp == NULL) {
181 printf("=> failed not compiled\n");
182 } else {
183 if (exec == NULL)
184 exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
185 if (ret == 0) {
186 ret = xmlRegExecPushString(exec, NULL, NULL);
187 }
188 if (ret == 1)
189 printf("=> Passed\n");
190 else if ((ret == 0) || (ret == -1))
191 printf("=> Failed\n");
192 else if (ret < 0)
193 printf("=> Error\n");
194 xmlRegFreeExecCtxt(exec);
195 exec = NULL;
196 }
197 ret = 0;
198 } else if (regexp != NULL) {
199 if (exec == NULL)
200 exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
201 ret = xmlRegExecPushString(exec, BAD_CAST expr, NULL);
202 } else {
203 xmlGenericError(xmlGenericErrorContext,
204 "Unexpected line %s\n", expr);
205 }
206 }
207 }
208 fclose(input);
209 if (regexp != NULL)
210 xmlRegFreeRegexp(regexp);
211 if (exec != NULL)
212 xmlRegFreeExecCtxt(exec);
213 if (am != NULL)
214 xmlFreeAutomata(am);
215 }
216
main(int argc,char ** argv)217 int main(int argc, char **argv) {
218
219 xmlInitMemory();
220
221 if (argc == 1) {
222 int ret;
223 xmlAutomataPtr am;
224 xmlAutomataStatePtr start, cur;
225 xmlRegexpPtr regexp;
226 xmlRegExecCtxtPtr exec;
227
228 am = xmlNewAutomata();
229 start = xmlAutomataGetInitState(am);
230
231 /* generate a[ba]*a */
232 cur = xmlAutomataNewTransition(am, start, NULL, BAD_CAST"a", NULL);
233 xmlAutomataNewTransition(am, cur, cur, BAD_CAST"b", NULL);
234 xmlAutomataNewTransition(am, cur, cur, BAD_CAST"a", NULL);
235 cur = xmlAutomataNewCountTrans(am, cur, NULL, BAD_CAST"a", 2, 3, NULL);
236 xmlAutomataSetFinalState(am, cur);
237
238 /* compile it in a regexp and free the automata */
239 regexp = xmlAutomataCompile(am);
240 xmlFreeAutomata(am);
241
242 /* test the regexp */
243 xmlRegexpPrint(stdout, regexp);
244 exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
245 ret = xmlRegExecPushString(exec, BAD_CAST"a", NULL);
246 if (ret == 1)
247 printf("final\n");
248 else if (ret < 0)
249 printf("error\n");
250 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
251 if (ret == 1)
252 printf("final\n");
253 else if (ret < 0)
254 printf("error\n");
255 ret =xmlRegExecPushString(exec, BAD_CAST"b", NULL);
256 if (ret == 1)
257 printf("final\n");
258 else if (ret < 0)
259 printf("error\n");
260 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
261 if (ret == 1)
262 printf("final\n");
263 else if (ret < 0)
264 printf("error\n");
265 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
266 if (ret == 1)
267 printf("final\n");
268 else if (ret < 0)
269 printf("error\n");
270 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
271 if (ret == 1)
272 printf("final\n");
273 else if (ret < 0)
274 printf("error\n");
275 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
276 if (ret == 1)
277 printf("final\n");
278 else if (ret < 0)
279 printf("error\n");
280 if (ret == 0) {
281 ret = xmlRegExecPushString(exec, NULL, NULL);
282 if (ret == 1)
283 printf("final\n");
284 else if (ret < 0)
285 printf("error\n");
286 }
287 xmlRegFreeExecCtxt(exec);
288
289 /* free the regexp */
290 xmlRegFreeRegexp(regexp);
291 } else {
292 int i;
293
294 for (i = 1;i < argc;i++)
295 testRegexpFile(argv[i]);
296 }
297
298 xmlCleanupParser();
299 xmlMemoryDump();
300 return(0);
301 }
302
303 #else
304 #include <stdio.h>
main(int argc ATTRIBUTE_UNUSED,char ** argv ATTRIBUTE_UNUSED)305 int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
306 printf("%s : Automata support not compiled in\n", argv[0]);
307 return(0);
308 }
309 #endif /* LIBXML_AUTOMATA_ENABLED */
310