fixed #129327 make sure parser flags get transmitted to the transformation
[platform/upstream/libxslt.git] / xsltproc / xsltproc.c
index 2db74f2..6131381 100644 (file)
 #include <libxml/debugXML.h>
 #include <libxml/HTMLtree.h>
 #include <libxml/xmlIO.h>
-#ifdef LIBXML_DOCB_ENABLED
-#include <libxml/DOCBparser.h>
-#endif
 #ifdef LIBXML_XINCLUDE_ENABLED
 #include <libxml/xinclude.h>
 #endif
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
+#include <libxml/parser.h>
 #include <libxml/parserInternals.h>
 #include <libxml/uri.h>
 
@@ -56,9 +54,8 @@
 #include <libexslt/exsltconfig.h>
 
 #if defined(WIN32) && !defined (__CYGWIN__)
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__MINGW32__)
 #include <winsock2.h>
-#pragma comment(lib, "ws2_32.lib")
 #define gettimeofday(p1,p2)
 #define HAVE_TIME_H
 #include <time.h>
 #endif
 #endif /* WIN32 */
 
+#ifdef HAVE_SYS_TIMEB_H
+#include <sys/timeb.h>
+#endif
+
 #ifndef HAVE_STAT
 #  ifdef HAVE__STAT
      /* MS C library seems to define stat and _stat. The definition
 #  endif
 #endif
 
-xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
-                                              const char *ID,
-                                              xmlParserCtxtPtr ctxt);
-
 static int debug = 0;
 static int repeat = 0;
 static int timing = 0;
 static int dumpextensions = 0;
 static int novalid = 0;
 static int noout = 0;
-#ifdef LIBXML_DOCB_ENABLED
-static int docbook = 0;
-#endif
 #ifdef LIBXML_HTML_ENABLED
 static int html = 0;
 #endif
+static int load_trace = 0;
 #ifdef LIBXML_XINCLUDE_ENABLED
 static int xinclude = 0;
 #endif
@@ -109,13 +104,16 @@ static int profile = 0;
 #define MAX_PARAMETERS 64
 #define MAX_PATHS 64
 
+#if LIBXML_VERSION >= 20600
+static int options = XSLT_PARSE_OPTIONS;
+#endif
 static const char *params[MAX_PARAMETERS + 1];
 static int nbparams = 0;
 static xmlChar *strparams[MAX_PARAMETERS + 1];
 static int nbstrparams = 0;
 static xmlChar *paths[MAX_PATHS + 1];
 static int nbpaths = 0;
-static const char *output = NULL;
+static char *output = NULL;
 static int errorno = 0;
 static const char *writesubtree = NULL;
 
@@ -157,6 +155,16 @@ xsltprocExternalEntityLoader(const char *URL, const char *ID,
     warningSAXFunc warning = NULL;
 
     int i;
+    const char *lastsegment = URL;
+    const char *iter = URL;
+
+    if (nbpaths > 0) {
+       while (*iter != 0) {
+           if (*iter == '/')
+               lastsegment = iter + 1;
+           iter++;
+       }
+    }
 
     if ((ctxt != NULL) && (ctxt->sax != NULL)) {
        warning = ctxt->sax->warning;
@@ -168,24 +176,38 @@ xsltprocExternalEntityLoader(const char *URL, const char *ID,
        if (ret != NULL) {
            if (warning != NULL)
                ctxt->sax->warning = warning;
+           if (load_trace) {
+               fprintf \
+                       (stderr,
+                        "Loaded URL=\"%s\" ID=\"%s\"\n",
+                        URL ? URL : "(null)",
+                        ID ? ID : "(null)");
+           }
            return(ret);
        }
     }
     for (i = 0;i < nbpaths;i++) {
        xmlChar *newURL;
-       int len;
 
-       len = xmlStrlen(paths[i]) + xmlStrlen(BAD_CAST URL) + 5;
-       newURL = xmlMalloc(len);
+       newURL = xmlStrdup((const xmlChar *) paths[i]);
+       newURL = xmlStrcat(newURL, (const xmlChar *) "/");
+       newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
        if (newURL != NULL) {
-           snprintf(newURL, len, "%s/%s", paths[i], URL);
            ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
-           xmlFree(newURL);
            if (ret != NULL) {
                if (warning != NULL)
                    ctxt->sax->warning = warning;
+               if (load_trace) {
+                   fprintf \
+                       (stderr,
+                        "Loaded URL=\"%s\" ID=\"%s\"\n",
+                        newURL,
+                        ID ? ID : "(null)");
+               }
+               xmlFree(newURL);
                return(ret);
            }
+           xmlFree(newURL);
        }
     }
     if (warning != NULL) {
@@ -352,7 +374,11 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
     if (xinclude) {
        if (timing)
            startTimer();
+#if LIBXML_VERSION >= 20603
+       xmlXIncludeProcessFlags(doc, XSLT_PARSE_OPTIONS);
+#else
        xmlXIncludeProcess(doc);
+#endif
        if (timing) {
            endTimer("XInclude processing %s", filename);
        }
@@ -368,22 +394,27 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
                res = xsltApplyStylesheet(cur, doc, params);
                xmlFreeDoc(res);
                xmlFreeDoc(doc);
+#if LIBXML_VERSION >= 20600
 #ifdef LIBXML_HTML_ENABLED
                if (html)
-                   doc = htmlParseFile(filename, NULL);
+                   doc = htmlReadFile(filename, NULL, options);
                else
 #endif
-#ifdef LIBXML_DOCB_ENABLED
-               if (docbook)
-                   doc = docbParseFile(filename, NULL);
+                   doc = xmlReadFile(filename, NULL, options);
+#else
+#ifdef LIBXML_HTML_ENABLED
+               if (html)
+                   doc = htmlParseFile(filename, NULL);
                else
 #endif
                    doc = xmlParseFile(filename);
+#endif
            }
        }
        ctxt = xsltNewTransformContext(cur, doc);
        if (ctxt == NULL)
            return;
+       xsltSetCtxtParseOptions(ctxt, options);
        if (profile) {
            res = xsltApplyStylesheetUser(cur, doc, params, NULL,
                                          stderr, ctxt);
@@ -444,16 +475,15 @@ xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
 
        xmlFreeDoc(res);
     } else {
-       int ret;
 
        ctxt = xsltNewTransformContext(cur, doc);
        if (ctxt == NULL)
            return;
        if (profile) {
-           ret = xsltRunStylesheetUser(cur, doc, params, output,
+           xsltRunStylesheetUser(cur, doc, params, output,
                                        NULL, NULL, stderr, ctxt);
        } else {
-           ret = xsltRunStylesheetUser(cur, doc, params, output,
+           xsltRunStylesheetUser(cur, doc, params, output,
                                        NULL, NULL, NULL, ctxt);
        }
        if (ctxt->state == XSLT_STATE_ERROR)
@@ -473,17 +503,19 @@ static void usage(const char *name) {
     printf("\t--output file or -o file: save to a given file\n");
     printf("\t--timing: display the time used\n");
     printf("\t--repeat: run the transformation 20 times\n");
+#ifdef LIBXML_DEBUG_ENABLED
     printf("\t--debug: dump the tree of the result instead\n");
+#endif
     printf("\t--dumpextensions: dump the registered extension elements and functions to stdout\n");
     printf("\t--novalid skip the Dtd loading phase\n");
     printf("\t--noout: do not dump the result\n");
     printf("\t--maxdepth val : increase the maximum depth\n");
+#if LIBXML_VERSION >= 20600
+    printf("\t--maxparserdepth val : increase the maximum parser depth\n");
+#endif
 #ifdef LIBXML_HTML_ENABLED
     printf("\t--html: the input document is(are) an HTML file(s)\n");
 #endif
-#ifdef LIBXML_DOCB_ENABLED
-    printf("\t--docbook: the input document is SGML docbook\n");
-#endif
     printf("\t--param name value : pass a (parameter,value) pair\n");
     printf("\t       value is an UTF8 XPath expression.\n");
     printf("\t       string values must be quoted like \"'string'\"\n or");
@@ -502,6 +534,7 @@ static void usage(const char *name) {
 #ifdef LIBXML_XINCLUDE_ENABLED
     printf("\t--xinclude : do XInclude processing on document intput\n");
 #endif
+    printf("\t--load-trace : print trace of all external entites loaded\n");
     printf("\t--profile or --norman : dump profiling informations \n");
     printf("\nProject libxslt home page: http://xmlsoft.org/XSLT/\n");
     printf("To report bugs and get help: http://xmlsoft.org/XSLT/bugs.html\n");
@@ -524,7 +557,6 @@ main(int argc, char **argv)
 
     LIBXML_TEST_VERSION
 
-    xmlLineNumbersDefault(1);
     sec = xsltNewSecurityPrefs();
     xsltSetDefaultSecurityPrefs(sec);
     defaultEntityLoader = xmlGetExternalEntityLoader();
@@ -549,7 +581,11 @@ main(int argc, char **argv)
                    (!strcmp(argv[i], "-output")) ||
                    (!strcmp(argv[i], "--output"))) {
             i++;
-            output = argv[i];
+#if defined(WIN32) || defined (__CYGWIN__)
+           output = xmlCanonicPath(argv[i]);
+            if (output == NULL)
+#endif
+               output = (char *) xmlStrdup((xmlChar *) argv[i]);
         } else if ((!strcmp(argv[i], "-V")) ||
                    (!strcmp(argv[i], "-version")) ||
                    (!strcmp(argv[i], "--version"))) {
@@ -574,11 +610,6 @@ main(int argc, char **argv)
         } else if ((!strcmp(argv[i], "-noout")) ||
                    (!strcmp(argv[i], "--noout"))) {
             noout++;
-#ifdef LIBXML_DOCB_ENABLED
-        } else if ((!strcmp(argv[i], "-docbook")) ||
-                   (!strcmp(argv[i], "--docbook"))) {
-            docbook++;
-#endif
 #ifdef LIBXML_HTML_ENABLED
         } else if ((!strcmp(argv[i], "-html")) ||
                    (!strcmp(argv[i], "--html"))) {
@@ -636,6 +667,9 @@ main(int argc, char **argv)
             xinclude++;
             xsltSetXIncludeDefault(1);
 #endif
+        } else if ((!strcmp(argv[i], "-load-trace")) ||
+                   (!strcmp(argv[i], "--load-trace"))) {
+            load_trace++;
         } else if ((!strcmp(argv[i], "-param")) ||
                    (!strcmp(argv[i], "--param"))) {
             i++;
@@ -649,12 +683,10 @@ main(int argc, char **argv)
                    (!strcmp(argv[i], "--stringparam"))) {
            const xmlChar *string;
            xmlChar *value;
-           int len;
 
             i++;
             params[nbparams++] = argv[i++];
            string = (const xmlChar *) argv[i];
-           len = xmlStrlen(string);
            if (xmlStrchr(string, '"')) {
                if (xmlStrchr(string, '\'')) {
                    fprintf(stderr,
@@ -685,6 +717,17 @@ main(int argc, char **argv)
                 if (value > 0)
                     xsltMaxDepth = value;
             }
+#if LIBXML_VERSION >= 20600
+        } else if ((!strcmp(argv[i], "-maxparserdepth")) ||
+                   (!strcmp(argv[i], "--maxparserdepth"))) {
+            int value;
+
+            i++;
+            if (sscanf(argv[i], "%d", &value) == 1) {
+                if (value > 0)
+                    xmlParserMaxDepth = value;
+            }
+#endif
         } else if ((!strcmp(argv[i],"-dumpextensions"))||
                        (!strcmp(argv[i],"--dumpextensions"))) {
                dumpextensions++;
@@ -697,16 +740,20 @@ main(int argc, char **argv)
     }
     params[nbparams] = NULL;
 
+#if LIBXML_VERSION < 20600
+    /*
+     * The old parser interfaces uses the global variables
+     */
     if (novalid == 0)
         xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
     else
         xmlLoadExtDtdDefaultValue = 0;
