diff options
Diffstat (limited to 'testRegexp.c')
| -rw-r--r-- | testRegexp.c | 276 |
1 files changed, 253 insertions, 23 deletions
diff --git a/testRegexp.c b/testRegexp.c index 7f34414..ff9c0fc 100644 --- a/testRegexp.c +++ b/testRegexp.c @@ -12,8 +12,8 @@ #include <libxml/tree.h> #include <libxml/xmlregexp.h> -int repeat = 0; -int debug = 0; +static int repeat = 0; +static int debug = 0; static void testRegexp(xmlRegexpPtr comp, const char *value) { int ret; @@ -85,13 +85,194 @@ testRegexpFile(const char *filename) { xmlRegFreeRegexp(comp); } +#ifdef LIBXML_EXPR_ENABLED +static void +runFileTest(xmlExpCtxtPtr ctxt, const char *filename) { + xmlExpNodePtr expr = NULL, sub; + FILE *input; + char expression[5000]; + int len; + + input = fopen(filename, "r"); + if (input == NULL) { + xmlGenericError(xmlGenericErrorContext, + "Cannot open %s for reading\n", filename); + return; + } + while (fgets(expression, 4500, input) != NULL) { + len = strlen(expression); + len--; + while ((len >= 0) && + ((expression[len] == '\n') || (expression[len] == '\t') || + (expression[len] == '\r') || (expression[len] == ' '))) len--; + expression[len + 1] = 0; + if (len >= 0) { + if (expression[0] == '#') + continue; + if ((expression[0] == '=') && (expression[1] == '>')) { + char *str = &expression[2]; + + if (expr != NULL) { + xmlExpFree(ctxt, expr); + if (xmlExpCtxtNbNodes(ctxt) != 0) + printf(" Parse/free of Expression leaked %d\n", + xmlExpCtxtNbNodes(ctxt)); + expr = NULL; + } + printf("Expression: %s\n", str) ; + expr = xmlExpParse(ctxt, str); + if (expr == NULL) { + printf(" parsing Failed\n"); + break; + } + } else if (expr != NULL) { + int expect = -1; + int nodes1, nodes2; + + if (expression[0] == '0') + expect = 0; + if (expression[0] == '1') + expect = 1; + printf("Subexp: %s", expression + 2) ; + nodes1 = xmlExpCtxtNbNodes(ctxt); + sub = xmlExpParse(ctxt, expression + 2); + if (sub == NULL) { + printf(" parsing Failed\n"); + break; + } else { + int ret; + + nodes2 = xmlExpCtxtNbNodes(ctxt); + ret = xmlExpSubsume(ctxt, expr, sub); + + if ((expect == 1) && (ret == 1)) { + printf(" => accept, Ok\n"); + } else if ((expect == 0) && (ret == 0)) { + printf(" => reject, Ok\n"); + } else if ((expect == 1) && (ret == 0)) { + printf(" => reject, Failed\n"); + } else if ((expect == 0) && (ret == 1)) { + printf(" => accept, Failed\n"); + } else { + printf(" => fail internally\n"); + } + if (xmlExpCtxtNbNodes(ctxt) > nodes2) { + printf(" Subsume leaked %d\n", + xmlExpCtxtNbNodes(ctxt) - nodes2); + nodes1 += xmlExpCtxtNbNodes(ctxt) - nodes2; + } + xmlExpFree(ctxt, sub); + if (xmlExpCtxtNbNodes(ctxt) > nodes1) { + printf(" Parse/free leaked %d\n", + xmlExpCtxtNbNodes(ctxt) - nodes1); + } + } + + } + } + } + if (expr != NULL) { + xmlExpFree(ctxt, expr); + if (xmlExpCtxtNbNodes(ctxt) != 0) + printf(" Parse/free of Expression leaked %d\n", + xmlExpCtxtNbNodes(ctxt)); + } + fclose(input); +} + +static void +testReduce(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr, const char *tst) { + xmlBufferPtr xmlExpBuf; + xmlExpNodePtr sub, deriv; + xmlExpBuf = xmlBufferCreate(); + + sub = xmlExpParse(ctxt, tst); + if (sub == NULL) { + printf("Subset %s failed to parse\n", tst); + return; + } + xmlExpDump(xmlExpBuf, sub); + printf("Subset parsed as: %s\n", + (const char *) xmlBufferContent(xmlExpBuf)); + deriv = xmlExpExpDerive(ctxt, expr, sub); + if (deriv == NULL) { + printf("Derivation led to an internal error, report this !\n"); + return; + } else { + xmlBufferEmpty(xmlExpBuf); + xmlExpDump(xmlExpBuf, deriv); + if (xmlExpIsNillable(deriv)) + printf("Resulting nillable derivation: %s\n", + (const char *) xmlBufferContent(xmlExpBuf)); + else + printf("Resulting derivation: %s\n", + (const char *) xmlBufferContent(xmlExpBuf)); + xmlExpFree(ctxt, deriv); + } + xmlExpFree(ctxt, sub); +} + +static void +exprDebug(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr) { + xmlBufferPtr xmlExpBuf; + xmlExpNodePtr deriv; + const char *list[40]; + int ret; + + xmlExpBuf = xmlBufferCreate(); + + if (expr == NULL) { + printf("Failed to parse\n"); + return; + } + xmlExpDump(xmlExpBuf, expr); + printf("Parsed as: %s\n", (const char *) xmlBufferContent(xmlExpBuf)); + printf("Max token input = %d\n", xmlExpMaxToken(expr)); + if (xmlExpIsNillable(expr) == 1) + printf("Is nillable\n"); + ret = xmlExpGetLanguage(ctxt, expr, (const xmlChar **) &list[0], 40); + if (ret < 0) + printf("Failed to get list: %d\n", ret); + else { + int i; + + printf("Language has %d strings, testing string derivations\n", ret); + for (i = 0;i < ret;i++) { + deriv = xmlExpStringDerive(ctxt, expr, BAD_CAST list[i], -1); + if (deriv == NULL) { + printf(" %s -> derivation failed\n", list[i]); + } else { + xmlBufferEmpty(xmlExpBuf); + xmlExpDump(xmlExpBuf, deriv); + printf(" %s -> %s\n", list[i], + (const char *) xmlBufferContent(xmlExpBuf)); + } + xmlExpFree(ctxt, deriv); + } + } + xmlBufferFree(xmlExpBuf); +} +#endif static void usage(const char *name) { - fprintf(stderr, "Usage: %s\n", name); + fprintf(stderr, "Usage: %s [flags]\n", name); + fprintf(stderr, "Testing tool for libxml2 string and pattern regexps\n"); + fprintf(stderr, " --debug: switch on debugging\n"); + fprintf(stderr, " --repeat: loop on the operation\n"); +#ifdef LIBXML_EXPR_ENABLED + fprintf(stderr, " --expr: test xmlExp and not xmlRegexp\n"); +#endif + fprintf(stderr, " --input filename: use the given filename for regexp\n"); + fprintf(stderr, " --input filename: use the given filename for exp\n"); } int main(int argc, char **argv) { xmlRegexpPtr comp = NULL; +#ifdef LIBXML_EXPR_ENABLED + xmlExpNodePtr expr = NULL; + int use_exp = 0; + xmlExpCtxtPtr ctxt = NULL; +#endif const char *pattern = NULL; char *filename = NULL; int i; @@ -113,39 +294,88 @@ int main(int argc, char **argv) { } else if ((!strcmp(argv[i], "-repeat")) || (!strcmp(argv[i], "--repeat"))) { repeat++; - } else if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "--input"))) +#ifdef LIBXML_EXPR_ENABLED + } else if ((!strcmp(argv[i], "-expr")) || + (!strcmp(argv[i], "--expr"))) { + use_exp++; +#endif + } else if ((!strcmp(argv[i], "-i")) || (!strcmp(argv[i], "-f")) || + (!strcmp(argv[i], "--input"))) filename = argv[++i]; else { fprintf(stderr, "Unknown option %s\n", argv[i]); usage(argv[0]); } } + +#ifdef LIBXML_EXPR_ENABLED + if (use_exp) + ctxt = xmlExpNewCtxt(0, NULL); +#endif + if (filename != NULL) { - testRegexpFile(filename); +#ifdef LIBXML_EXPR_ENABLED + if (use_exp) + runFileTest(ctxt, filename); + else +#endif + testRegexpFile(filename); } else { - for (i = 1; i < argc ; i++) { - if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) { - if (pattern == NULL) { - pattern = argv[i]; - printf("Testing %s:\n", pattern); - comp = xmlRegexpCompile((const xmlChar *) pattern); - if (comp == NULL) { - printf(" failed to compile\n"); - break; +#ifdef LIBXML_EXPR_ENABLED + if (use_exp) { + for (i = 1; i < argc ; i++) { + if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) { + if (pattern == NULL) { + pattern = argv[i]; + printf("Testing expr %s:\n", pattern); + expr = xmlExpParse(ctxt, pattern); + if (expr == NULL) { + printf(" failed to compile\n"); + break; + } + if (debug) { + exprDebug(ctxt, expr); + } + } else { + testReduce(ctxt, expr, argv[i]); } - if (debug) - xmlRegexpPrint(stdout, comp); - } else { - testRegexp(comp, argv[i]); } } - } - xmlMemoryDump(); - if (comp != NULL) - xmlRegFreeRegexp(comp); + if (expr != NULL) + xmlExpFree(ctxt, expr); + } else +#endif + { + for (i = 1; i < argc ; i++) { + if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) { + if (pattern == NULL) { + pattern = argv[i]; + printf("Testing %s:\n", pattern); + comp = xmlRegexpCompile((const xmlChar *) pattern); + if (comp == NULL) { + printf(" failed to compile\n"); + break; + } + if (debug) + xmlRegexpPrint(stdout, comp); + } else { + testRegexp(comp, argv[i]); + } + } + } + if (comp != NULL) + xmlRegFreeRegexp(comp); + } + } +#ifdef LIBXML_EXPR_ENABLED + if (ctxt != NULL) { + printf("Ops: %d nodes, %d cons\n", + xmlExpCtxtNbNodes(ctxt), xmlExpCtxtNbCons(ctxt)); + xmlExpFreeCtxt(ctxt); } +#endif xmlCleanupParser(); - /* xmlMemoryDump(); */ + xmlMemoryDump(); return(0); } |
