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