2 * testRegexp.c: simple module for testing regular expressions
4 * See Copyright for the status of this software.
6 * Daniel Veillard <veillard@redhat.com>
10 #ifdef LIBXML_AUTOMATA_ENABLED
13 #include <libxml/tree.h>
14 #include <libxml/xmlautomata.h>
16 static int scanNumber(char **ptr) {
21 while ((*cur >= '0') && (*cur <= '9')) {
22 ret = ret * 10 + (*cur - '0');
30 testRegexpFile(const char *filename) {
37 xmlAutomataStatePtr states[1000];
38 xmlRegexpPtr regexp = NULL;
39 xmlRegExecCtxtPtr exec = NULL;
41 for (i = 0;i<1000;i++)
44 input = fopen(filename, "r");
46 xmlGenericError(xmlGenericErrorContext,
47 "Cannot open %s for reading\n", filename);
51 am = xmlNewAutomata();
53 xmlGenericError(xmlGenericErrorContext,
54 "Cannot create automata\n");
58 states[0] = xmlAutomataGetInitState(am);
59 if (states[0] == NULL) {
60 xmlGenericError(xmlGenericErrorContext,
61 "Cannot get start state\n");
68 while (fgets(expr, 4500, input) != NULL) {
74 ((expr[len] == '\n') || (expr[len] == '\t') ||
75 (expr[len] == '\r') || (expr[len] == ' '))) len--;
78 if ((am != NULL) && (expr[0] == 't') && (expr[1] == ' ')) {
82 from = scanNumber(&ptr);
84 xmlGenericError(xmlGenericErrorContext,
85 "Bad line %s\n", expr);
88 if (states[from] == NULL)
89 states[from] = xmlAutomataNewState(am);
91 to = scanNumber(&ptr);
93 xmlGenericError(xmlGenericErrorContext,
94 "Bad line %s\n", expr);
97 if (states[to] == NULL)
98 states[to] = xmlAutomataNewState(am);
100 xmlAutomataNewTransition(am, states[from], states[to],
102 } else if ((am != NULL) && (expr[0] == 'e') && (expr[1] == ' ')) {
103 char *ptr = &expr[2];
106 from = scanNumber(&ptr);
108 xmlGenericError(xmlGenericErrorContext,
109 "Bad line %s\n", expr);
112 if (states[from] == NULL)
113 states[from] = xmlAutomataNewState(am);
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];
123 state = scanNumber(&ptr);
124 if (states[state] == NULL) {
125 xmlGenericError(xmlGenericErrorContext,
126 "Bad state %d : %s\n", state, expr);
129 xmlAutomataSetFinalState(am, states[state]);
130 } else if ((am != NULL) && (expr[0] == 'c') && (expr[1] == ' ')) {
131 char *ptr = &expr[2];
135 from = scanNumber(&ptr);
137 xmlGenericError(xmlGenericErrorContext,
138 "Bad line %s\n", expr);
141 if (states[from] == NULL)
142 states[from] = xmlAutomataNewState(am);
144 to = scanNumber(&ptr);
146 xmlGenericError(xmlGenericErrorContext,
147 "Bad line %s\n", expr);
150 if (states[to] == NULL)
151 states[to] = xmlAutomataNewState(am);
153 min = scanNumber(&ptr);
155 xmlGenericError(xmlGenericErrorContext,
156 "Bad line %s\n", expr);
160 max = scanNumber(&ptr);
162 xmlGenericError(xmlGenericErrorContext,
163 "Bad line %s\n", expr);
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);
174 if (regexp == NULL) {
175 xmlGenericError(xmlGenericErrorContext,
176 "Failed to compile the automata");
179 } else if ((expr[0] == '=') && (expr[1] == '>')) {
180 if (regexp == NULL) {
181 printf("=> failed not compiled\n");
184 exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
186 ret = xmlRegExecPushString(exec, NULL, NULL);
189 printf("=> Passed\n");
190 else if ((ret == 0) || (ret == -1))
191 printf("=> Failed\n");
193 printf("=> Error\n");
194 xmlRegFreeExecCtxt(exec);
198 } else if (regexp != NULL) {
200 exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
201 ret = xmlRegExecPushString(exec, BAD_CAST expr, NULL);
203 xmlGenericError(xmlGenericErrorContext,
204 "Unexpected line %s\n", expr);
210 xmlRegFreeRegexp(regexp);
212 xmlRegFreeExecCtxt(exec);
217 int main(int argc, char **argv) {
224 xmlAutomataStatePtr start, cur;
226 xmlRegExecCtxtPtr exec;
228 am = xmlNewAutomata();
229 start = xmlAutomataGetInitState(am);
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);
238 /* compile it in a regexp and free the automata */
239 regexp = xmlAutomataCompile(am);
242 /* test the regexp */
243 xmlRegexpPrint(stdout, regexp);
244 exec = xmlRegNewExecCtxt(regexp, NULL, NULL);
245 ret = xmlRegExecPushString(exec, BAD_CAST"a", NULL);
250 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
255 ret =xmlRegExecPushString(exec, BAD_CAST"b", NULL);
260 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
265 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
270 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
275 ret =xmlRegExecPushString(exec, BAD_CAST"a", NULL);
281 ret = xmlRegExecPushString(exec, NULL, NULL);
287 xmlRegFreeExecCtxt(exec);
289 /* free the regexp */
290 xmlRegFreeRegexp(regexp);
294 for (i = 1;i < argc;i++)
295 testRegexpFile(argv[i]);
305 int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
306 printf("%s : Automata support not compiled in\n", argv[0]);
309 #endif /* LIBXML_AUTOMATA_ENABLED */