The conversion to HTML creates proper XHTML.
[xmldoc.git] / xp.c
1 /*
2  * xsltproc.c: user program for the XSL Transformation 1.0 engine
3  *
4  * See Copyright for the status of this software.
5  *
6  * daniel@veillard.com
7  */
8
9 //#include <libxslt/libxslt.h>
10 //#include <libexslt/exslt.h>
11 #include <string.h>
12 #ifdef HAVE_SYS_STAT_H
13 #include <sys/stat.h>
14 #endif
15 #ifdef HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #include <stdlib.h>
19 #ifdef HAVE_STDARG_H
20 #include <stdarg.h>
21 #endif
22 #include <libxml/xmlmemory.h>
23 #include <libxml/debugXML.h>
24 #include <libxml/HTMLtree.h>
25 #include <libxml/xmlIO.h>
26 #ifdef LIBXML_XINCLUDE_ENABLED
27 #include <libxml/xinclude.h>
28 #endif
29 #ifdef LIBXML_CATALOG_ENABLED
30 #include <libxml/catalog.h>
31 #endif
32 #include <libxml/parserInternals.h>
33
34 #include <libxslt/xslt.h>
35 #include <libxslt/xsltInternals.h>
36 #include <libxslt/transform.h>
37 #include <libxslt/xsltutils.h>
38 #include <libxslt/extensions.h>
39
40 #include <libexslt/exsltconfig.h>
41
42
43 #ifndef HAVE_STAT
44 #  ifdef HAVE__STAT
45      /* MS C library seems to define stat and _stat. The definition
46       *         is identical. Still, mapping them to each other causes a warning. */
47 #    ifndef _MSC_VER
48 #      define stat(x,y) _stat(x,y)
49 #    endif
50 #    define HAVE_STAT
51 #  endif
52 #endif
53
54 xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
55                                                const char *ID,
56                                                xmlParserCtxtPtr ctxt);
57
58 static int debug = 0;
59 static int novalid = 0;
60 static int noout = 0;
61 static int latex = 0;
62 #ifdef LIBXML_DOCB_ENABLED
63 static int docbook = 0;
64 #endif
65 #ifdef LIBXML_HTML_ENABLED
66 static int html = 0;
67 #endif
68
69 static const char *params[16 + 1];
70 static int nbparams = 0;
71 static const char *output = NULL;
72
73 void LatexEscape(xmlNodePtr node);
74
75 /*
76  *  The LaTeX translation table. Translate unicodes to LaTeX escape sequences.
77  */
78
79 //#define DEBUG
80
81 struct
82 {
83    int           unicode;
84    unsigned char *sequence;
85 } textab[] =
86 {
87    {  '#',     "\\#"              },
88    {  '$',     "\\$"              },
89    {  '%',     "\\%"              },
90    {  '&',     "\\&"              },
91    {  '<',     "\\verb+<+"        },
92    {  '>',     "\\verb+>+"        },
93    {  '\\',    "$\\backslash$"    },
94    {  '^',     "\\verb+^+"        },
95    {  '_',     "\\_"              },
96    {  '{',     "\\{"              },
97    {  '}',     "\\}"              },
98    {  '~',     "\\verb+~+"        },
99    {  160,     "~"                },
100    {  161,     "!`"               },
101    {  162,     "..."              },
102    {  163,     "\\pounds"         },
103    {  164,     "..."              },
104    {  165,     "..."              },
105    {  166,     "..."              },
106    {  167,     "\\S"              },
107    {  168,     "\\\"{ }"          },
108    {  169,     "\\copyright"      },
109    {  170,     "..."              },
110    {  171,     "..."              },
111    {  172,     "$\\neg$"          },
112    {  173,     "..."              },
113    {  174,     "..."              },
114    {  175,     "\\={ }"           },
115    {  176,     "$^{\\circ}$"      },
116    {  177,     "$\\pm$"           },
117    {  178,     "$^{2}$"           },
118    {  179,     "$^{3}$"           },
119    {  180,     "\\'{ }"           },
120    {  181,     "$\\mu$"           },
121    {  182,     "\\P"              },
122    {  183,     "$\\cdot$"         },
123    {  184,     "\\c{ }"           },
124    {  185,     "$^{1}$"           },
125    {  186,     "..."              },
126    {  187,     "..."              },
127    {  188,     "$\\frac{1}{4}$"   },
128    {  189,     "$\\frac{1}{2}$"   },
129    {  190,     "$\\frac{3}{4}$"   },
130    {  191,     "?`"               },
131    {  192,     "\\`{A}"           },
132    {  193,     "\\'{A}"           },
133    {  194,     "\\^{A}"           },
134    {  195,     "\\~{A}"           },
135    {  196,     "\\\"{A}"          },
136    {  197,     "\\AA"             },
137    {  198,     "\\AE"             },
138    {  199,     "\\c{C}"           },
139    {  200,     "\\`{E}"           },
140    {  201,     "\\'{E}"           },
141    {  202,     "\\^{E}"           },
142    {  203,     "\\\"{E}"          },
143    {  204,     "\\`{I}"           },
144    {  205,     "\\'{I}"           },
145    {  206,     "\\^{I}"           },
146    {  207,     "\\\"{I}"          },
147    {  208,     "..."              },
148    {  209,     "\\~{N}"           },
149    {  210,     "\\`{O}"           },
150    {  211,     "\\'{O}"           },
151    {  212,     "\\^{O}"           },
152    {  213,     "\\~{O}"           },
153    {  214,     "\\\"{O}"          },
154    {  215,     "$\\times$"        },
155    {  216,     "\\O"              },
156    {  217,     "\\`{U}"           },
157    {  218,     "\\'{U}"           },
158    {  219,     "\\^{U}"           },
159    {  220,     "\\\"{U}"          },
160    {  221,     "\\'{Y}"           },
161    {  222,     "..."              },
162    {  223,     "\\ss"             },
163    {  224,     "\\`{a}"           },
164    {  225,     "\\'{a}"           },
165    {  226,     "\\^{a}"           },
166    {  227,     "\\~{a}"           },
167    {  228,     "\\\"{a}"          },
168    {  229,     "\\aa"             },
169    {  230,     "\\ae"             },
170    {  231,     "\\c{c}"           },
171    {  232,     "\\`{e}"           },
172    {  233,     "\\'{e}"           },
173    {  234,     "\\^{e}"           },
174    {  235,     "\\\"{e}"          },
175    {  236,     "\\`{i}"           },
176    {  237,     "\\'{i}"           },
177    {  238,     "\\^{i}"           },
178    {  239,     "\\\"{i}"          },
179    {  240,     "..."              },
180    {  241,     "\\~{n}"           },
181    {  242,     "\\`{o}"           },
182    {  243,     "\\'{o}"           },
183    {  244,     "\\^{o}"           },
184    {  245,     "\\~{o}"           },
185    {  246,     "\\\"{o}"          },
186    {  247,     "$\\div$"          },
187    {  248,     "\\o"              },
188    {  249,     "\\`{u}"           },
189    {  250,     "\\'{u}"           },
190    {  251,     "\\^{u}"           },
191    {  252,     "\\\"{u}"          },
192    {  253,     "\\'{y}"           },
193    {  254,     "..."              },
194    {  255,     "\\\"{y}"          },
195    {  338,     "\\OE"             },
196    {  339,     "\\oe"             },
197    {  352,     "\\u{S}"           },
198    {  353,     "\\u{s}"           },
199    {  376,     "\\\"{Y}"          },
200    {  913,     "A"                },
201    {  914,     "B"                },
202    {  915,     "$\\Gamma$"        },
203    {  916,     "$\\Delta$"        },
204    {  917,     "E"                },
205    {  918,     "Z"                },
206    {  919,     "H"                },
207    {  920,     "$\\Theta$"        },
208    {  921,     "I"                },
209    {  922,     "K"                },
210    {  923,     "$\\Lambda$"       },
211    {  924,     "M"                },
212    {  925,     "N"                },
213    {  926,     "$\\Xi$"           },
214    {  927,     "O"                },
215    {  928,     "$\\Pi$"           },
216    {  929,     "P"                },
217    {  931,     "$\\Sigma$"        },
218    {  932,     "T"                },
219    {  933,     "$\\Upsilon$"      },
220    {  934,     "$\\Phi$"          },
221    {  935,     "X"                },
222    {  936,     "$\\Psi$"          },
223    {  937,     "$\\Omega$"        },
224    {  945,     "$\\alpha$"        },
225    {  946,     "$\\beta$"         },
226    {  947,     "$\\gamma$"        },
227    {  948,     "$\\delta$"        },
228    {  949,     "$\\epsilon$"      },
229    {  950,     "$\\zeta$"         },
230    {  951,     "$\\eta$"          },
231    {  952,     "$\\theta$"        },
232    {  953,     "$\\iota$"         },
233    {  954,     "$\\kappa$"        },
234    {  955,     "$\\lambda$"       },
235    {  956,     "$\\mu$"           },
236    {  957,     "$\\nu$"           },
237    {  958,     "$\\xi$"           },
238    {  959,     "o"                },
239    {  960,     "$\\pi$"           },
240    {  961,     "$\\rho$"          },
241    {  962,     "$\\varsigma$"     },
242    {  963,     "$\\sigma$"        },
243    {  964,     "$\\tau$"          },
244    {  965,     "$\\upsilon$"      },
245    {  966,     "$\\phi$"          },
246    {  967,     "$\\chi$"          },
247    {  968,     "$\\psi$"          },
248    {  969,     "$\\omega$"        },
249    { 8224,     "\\dag"            },
250    { 8225,     "\\ddag"           },
251    { 8226,     "$\\bullet$"       },
252    { 8230,     "$\\ldots$"        },
253    { 8242,     "$\\prime$"        },
254    { 8243,     "$\\prime\\prime$" },
255    { 8254,     "\\={ }"           },
256    { 8364,     "\\EUR"            },
257    { 8465,     "$\\Im$"           },
258    { 8472,     "$\\wp$"           },
259    { 8476,     "$\\Re$"           },
260    { 8482,     "$^{TM}$"          },
261    { 8501,     "$\\aleph$"        },
262    { 8592,     "$\\leftarrow$"    },
263    { 8593,     "$\\uparrow$"      },
264    { 8594,     "$\\rightarrow$"   },
265    { 8595,     "$\\downarrow$"    },
266    { 8596,     "$\\leftrightarrow$" },
267    { 8629,     "$\\hookleftarrow$"},
268    { 8656,     "$\\Leftarrow$"    },
269    { 8657,     "$\\Uparrow$"      },
270    { 8658,     "$\\Rightarrow$"   },
271    { 8659,     "$\\Downarrow$"    },
272    { 8660,     "$\\Leftrightarrow$" },
273    { 8704,     "$\\forall$"       },
274    { 8706,     "$\\partial$"      },
275    { 8707,     "$\\exists$"       },
276    { 8709,     "$\\emptyset$"     },
277    { 8711,     "$\\nabla$"        },
278    { 8712,     "$\\in$"           },
279    { 8713,     "..."              },
280    { 8715,     "$\\ni$"           },
281    { 8719,     "$\\prod$"         },
282    { 8721,     "$\\sum$"          },
283    { 8722,     "$-$"              },
284    { 8727,     "$\\ast$"          },
285    { 8730,     "$\\surd$"         },
286    { 8733,     "$\\propto$"       },
287    { 8734,     "$\\infty$"        },
288    { 8736,     "$\\angle$"        },
289    { 8743,     "$\\wedge$"        },
290    { 8744,     "$\\vee$"          },
291    { 8745,     "$\\cap$"          },
292    { 8746,     "$\\cup$"          },
293    { 8747,     "$\\int$"          },
294    { 8756,     "$\\leadsto$"      },
295    { 8764,     "$\\sim$"          },
296    { 8773,     "$\\cong$"         },
297    { 8776,     "$\\approx$"       },
298    { 8800,     "$\\neq$"          },
299    { 8801,     "$\\equiv$"        },
300    { 8804,     "$\\leq$"          },
301    { 8805,     "$\\geq$"          },
302    { 8834,     "$\\subset$"       },
303    { 8835,     "$\\supset$"       },
304    { 8836,     "..."              },
305    { 8838,     "$\\subseteq$"     },
306    { 8839,     "$\\supseteq$"     },
307    { 8853,     "$\\oplus$"        },
308    { 8855,     "$\\otimes$"       },
309    { 8869,     "$\\perp$"         },
310    { 8901,     "$\\cdot$"         },
311    { 8968,     "$\\lceil$"        },
312    { 8969,     "$\\rceil$"        },
313    { 8970,     "$\\lfloor$"       },
314    { 8971,     "$\\rfloor$"       },
315    { 9001,     "$\\langle$"       },
316    { 9002,     "$\\rangle$"       },
317    { 9674,     "$\\Diamond$"      },
318    { 9824,     "$\\spadesuit$"    },
319    { 9827,     "$\\clubsuit$"     },
320    { 9829,     "$\\heartsuit$"    },
321    { 9830,     "$\\diamondsuit$"  },
322 };
323
324 unsigned char *latex_translate(int code)
325 {
326    char   *translation;
327    int    i;
328
329    translation = 0;
330
331    for (i = 0; translation == 0 && textab[i].unicode <= code
332                && i < sizeof(textab) / sizeof(textab[0]); i++)
333    {
334       if (textab[i].unicode == code)
335       {
336          translation = textab[i].sequence;
337 #ifdef DEBUG
338          fprintf(stderr, "\n*** translation for 0x%04x is %s\n", code, translation);
339 #endif
340       }
341    }
342    return  translation;
343 }
344
345 static void
346 xsltProcess(xmlDocPtr doc, xsltStylesheetPtr cur, const char *filename) {
347     xmlDocPtr res;
348
349     xmlXIncludeProcessFlags(doc, XSLT_PARSE_OPTIONS);
350
351     if (latex)
352     {
353        LatexEscape(xmlDocGetRootElement(doc));
354     }
355
356     if (output == NULL) {
357         res = xsltApplyStylesheet(cur, doc, params);
358
359         xmlFreeDoc(doc);
360         if (res == NULL) {
361             fprintf(stderr, "no result for %s\n", filename);
362             return;
363         }
364         if (noout) {
365             xmlFreeDoc(res);
366             return;
367         }
368 #ifdef LIBXML_DEBUG_ENABLED
369         if (debug)
370             xmlDebugDumpDocument(stdout, res);
371         else {
372 #endif
373             if (cur->methodURI == NULL) {
374                 xsltSaveResultToFile(stdout, res, cur);
375             } else {
376                 if (xmlStrEqual
377                     (cur->method, (const xmlChar *) "xhtml")) {
378                     fprintf(stderr, "non standard output xhtml\n");
379                     xsltSaveResultToFile(stdout, res, cur);
380                 } else {
381                     fprintf(stderr,
382                             "Unsupported non standard output %s\n",
383                             cur->method);
384                     xsltSaveResultToFile(stdout, res, cur);
385                 }
386             }
387 #ifdef LIBXML_DEBUG_ENABLED
388         }
389 #endif
390
391         xmlFreeDoc(res);
392     } else {
393         xsltRunStylesheet(cur, doc, params, output, NULL, NULL);
394         xmlFreeDoc(doc);
395     }
396 }
397
398
399 void LatexEscape(xmlNodePtr node)
400 {
401    xmlNodePtr  child;
402    xmlChar     *byte;
403    int         unicode;
404
405    unsigned char  *translation, *replacement;
406    int            textlen;
407    int            i;
408
409    if (xmlNodeIsText(node))
410    {
411 #ifdef DEBUG
412       fprintf(stderr, "\n-------- Text node at %p (%d bytes):\n%s",
413                       node, strlen(node->content), node->content);
414 #endif
415
416       textlen = strlen(node->content);
417       if (textlen < 100)
418       {
419          textlen = 100;
420       }
421       replacement = malloc(textlen);
422       i           = 0;
423       
424       for (byte = node->content; *byte != '\0'; byte++)
425       {
426          /* transform from utf-8 to unicode */
427
428          if ((*byte & 0x80) == 0)
429          {
430             unicode = *byte;
431          }
432          else if ((*byte & 0xe0) == 0xc0)
433          {
434 #ifdef DEBUG
435             fprintf(stderr, "2-byte unicode: 0x%02x, 0x%02x\n",byte[0], byte[1]);
436 #endif
437             unicode = (*byte & 0x1f) << 6;
438             byte++;
439             unicode |= *byte & 0x3f;
440 #ifdef DEBUG
441             fprintf(stderr, "Unicode = 0x%04x\n", unicode);
442 #endif
443          }
444          else if ((*byte & 0xf0) == 0xe0)
445          {
446              /*  3-byte unicode */
447
448             unicode = (*byte & 0x0f) << 12;
449             byte++;
450             unicode |= (*byte & 0x3f) << 6;
451             byte++;
452             unicode |= *byte & 0x3f;
453          }
454          else
455          {
456             fprintf(stderr, "More than 3 bytes utf-8 is not supported.\n");
457          }
458
459          translation = latex_translate(unicode);
460
461          /*  Append the original byte or the translation to the replacment text */
462
463          if (translation == 0)
464          {
465             if (i + 1 >= textlen)
466             {
467                textlen += 100;
468                replacement = realloc(replacement, textlen);
469             }
470             replacement[i++] = *byte;
471          }
472          else
473          {
474             int   j;
475
476             if (i + strlen(translation) + 1 >= textlen)
477             {
478                textlen += 100;
479                replacement = realloc(replacement, textlen);
480             }
481             for (j = 0; translation[j]; j++)
482             {
483                replacement[i++] = translation[j];
484             } 
485          }
486       }
487       replacement[i] = '\0';
488       xmlNodeSetContent(node, replacement);
489 #ifdef DEBUG
490       fprintf(stderr, "\n-------- Replacement text:\n%s", replacement);
491 #endif
492       free(replacement);
493    }
494    else
495    {
496       for (child = node->children; child != 0; child = child->next)
497       {
498          if (strcmp(child->name, "verbatim") != 0 )
499          {
500             LatexEscape(child);
501          }
502       }
503    }
504 }
505
506 static void usage(const char *name)
507 {
508     printf("Usage: %s [options] stylesheet file [file ...]\n", name);
509     printf("   Options:\n");
510     printf("\t--version or -V: show the version of libxml and libxslt used\n");
511     printf("\t--verbose or -v: show logs of what's happening\n");
512     printf("\t--output file or -o file: save to a given file\n");
513     printf("\t--debug: dump the tree of the result instead\n");
514     printf("\t--latex: transform special characters for latex\n");
515     printf("\t--novalid: skip the Dtd loading phase\n");
516     printf("\t--noout: do not dump the result\n");
517     printf("\t--maxdepth val : increase the maximum depth\n");
518 #ifdef LIBXML_HTML_ENABLED
519     printf("\t--html: the input document is(are) an HTML file(s)\n");
520 #endif
521 #ifdef LIBXML_DOCB_ENABLED
522     printf("\t--docbook: the input document is SGML docbook\n");
523 #endif
524     printf("\t--param name value : pass a (parameter,value) pair\n");
525     printf("\t      string values must be quoted like \"'string'\"\n");
526     printf("\t--nonet refuse to fetch DTDs or entities over network\n");
527 #ifdef LIBXML_CATALOG_ENABLED
528     printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
529     printf("\t             otherwise XML Catalogs starting from \n");
530     printf("\t         file:///etc/xml/catalog are activated by default\n");
531 #endif
532 }
533
534 int
535 main(int argc, char **argv)
536 {
537     int i;
538     xsltStylesheetPtr cur = NULL;
539     xmlDocPtr doc, style;
540
541     if (argc <= 1) {
542         usage(argv[0]);
543         return (1);
544     }
545
546     xmlInitMemory();
547
548     LIBXML_TEST_VERSION
549
550     xmlLineNumbersDefault(1);
551
552     if (novalid == 0)
553         xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
554     else
555         xmlLoadExtDtdDefaultValue = 0;
556     for (i = 1; i < argc; i++) {
557         if (!strcmp(argv[i], "-"))
558             break;
559
560         if (argv[i][0] != '-')
561             continue;
562 #ifdef LIBXML_DEBUG_ENABLED
563         if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) {
564             debug++;
565         } else
566 #endif
567         if ((!strcmp(argv[i], "-v")) ||
568                 (!strcmp(argv[i], "-verbose")) ||
569                 (!strcmp(argv[i], "--verbose"))) {
570             xsltSetGenericDebugFunc(stderr, NULL);
571         } else if ((!strcmp(argv[i], "-o")) ||
572                    (!strcmp(argv[i], "-output")) ||
573                    (!strcmp(argv[i], "--output"))) {
574             i++;
575             output = argv[i++];
576         } else if ((!strcmp(argv[i], "-V")) ||
577                    (!strcmp(argv[i], "-version")) ||
578                    (!strcmp(argv[i], "--version")))
579         {
580
581         } else if ((!strcmp(argv[i], "-novalid")) ||
582                    (!strcmp(argv[i], "--novalid"))) {
583             novalid++;
584         } else if ((!strcmp(argv[i], "-latex")) ||
585                    (!strcmp(argv[i], "--latex"))) {
586             latex++;
587         } else if ((!strcmp(argv[i], "-noout")) ||
588                    (!strcmp(argv[i], "--noout"))) {
589             noout++;
590 #ifdef LIBXML_HTML_ENABLED
591         } else if ((!strcmp(argv[i], "-html")) ||
592                    (!strcmp(argv[i], "--html"))) {
593             html++;
594 #endif
595         } else if ((!strcmp(argv[i], "-nonet")) ||
596                    (!strcmp(argv[i], "--nonet"))) {
597             xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
598 #ifdef LIBXML_CATALOG_ENABLED
599         } else if ((!strcmp(argv[i], "-catalogs")) ||
600                    (!strcmp(argv[i], "--catalogs"))) {
601             const char *catalogs;
602
603             catalogs = getenv("SGML_CATALOG_FILES");
604             if (catalogs == NULL) {
605                 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
606             } else {
607                 xmlLoadCatalogs(catalogs);
608             }
609 #endif
610         } else if ((!strcmp(argv[i], "-param")) ||
611                    (!strcmp(argv[i], "--param"))) {
612             i++;
613             params[nbparams++] = argv[i++];
614             params[nbparams++] = argv[i];
615             if (nbparams >= 16) {
616                 fprintf(stderr, "too many params\n");
617                 return (1);
618             }
619         } else if ((!strcmp(argv[i], "-maxdepth")) ||
620                    (!strcmp(argv[i], "--maxdepth"))) {
621             int value;
622
623             i++;
624             if (sscanf(argv[i], "%d", &value) == 1) {
625                 if (value > 0)
626                     xsltMaxDepth = value;
627             }
628         } else {
629             fprintf(stderr, "Unknown option %s\n", argv[i]);
630             usage(argv[0]);
631             return (1);
632         }
633     }
634     params[nbparams] = NULL;
635
636     xsltSetXIncludeDefault(1);
637     /*
638      * Replace entities with their content.
639      */
640     xmlSubstituteEntitiesDefault(1);
641
642     /*
643      * Register the EXSLT extensions and the test module
644      */
645     exsltRegisterAll();
646     //xsltRegisterTestModule();
647
648     for (i = 1; i < argc; i++) {
649         if ((!strcmp(argv[i], "-maxdepth")) ||
650             (!strcmp(argv[i], "--maxdepth"))) {
651             i++;
652             continue;
653         } else if ((!strcmp(argv[i], "-o")) ||
654                    (!strcmp(argv[i], "-output")) ||
655                    (!strcmp(argv[i], "--output"))) {
656             i++;
657             continue;
658         }
659         if ((!strcmp(argv[i], "-param")) || (!strcmp(argv[i], "--param"))) {
660             i += 2;
661             continue;
662         }
663         if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
664             style = xmlParseFile((const char *) argv[i]);
665             if (style == NULL) {
666                 fprintf(stderr,  "cannot parse %s\n", argv[i]);
667                 cur = NULL;
668             } else {
669                 cur = xsltLoadStylesheetPI(style);
670                 if (cur != NULL) {
671                     /* it is an embedded stylesheet */
672                     xsltProcess(style, cur, argv[i]);
673                     xsltFreeStylesheet(cur);
674                     goto done;
675                 }
676                 cur = xsltParseStylesheetDoc(style);
677                 if (cur != NULL) {
678                     if (cur->indent == 1)
679                         xmlIndentTreeOutput = 1;
680                     else
681                         xmlIndentTreeOutput = 0;
682                     i++;
683                 } else {
684                     xmlFreeDoc(style);
685                     goto done;
686                 }
687             }
688             break;
689
690         }
691     }
692
693     /*
694      * disable CDATA from being built in the document tree
695      */
696     xmlDefaultSAXHandlerInit();
697     xmlDefaultSAXHandler.cdataBlock = NULL;
698
699     if ((cur != NULL) && (cur->errors == 0)) {
700         for (; i < argc; i++) {
701             doc = NULL;
702 #ifdef LIBXML_HTML_ENABLED
703             if (html)
704                 doc = htmlParseFile(argv[i], NULL);
705             else
706 #endif
707                 doc = xmlParseFile(argv[i]);
708             if (doc == NULL) {
709                 fprintf(stderr, "unable to parse %s\n", argv[i]);
710                 continue;
711             }
712             xsltProcess(doc, cur, argv[i]);
713         }
714     }
715     if (cur != NULL)
716         xsltFreeStylesheet(cur);
717 done:
718     //xsltCleanupGlobals();
719     xmlCleanupParser();
720     xmlMemoryDump();
721     return (0);
722 }
723