-
-
-    /*
-     * Replace entities with their content.
-     */
     xmlSubstituteEntitiesDefault(1);
+    xmlLineNumbersDefault(1);
+#else
+    if (novalid != 0)
+       options = XML_PARSE_NOENT | XML_PARSE_NOCDATA;
+#endif
 
     /*
      * Register the EXSLT extensions and the test module
@@ -722,6 +769,12 @@ main(int argc, char **argv)
             (!strcmp(argv[i], "--maxdepth"))) {
             i++;
             continue;
+#if LIBXML_VERSION >= 20600
+        } else if ((!strcmp(argv[i], "-maxparserdepth")) ||
+            (!strcmp(argv[i], "--maxparserdepth"))) {
+            i++;
+            continue;
+#endif
         } else if ((!strcmp(argv[i], "-o")) ||
                    (!strcmp(argv[i], "-output")) ||
                    (!strcmp(argv[i], "--output"))) {
@@ -748,7 +801,11 @@ main(int argc, char **argv)
         if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
             if (timing)
                 startTimer();
+#if LIBXML_VERSION >= 20600
+           style = xmlReadFile((const char *) argv[i], NULL, options);
+#else
            style = xmlParseFile((const char *) argv[i]);
+#endif
             if (timing) 
                endTimer("Parsing stylesheet %s", argv[i]);
            if (style == NULL) {
@@ -761,6 +818,7 @@ main(int argc, char **argv)
                    /* it is an embedded stylesheet */
                    xsltProcess(style, cur, argv[i]);
                    xsltFreeStylesheet(cur);
