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