2 * testRegexp.c: simple module for testing regular expressions
4 * See Copyright for the status of this software.
6 * Daniel Veillard <veillard@redhat.com>
11 #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");
57 states
[0] = xmlAutomataGetInitState(am
);
58 if (states
[0] == NULL
) {
59 xmlGenericError(xmlGenericErrorContext
,
60 "Cannot get start state\n");
66 while (fgets(exp
, 4500, input
) != NULL
) {
72 ((exp
[len
] == '\n') || (exp
[len
] == '\t') ||
73 (exp
[len
] == '\r') || (exp
[len
] == ' '))) len
--;
76 if ((am
!= NULL
) && (exp
[0] == 't') && (exp
[1] == ' ')) {
80 from
= scanNumber(&ptr
);
82 xmlGenericError(xmlGenericErrorContext
,
83 "Bad line %s\n", exp
);
86 if (states
[from
] == NULL
)
87 states
[from
] = xmlAutomataNewState(am
);
89 to
= scanNumber(&ptr
);
91 xmlGenericError(xmlGenericErrorContext
,
92 "Bad line %s\n", exp
);
95 if (states
[to
] == NULL
)
96 states
[to
] = xmlAutomataNewState(am
);
98 xmlAutomataNewTransition(am
, states
[from
], states
[to
],
100 } else if ((am
!= NULL
) && (exp
[0] == 'e') && (exp
[1] == ' ')) {
104 from
= scanNumber(&ptr
);
106 xmlGenericError(xmlGenericErrorContext
,
107 "Bad line %s\n", exp
);
110 if (states
[from
] == NULL
)
111 states
[from
] = xmlAutomataNewState(am
);
113 to
= scanNumber(&ptr
);
114 if (states
[to
] == NULL
)
115 states
[to
] = xmlAutomataNewState(am
);
116 xmlAutomataNewEpsilon(am
, states
[from
], states
[to
]);
117 } else if ((am
!= NULL
) && (exp
[0] == 'f') && (exp
[1] == ' ')) {
121 state
= scanNumber(&ptr
);
122 if (states
[state
] == NULL
) {
123 xmlGenericError(xmlGenericErrorContext
,
124 "Bad state %d : %s\n", state
, exp
);
127 xmlAutomataSetFinalState(am
, states
[state
]);
128 } else if ((am
!= NULL
) && (exp
[0] == 'c') && (exp
[1] == ' ')) {
133 from
= scanNumber(&ptr
);
135 xmlGenericError(xmlGenericErrorContext
,
136 "Bad line %s\n", exp
);
139 if (states
[from
] == NULL
)
140 states
[from
] = xmlAutomataNewState(am
);
142 to
= scanNumber(&ptr
);
144 xmlGenericError(xmlGenericErrorContext
,
145 "Bad line %s\n", exp
);
148 if (states
[to
] == NULL
)
149 states
[to
] = xmlAutomataNewState(am
);
151 min
= scanNumber(&ptr
);
153 xmlGenericError(xmlGenericErrorContext
,
154 "Bad line %s\n", exp
);
158 max
= scanNumber(&ptr
);
160 xmlGenericError(xmlGenericErrorContext
,
161 "Bad line %s\n", exp
);
165 xmlAutomataNewCountTrans(am
, states
[from
], states
[to
],
166 BAD_CAST ptr
, min
, max
, NULL
);
167 } else if ((am
!= NULL
) && (exp
[0] == '-') && (exp
[1] == '-')) {
168 /* end of the automata */
169 regexp
= xmlAutomataCompile(am
);
172 if (regexp
== NULL
) {
173 xmlGenericError(xmlGenericErrorContext
,
174 "Failed to compile the automata");
177 } else if ((exp
[0] == '=') && (exp
[1] == '>')) {
178 if (regexp
== NULL
) {
179 printf("=> failed not compiled\n");
182 exec
= xmlRegNewExecCtxt(regexp
, NULL
, NULL
);
184 ret
= xmlRegExecPushString(exec
, NULL
, NULL
);
187 printf("=> Passed\n");
188 else if ((ret
== 0) || (ret
== -1))
189 printf("=> Failed\n");
191 printf("=> Error\n");
192 xmlRegFreeExecCtxt(exec
);
196 } else if (regexp
!= NULL
) {
198 exec
= xmlRegNewExecCtxt(regexp
, NULL
, NULL
);
199 ret
= xmlRegExecPushString(exec
, BAD_CAST exp
, NULL
);
201 xmlGenericError(xmlGenericErrorContext
,
202 "Unexpected line %s\n", exp
);
208 xmlRegFreeRegexp(regexp
);
210 xmlRegFreeExecCtxt(exec
);
215 int main(int argc
, char **argv
) {
222 xmlAutomataStatePtr start
, cur
;
224 xmlRegExecCtxtPtr exec
;
226 am
= xmlNewAutomata();
227 start
= xmlAutomataGetInitState(am
);
229 /* generate a[ba]*a */
230 cur
= xmlAutomataNewTransition(am
, start
, NULL
, BAD_CAST
"a", NULL
);
231 xmlAutomataNewTransition(am
, cur
, cur
, BAD_CAST
"b", NULL
);
232 xmlAutomataNewTransition(am
, cur
, cur
, BAD_CAST
"a", NULL
);
233 cur
= xmlAutomataNewCountTrans(am
, cur
, NULL
, BAD_CAST
"a", 2, 3, NULL
);
234 xmlAutomataSetFinalState(am
, cur
);
236 /* compile it in a regexp and free the automata */
237 regexp
= xmlAutomataCompile(am
);
240 /* test the regexp */
241 xmlRegexpPrint(stdout
, regexp
);
242 exec
= xmlRegNewExecCtxt(regexp
, NULL
, NULL
);
243 ret
= xmlRegExecPushString(exec
, BAD_CAST
"a", NULL
);
248 ret
=xmlRegExecPushString(exec
, BAD_CAST
"a", NULL
);
253 ret
=xmlRegExecPushString(exec
, BAD_CAST
"b", NULL
);
258 ret
=xmlRegExecPushString(exec
, BAD_CAST
"a", NULL
);
263 ret
=xmlRegExecPushString(exec
, BAD_CAST
"a", NULL
);
268 ret
=xmlRegExecPushString(exec
, BAD_CAST
"a", NULL
);
273 ret
=xmlRegExecPushString(exec
, BAD_CAST
"a", NULL
);
279 ret
= xmlRegExecPushString(exec
, NULL
, NULL
);
285 xmlRegFreeExecCtxt(exec
);
287 /* free the regexp */
288 xmlRegFreeRegexp(regexp
);
292 for (i
= 1;i
< argc
;i
++)
293 testRegexpFile(argv
[i
]);
303 int main(int argc
, char **argv
) {
304 printf("%s : Automata support not compiled in\n", argv
[0]);
307 #endif /* LIBXML_AUTOMATA_ENABLED */