testAutomata.c 7.5 KB

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