+                   cur = NULL;
                    goto done;
                }
                cur = xsltParseStylesheetDoc(style);
@@ -769,10 +827,6 @@ main(int argc, char **argv)
                        errorno = 5;
                        goto done;
                    }
-                   if (cur->indent == 1)
-                       xmlIndentTreeOutput = 1;
-                   else
-                       xmlIndentTreeOutput = 0;
                    i++;
                } else {
                    xmlFreeDoc(style);
@@ -785,28 +839,35 @@ main(int argc, char **argv)
         }
     }
 
+#if LIBXML_VERSION < 20600
     /*
+     * The old parser interfaces uses the global variables
      * disable CDATA from being built in the document tree
      */
     xmlDefaultSAXHandlerInit();
     xmlDefaultSAXHandler.cdataBlock = NULL;
+#endif
 
     if ((cur != NULL) && (cur->errors == 0)) {
         for (; i < argc; i++) {
            doc = NULL;
             if (timing)
                 startTimer();
+#if LIBXML_VERSION >= 20600
 #ifdef LIBXML_HTML_ENABLED
             if (html)
-                doc = htmlParseFile(argv[i], NULL);
+                doc = htmlReadFile(argv[i], NULL, options);
             else
 #endif
-#ifdef LIBXML_DOCB_ENABLED
-            if (docbook)
-                doc = docbParseFile(argv[i], NULL);
+                doc = xmlReadFile(argv[i], NULL, options);
+#else
+#ifdef LIBXML_HTML_ENABLED
+            if (html)
+                doc = htmlParseFile(argv[i], NULL);
             else
 #endif
                 doc = xmlParseFile(argv[i]);
+#endif
             if (doc == NULL) {
                 fprintf(stderr, "unable to parse %s\n", argv[i]);
                errorno = 6;
@@ -817,17 +878,17 @@ main(int argc, char **argv)
            xsltProcess(doc, cur, argv[i]);
         }
     }
+done:
     if (cur != NULL)
         xsltFreeStylesheet(cur);
     for (i = 0;i < nbstrparams;i++)
        xmlFree(strparams[i]);
-done:
+    if (output != NULL)
+       xmlFree(output);
+    xsltFreeSecurityPrefs(sec);
     xsltCleanupGlobals();
     xmlCleanupParser();
-#if 0
     xmlMemoryDump();
-#endif
-    xsltFreeSecurityPrefs(sec);
     return(errorno);
 }