ReactOS 0.4.15-dev-7918-g2a2556c
debugXML.c
Go to the documentation of this file.
1/*
2 * debugXML.c : This is a set of routines used for debugging the tree
3 * produced by the XML parser.
4 *
5 * See Copyright for the status of this software.
6 *
7 * Daniel Veillard <daniel@veillard.com>
8 */
9
10#define IN_LIBXML
11#include "libxml.h"
12#ifdef LIBXML_DEBUG_ENABLED
13
14#include <string.h>
15#include <stdlib.h>
16
17#include <libxml/xmlmemory.h>
18#include <libxml/tree.h>
19#include <libxml/parser.h>
21#include <libxml/valid.h>
22#include <libxml/debugXML.h>
23#include <libxml/HTMLtree.h>
24#include <libxml/HTMLparser.h>
25#include <libxml/xmlerror.h>
26#include <libxml/globals.h>
28#include <libxml/uri.h>
29#ifdef LIBXML_SCHEMAS_ENABLED
30#include <libxml/relaxng.h>
31#endif
32
33#define DUMP_TEXT_TYPE 1
34
35typedef struct _xmlDebugCtxt xmlDebugCtxt;
36typedef xmlDebugCtxt *xmlDebugCtxtPtr;
37struct _xmlDebugCtxt {
38 FILE *output; /* the output file */
39 char shift[101]; /* used for indenting */
40 int depth; /* current depth */
41 xmlDocPtr doc; /* current document */
42 xmlNodePtr node; /* current node */
43 xmlDictPtr dict; /* the doc dictionary */
44 int check; /* do just checkings */
45 int errors; /* number of errors found */
46 int nodict; /* if the document has no dictionary */
47 int options; /* options */
48};
49
50static void xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node);
51
52static void
53xmlCtxtDumpInitCtxt(xmlDebugCtxtPtr ctxt)
54{
55 int i;
56
57 ctxt->depth = 0;
58 ctxt->check = 0;
59 ctxt->errors = 0;
60 ctxt->output = stdout;
61 ctxt->doc = NULL;
62 ctxt->node = NULL;
63 ctxt->dict = NULL;
64 ctxt->nodict = 0;
65 ctxt->options = 0;
66 for (i = 0; i < 100; i++)
67 ctxt->shift[i] = ' ';
68 ctxt->shift[100] = 0;
69}
70
71static void
72xmlCtxtDumpCleanCtxt(xmlDebugCtxtPtr ctxt ATTRIBUTE_UNUSED)
73{
74 /* remove the ATTRIBUTE_UNUSED when this is added */
75}
76
88static int
89xmlNsCheckScope(xmlNodePtr node, xmlNsPtr ns)
90{
92
93 if ((node == NULL) || (ns == NULL))
94 return(-1);
95
96 if ((node->type != XML_ELEMENT_NODE) &&
97 (node->type != XML_ATTRIBUTE_NODE) &&
98 (node->type != XML_DOCUMENT_NODE) &&
99 (node->type != XML_TEXT_NODE) &&
100 (node->type != XML_HTML_DOCUMENT_NODE) &&
101 (node->type != XML_XINCLUDE_START))
102 return(-2);
103
104 while ((node != NULL) &&
105 ((node->type == XML_ELEMENT_NODE) ||
106 (node->type == XML_ATTRIBUTE_NODE) ||
107 (node->type == XML_TEXT_NODE) ||
108 (node->type == XML_XINCLUDE_START))) {
109 if ((node->type == XML_ELEMENT_NODE) ||
110 (node->type == XML_XINCLUDE_START)) {
111 cur = node->nsDef;
112 while (cur != NULL) {
113 if (cur == ns)
114 return(1);
115 if (xmlStrEqual(cur->prefix, ns->prefix))
116 return(-2);
117 cur = cur->next;
118 }
119 }
120 node = node->parent;
121 }
122 /* the xml namespace may be declared on the document node */
123 if ((node != NULL) &&
124 ((node->type == XML_DOCUMENT_NODE) ||
125 (node->type == XML_HTML_DOCUMENT_NODE))) {
126 xmlNsPtr oldNs = ((xmlDocPtr) node)->oldNs;
127 if (oldNs == ns)
128 return(1);
129 }
130 return(-3);
131}
132
133static void
134xmlCtxtDumpSpaces(xmlDebugCtxtPtr ctxt)
135{
136 if (ctxt->check)
137 return;
138 if ((ctxt->output != NULL) && (ctxt->depth > 0)) {
139 if (ctxt->depth < 50)
140 fprintf(ctxt->output, "%s", &ctxt->shift[100 - 2 * ctxt->depth]);
141 else
142 fprintf(ctxt->output, "%s", ctxt->shift);
143 }
144}
145
153static void
154xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg)
155{
156 ctxt->errors++;
157 __xmlRaiseError(NULL, NULL, NULL,
158 NULL, ctxt->node, XML_FROM_CHECK,
160 NULL, NULL, NULL, 0, 0,
161 "%s", msg);
162}
163static void LIBXML_ATTR_FORMAT(3,0)
164xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
165{
166 ctxt->errors++;
167 __xmlRaiseError(NULL, NULL, NULL,
168 NULL, ctxt->node, XML_FROM_CHECK,
170 NULL, NULL, NULL, 0, 0,
171 msg, extra);
172}
173static void LIBXML_ATTR_FORMAT(3,0)
174xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
175{
176 ctxt->errors++;
177 __xmlRaiseError(NULL, NULL, NULL,
178 NULL, ctxt->node, XML_FROM_CHECK,
180 NULL, NULL, NULL, 0, 0,
181 msg, extra);
182}
183
192static void
193xmlCtxtNsCheckScope(xmlDebugCtxtPtr ctxt, xmlNodePtr node, xmlNsPtr ns)
194{
195 int ret;
196
197 ret = xmlNsCheckScope(node, ns);
198 if (ret == -2) {
199 if (ns->prefix == NULL)
200 xmlDebugErr(ctxt, XML_CHECK_NS_SCOPE,
201 "Reference to default namespace not in scope\n");
202 else
203 xmlDebugErr3(ctxt, XML_CHECK_NS_SCOPE,
204 "Reference to namespace '%s' not in scope\n",
205 (char *) ns->prefix);
206 }
207 if (ret == -3) {
208 if (ns->prefix == NULL)
209 xmlDebugErr(ctxt, XML_CHECK_NS_ANCESTOR,
210 "Reference to default namespace not on ancestor\n");
211 else
212 xmlDebugErr3(ctxt, XML_CHECK_NS_ANCESTOR,
213 "Reference to namespace '%s' not on ancestor\n",
214 (char *) ns->prefix);
215 }
216}
217
225static void
226xmlCtxtCheckString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
227{
228 if (str == NULL) return;
229 if (ctxt->check) {
230 if (!xmlCheckUTF8(str)) {
231 xmlDebugErr3(ctxt, XML_CHECK_NOT_UTF8,
232 "String is not UTF-8 %s", (const char *) str);
233 }
234 }
235}
236
245static void
246xmlCtxtCheckName(xmlDebugCtxtPtr ctxt, const xmlChar * name)
247{
248 if (ctxt->check) {
249 if (name == NULL) {
250 xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL");
251 return;
252 }
253#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
254 if (xmlValidateName(name, 0)) {
255 xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
256 "Name is not an NCName '%s'", (const char *) name);
257 }
258#endif
259 if ((ctxt->dict != NULL) &&
260 (!xmlDictOwns(ctxt->dict, name)) &&
261 ((ctxt->doc == NULL) ||
262 ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) {
263 xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT,
264 "Name is not from the document dictionary '%s'",
265 (const char *) name);
266 }
267 }
268}
269
270static void
271xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) {
272 xmlDocPtr doc;
273 xmlDictPtr dict;
274
275 doc = node->doc;
276
277 if (node->parent == NULL)
278 xmlDebugErr(ctxt, XML_CHECK_NO_PARENT,
279 "Node has no parent\n");
280 if (node->doc == NULL) {
281 xmlDebugErr(ctxt, XML_CHECK_NO_DOC,
282 "Node has no doc\n");
283 dict = NULL;
284 } else {
285 dict = doc->dict;
286 if ((dict == NULL) && (ctxt->nodict == 0)) {
287#if 0
288 /* deactivated right now as it raises too many errors */
289 if (doc->type == XML_DOCUMENT_NODE)
290 xmlDebugErr(ctxt, XML_CHECK_NO_DICT,
291 "Document has no dictionary\n");
292#endif
293 ctxt->nodict = 1;
294 }
295 if (ctxt->doc == NULL)
296 ctxt->doc = doc;
297
298 if (ctxt->dict == NULL) {
299 ctxt->dict = dict;
300 }
301 }
302 if ((node->parent != NULL) && (node->doc != node->parent->doc) &&
303 (!xmlStrEqual(node->name, BAD_CAST "pseudoroot")))
304 xmlDebugErr(ctxt, XML_CHECK_WRONG_DOC,
305 "Node doc differs from parent's one\n");
306 if (node->prev == NULL) {
307 if (node->type == XML_ATTRIBUTE_NODE) {
308 if ((node->parent != NULL) &&
309 (node != (xmlNodePtr) node->parent->properties))
310 xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
311 "Attr has no prev and not first of attr list\n");
312
313 } else if ((node->parent != NULL) && (node->parent->children != node))
314 xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
315 "Node has no prev and not first of parent list\n");
316 } else {
317 if (node->prev->next != node)
318 xmlDebugErr(ctxt, XML_CHECK_WRONG_PREV,
319 "Node prev->next : back link wrong\n");
320 }
321 if (node->next == NULL) {
322 if ((node->parent != NULL) && (node->type != XML_ATTRIBUTE_NODE) &&
323 (node->parent->last != node) &&
324 (node->parent->type == XML_ELEMENT_NODE))
325 xmlDebugErr(ctxt, XML_CHECK_NO_NEXT,
326 "Node has no next and not last of parent list\n");
327 } else {
328 if (node->next->prev != node)
329 xmlDebugErr(ctxt, XML_CHECK_WRONG_NEXT,
330 "Node next->prev : forward link wrong\n");
331 if (node->next->parent != node->parent)
332 xmlDebugErr(ctxt, XML_CHECK_WRONG_PARENT,
333 "Node next->prev : forward link wrong\n");
334 }
335 if (node->type == XML_ELEMENT_NODE) {
336 xmlNsPtr ns;
337
338 ns = node->nsDef;
339 while (ns != NULL) {
340 xmlCtxtNsCheckScope(ctxt, node, ns);
341 ns = ns->next;
342 }
343 if (node->ns != NULL)
344 xmlCtxtNsCheckScope(ctxt, node, node->ns);
345 } else if (node->type == XML_ATTRIBUTE_NODE) {
346 if (node->ns != NULL)
347 xmlCtxtNsCheckScope(ctxt, node, node->ns);
348 }
349
350 if ((node->type != XML_ELEMENT_NODE) &&
351 (node->type != XML_ATTRIBUTE_NODE) &&
352 (node->type != XML_ELEMENT_DECL) &&
353 (node->type != XML_ATTRIBUTE_DECL) &&
354 (node->type != XML_DTD_NODE) &&
355 (node->type != XML_HTML_DOCUMENT_NODE) &&
356 (node->type != XML_DOCUMENT_NODE)) {
357 if (node->content != NULL)
358 xmlCtxtCheckString(ctxt, (const xmlChar *) node->content);
359 }
360 switch (node->type) {
361 case XML_ELEMENT_NODE:
363 xmlCtxtCheckName(ctxt, node->name);
364 break;
365 case XML_TEXT_NODE:
366 if ((node->name == xmlStringText) ||
367 (node->name == xmlStringTextNoenc))
368 break;
369 /* some case of entity substitution can lead to this */
370 if ((ctxt->dict != NULL) &&
371 (node->name == xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
372 7)))
373 break;
374
375 xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
376 "Text node has wrong name '%s'",
377 (const char *) node->name);
378 break;
379 case XML_COMMENT_NODE:
380 if (node->name == xmlStringComment)
381 break;
382 xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
383 "Comment node has wrong name '%s'",
384 (const char *) node->name);
385 break;
386 case XML_PI_NODE:
387 xmlCtxtCheckName(ctxt, node->name);
388 break;
390 if (node->name == NULL)
391 break;
392 xmlDebugErr3(ctxt, XML_CHECK_NAME_NOT_NULL,
393 "CData section has non NULL name '%s'",
394 (const char *) node->name);
395 break;
397 case XML_ENTITY_NODE:
401 case XML_DTD_NODE:
402 case XML_ELEMENT_DECL:
404 case XML_ENTITY_DECL:
407 case XML_XINCLUDE_END:
410 break;
411 }
412}
413
414static void
415xmlCtxtDumpString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
416{
417 int i;
418
419 if (ctxt->check) {
420 return;
421 }
422 /* TODO: check UTF8 content of the string */
423 if (str == NULL) {
424 fprintf(ctxt->output, "(NULL)");
425 return;
426 }
427 for (i = 0; i < 40; i++)
428 if (str[i] == 0)
429 return;
430 else if (IS_BLANK_CH(str[i]))
431 fputc(' ', ctxt->output);
432 else if (str[i] >= 0x80)
433 fprintf(ctxt->output, "#%X", str[i]);
434 else
435 fputc(str[i], ctxt->output);
436 fprintf(ctxt->output, "...");
437}
438
439static void
440xmlCtxtDumpDtdNode(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
441{
442 xmlCtxtDumpSpaces(ctxt);
443
444 if (dtd == NULL) {
445 if (!ctxt->check)
446 fprintf(ctxt->output, "DTD node is NULL\n");
447 return;
448 }
449
450 if (dtd->type != XML_DTD_NODE) {
451 xmlDebugErr(ctxt, XML_CHECK_NOT_DTD,
452 "Node is not a DTD");
453 return;
454 }
455 if (!ctxt->check) {
456 if (dtd->name != NULL)
457 fprintf(ctxt->output, "DTD(%s)", (char *) dtd->name);
458 else
459 fprintf(ctxt->output, "DTD");
460 if (dtd->ExternalID != NULL)
461 fprintf(ctxt->output, ", PUBLIC %s", (char *) dtd->ExternalID);
462 if (dtd->SystemID != NULL)
463 fprintf(ctxt->output, ", SYSTEM %s", (char *) dtd->SystemID);
464 fprintf(ctxt->output, "\n");
465 }
466 /*
467 * Do a bit of checking
468 */
469 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) dtd);
470}
471
472static void
473xmlCtxtDumpAttrDecl(xmlDebugCtxtPtr ctxt, xmlAttributePtr attr)
474{
475 xmlCtxtDumpSpaces(ctxt);
476
477 if (attr == NULL) {
478 if (!ctxt->check)
479 fprintf(ctxt->output, "Attribute declaration is NULL\n");
480 return;
481 }
482 if (attr->type != XML_ATTRIBUTE_DECL) {
483 xmlDebugErr(ctxt, XML_CHECK_NOT_ATTR_DECL,
484 "Node is not an attribute declaration");
485 return;
486 }
487 if (attr->name != NULL) {
488 if (!ctxt->check)
489 fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name);
490 } else
491 xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
492 "Node attribute declaration has no name");
493 if (attr->elem != NULL) {
494 if (!ctxt->check)
495 fprintf(ctxt->output, " for %s", (char *) attr->elem);
496 } else
497 xmlDebugErr(ctxt, XML_CHECK_NO_ELEM,
498 "Node attribute declaration has no element name");
499 if (!ctxt->check) {
500 switch (attr->atype) {
502 fprintf(ctxt->output, " CDATA");
503 break;
504 case XML_ATTRIBUTE_ID:
505 fprintf(ctxt->output, " ID");
506 break;
508 fprintf(ctxt->output, " IDREF");
509 break;
511 fprintf(ctxt->output, " IDREFS");
512 break;
514 fprintf(ctxt->output, " ENTITY");
515 break;
517 fprintf(ctxt->output, " ENTITIES");
518 break;
520 fprintf(ctxt->output, " NMTOKEN");
521 break;
523 fprintf(ctxt->output, " NMTOKENS");
524 break;
526 fprintf(ctxt->output, " ENUMERATION");
527 break;
529 fprintf(ctxt->output, " NOTATION ");
530 break;
531 }
532 if (attr->tree != NULL) {
533 int indx;
534 xmlEnumerationPtr cur = attr->tree;
535
536 for (indx = 0; indx < 5; indx++) {
537 if (indx != 0)
538 fprintf(ctxt->output, "|%s", (char *) cur->name);
539 else
540 fprintf(ctxt->output, " (%s", (char *) cur->name);
541 cur = cur->next;
542 if (cur == NULL)
543 break;
544 }
545 if (cur == NULL)
546 fprintf(ctxt->output, ")");
547 else
548 fprintf(ctxt->output, "...)");
549 }
550 switch (attr->def) {
552 break;
554 fprintf(ctxt->output, " REQUIRED");
555 break;
557 fprintf(ctxt->output, " IMPLIED");
558 break;
560 fprintf(ctxt->output, " FIXED");
561 break;
562 }
563 if (attr->defaultValue != NULL) {
564 fprintf(ctxt->output, "\"");
565 xmlCtxtDumpString(ctxt, attr->defaultValue);
566 fprintf(ctxt->output, "\"");
567 }
568 fprintf(ctxt->output, "\n");
569 }
570
571 /*
572 * Do a bit of checking
573 */
574 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
575}
576
577static void
578xmlCtxtDumpElemDecl(xmlDebugCtxtPtr ctxt, xmlElementPtr elem)
579{
580 xmlCtxtDumpSpaces(ctxt);
581
582 if (elem == NULL) {
583 if (!ctxt->check)
584 fprintf(ctxt->output, "Element declaration is NULL\n");
585 return;
586 }
587 if (elem->type != XML_ELEMENT_DECL) {
588 xmlDebugErr(ctxt, XML_CHECK_NOT_ELEM_DECL,
589 "Node is not an element declaration");
590 return;
591 }
592 if (elem->name != NULL) {
593 if (!ctxt->check) {
594 fprintf(ctxt->output, "ELEMDECL(");
595 xmlCtxtDumpString(ctxt, elem->name);
596 fprintf(ctxt->output, ")");
597 }
598 } else
599 xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
600 "Element declaration has no name");
601 if (!ctxt->check) {
602 switch (elem->etype) {
604 fprintf(ctxt->output, ", UNDEFINED");
605 break;
607 fprintf(ctxt->output, ", EMPTY");
608 break;
610 fprintf(ctxt->output, ", ANY");
611 break;
613 fprintf(ctxt->output, ", MIXED ");
614 break;
616 fprintf(ctxt->output, ", MIXED ");
617 break;
618 }
619 if ((elem->type != XML_ELEMENT_NODE) && (elem->content != NULL)) {
620 char buf[5001];
621
622 buf[0] = 0;
623 xmlSnprintfElementContent(buf, 5000, elem->content, 1);
624 buf[5000] = 0;
625 fprintf(ctxt->output, "%s", buf);
626 }
627 fprintf(ctxt->output, "\n");
628 }
629
630 /*
631 * Do a bit of checking
632 */
633 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) elem);
634}
635
636static void
637xmlCtxtDumpEntityDecl(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
638{
639 xmlCtxtDumpSpaces(ctxt);
640
641 if (ent == NULL) {
642 if (!ctxt->check)
643 fprintf(ctxt->output, "Entity declaration is NULL\n");
644 return;
645 }
646 if (ent->type != XML_ENTITY_DECL) {
647 xmlDebugErr(ctxt, XML_CHECK_NOT_ENTITY_DECL,
648 "Node is not an entity declaration");
649 return;
650 }
651 if (ent->name != NULL) {
652 if (!ctxt->check) {
653 fprintf(ctxt->output, "ENTITYDECL(");
654 xmlCtxtDumpString(ctxt, ent->name);
655 fprintf(ctxt->output, ")");
656 }
657 } else
658 xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
659 "Entity declaration has no name");
660 if (!ctxt->check) {
661 switch (ent->etype) {
663 fprintf(ctxt->output, ", internal\n");
664 break;
666 fprintf(ctxt->output, ", external parsed\n");
667 break;
669 fprintf(ctxt->output, ", unparsed\n");
670 break;
672 fprintf(ctxt->output, ", parameter\n");
673 break;
675 fprintf(ctxt->output, ", external parameter\n");
676 break;
678 fprintf(ctxt->output, ", predefined\n");
679 break;
680 }
681 if (ent->ExternalID) {
682 xmlCtxtDumpSpaces(ctxt);
683 fprintf(ctxt->output, " ExternalID=%s\n",
684 (char *) ent->ExternalID);
685 }
686 if (ent->SystemID) {
687 xmlCtxtDumpSpaces(ctxt);
688 fprintf(ctxt->output, " SystemID=%s\n",
689 (char *) ent->SystemID);
690 }
691 if (ent->URI != NULL) {
692 xmlCtxtDumpSpaces(ctxt);
693 fprintf(ctxt->output, " URI=%s\n", (char *) ent->URI);
694 }
695 if (ent->content) {
696 xmlCtxtDumpSpaces(ctxt);
697 fprintf(ctxt->output, " content=");
698 xmlCtxtDumpString(ctxt, ent->content);
699 fprintf(ctxt->output, "\n");
700 }
701 }
702
703 /*
704 * Do a bit of checking
705 */
706 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) ent);
707}
708
709static void
710xmlCtxtDumpNamespace(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
711{
712 xmlCtxtDumpSpaces(ctxt);
713
714 if (ns == NULL) {
715 if (!ctxt->check)
716 fprintf(ctxt->output, "namespace node is NULL\n");
717 return;
718 }
719 if (ns->type != XML_NAMESPACE_DECL) {
720 xmlDebugErr(ctxt, XML_CHECK_NOT_NS_DECL,
721 "Node is not a namespace declaration");
722 return;
723 }
724 if (ns->href == NULL) {
725 if (ns->prefix != NULL)
726 xmlDebugErr3(ctxt, XML_CHECK_NO_HREF,
727 "Incomplete namespace %s href=NULL\n",
728 (char *) ns->prefix);
729 else
730 xmlDebugErr(ctxt, XML_CHECK_NO_HREF,
731 "Incomplete default namespace href=NULL\n");
732 } else {
733 if (!ctxt->check) {
734 if (ns->prefix != NULL)
735 fprintf(ctxt->output, "namespace %s href=",
736 (char *) ns->prefix);
737 else
738 fprintf(ctxt->output, "default namespace href=");
739
740 xmlCtxtDumpString(ctxt, ns->href);
741 fprintf(ctxt->output, "\n");
742 }
743 }
744}
745
746static void
747xmlCtxtDumpNamespaceList(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
748{
749 while (ns != NULL) {
750 xmlCtxtDumpNamespace(ctxt, ns);
751 ns = ns->next;
752 }
753}
754
755static void
756xmlCtxtDumpEntity(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
757{
758 xmlCtxtDumpSpaces(ctxt);
759
760 if (ent == NULL) {
761 if (!ctxt->check)
762 fprintf(ctxt->output, "Entity is NULL\n");
763 return;
764 }
765 if (!ctxt->check) {
766 switch (ent->etype) {
768 fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY ");
769 break;
771 fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
772 break;
774 fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
775 break;
777 fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY ");
778 break;
780 fprintf(ctxt->output, "EXTERNAL_PARAMETER_ENTITY ");
781 break;
782 default:
783 fprintf(ctxt->output, "ENTITY_%d ! ", (int) ent->etype);
784 }
785 fprintf(ctxt->output, "%s\n", ent->name);
786 if (ent->ExternalID) {
787 xmlCtxtDumpSpaces(ctxt);
788 fprintf(ctxt->output, "ExternalID=%s\n",
789 (char *) ent->ExternalID);
790 }
791 if (ent->SystemID) {
792 xmlCtxtDumpSpaces(ctxt);
793 fprintf(ctxt->output, "SystemID=%s\n", (char *) ent->SystemID);
794 }
795 if (ent->URI) {
796 xmlCtxtDumpSpaces(ctxt);
797 fprintf(ctxt->output, "URI=%s\n", (char *) ent->URI);
798 }
799 if (ent->content) {
800 xmlCtxtDumpSpaces(ctxt);
801 fprintf(ctxt->output, "content=");
802 xmlCtxtDumpString(ctxt, ent->content);
803 fprintf(ctxt->output, "\n");
804 }
805 }
806}
807
816static void
817xmlCtxtDumpAttr(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
818{
819 xmlCtxtDumpSpaces(ctxt);
820
821 if (attr == NULL) {
822 if (!ctxt->check)
823 fprintf(ctxt->output, "Attr is NULL");
824 return;
825 }
826 if (!ctxt->check) {
827 fprintf(ctxt->output, "ATTRIBUTE ");
828 xmlCtxtDumpString(ctxt, attr->name);
829 fprintf(ctxt->output, "\n");
830 if (attr->children != NULL) {
831 ctxt->depth++;
832 xmlCtxtDumpNodeList(ctxt, attr->children);
833 ctxt->depth--;
834 }
835 }
836 if (attr->name == NULL)
837 xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
838 "Attribute has no name");
839
840 /*
841 * Do a bit of checking
842 */
843 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
844}
845
854static void
855xmlCtxtDumpAttrList(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
856{
857 while (attr != NULL) {
858 xmlCtxtDumpAttr(ctxt, attr);
859 attr = attr->next;
860 }
861}
862
871static void
872xmlCtxtDumpOneNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
873{
874 if (node == NULL) {
875 if (!ctxt->check) {
876 xmlCtxtDumpSpaces(ctxt);
877 fprintf(ctxt->output, "node is NULL\n");
878 }
879 return;
880 }
881 ctxt->node = node;
882
883 switch (node->type) {
884 case XML_ELEMENT_NODE:
885 if (!ctxt->check) {
886 xmlCtxtDumpSpaces(ctxt);
887 fprintf(ctxt->output, "ELEMENT ");
888 if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
889 xmlCtxtDumpString(ctxt, node->ns->prefix);
890 fprintf(ctxt->output, ":");
891 }
892 xmlCtxtDumpString(ctxt, node->name);
893 fprintf(ctxt->output, "\n");
894 }
895 break;
897 if (!ctxt->check)
898 xmlCtxtDumpSpaces(ctxt);
899 fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
900 xmlCtxtGenericNodeCheck(ctxt, node);
901 return;
902 case XML_TEXT_NODE:
903 if (!ctxt->check) {
904 xmlCtxtDumpSpaces(ctxt);
905 if (node->name == (const xmlChar *) xmlStringTextNoenc)
906 fprintf(ctxt->output, "TEXT no enc");
907 else
908 fprintf(ctxt->output, "TEXT");
909 if (ctxt->options & DUMP_TEXT_TYPE) {
910 if (node->content == (xmlChar *) &(node->properties))
911 fprintf(ctxt->output, " compact\n");
912 else if (xmlDictOwns(ctxt->dict, node->content) == 1)
913 fprintf(ctxt->output, " interned\n");
914 else
915 fprintf(ctxt->output, "\n");
916 } else
917 fprintf(ctxt->output, "\n");
918 }
919 break;
921 if (!ctxt->check) {
922 xmlCtxtDumpSpaces(ctxt);
923 fprintf(ctxt->output, "CDATA_SECTION\n");
924 }
925 break;
927 if (!ctxt->check) {
928 xmlCtxtDumpSpaces(ctxt);
929 fprintf(ctxt->output, "ENTITY_REF(%s)\n",
930 (char *) node->name);
931 }
932 break;
933 case XML_ENTITY_NODE:
934 if (!ctxt->check) {
935 xmlCtxtDumpSpaces(ctxt);
936 fprintf(ctxt->output, "ENTITY\n");
937 }
938 break;
939 case XML_PI_NODE:
940 if (!ctxt->check) {
941 xmlCtxtDumpSpaces(ctxt);
942 fprintf(ctxt->output, "PI %s\n", (char *) node->name);
943 }
944 break;
945 case XML_COMMENT_NODE:
946 if (!ctxt->check) {
947 xmlCtxtDumpSpaces(ctxt);
948 fprintf(ctxt->output, "COMMENT\n");
949 }
950 break;
953 if (!ctxt->check) {
954 xmlCtxtDumpSpaces(ctxt);
955 }
956 fprintf(ctxt->output, "Error, DOCUMENT found here\n");
957 xmlCtxtGenericNodeCheck(ctxt, node);
958 return;
960 if (!ctxt->check) {
961 xmlCtxtDumpSpaces(ctxt);
962 fprintf(ctxt->output, "DOCUMENT_TYPE\n");
963 }
964 break;
966 if (!ctxt->check) {
967 xmlCtxtDumpSpaces(ctxt);
968 fprintf(ctxt->output, "DOCUMENT_FRAG\n");
969 }
970 break;
972 if (!ctxt->check) {
973 xmlCtxtDumpSpaces(ctxt);
974 fprintf(ctxt->output, "NOTATION\n");
975 }
976 break;
977 case XML_DTD_NODE:
978 xmlCtxtDumpDtdNode(ctxt, (xmlDtdPtr) node);
979 return;
980 case XML_ELEMENT_DECL:
981 xmlCtxtDumpElemDecl(ctxt, (xmlElementPtr) node);
982 return;
984 xmlCtxtDumpAttrDecl(ctxt, (xmlAttributePtr) node);
985 return;
986 case XML_ENTITY_DECL:
987 xmlCtxtDumpEntityDecl(ctxt, (xmlEntityPtr) node);
988 return;
990 xmlCtxtDumpNamespace(ctxt, (xmlNsPtr) node);
991 return;
993 if (!ctxt->check) {
994 xmlCtxtDumpSpaces(ctxt);
995 fprintf(ctxt->output, "INCLUDE START\n");
996 }
997 return;
998 case XML_XINCLUDE_END:
999 if (!ctxt->check) {
1000 xmlCtxtDumpSpaces(ctxt);
1001 fprintf(ctxt->output, "INCLUDE END\n");
1002 }
1003 return;
1004 default:
1005 if (!ctxt->check)
1006 xmlCtxtDumpSpaces(ctxt);
1007 xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
1008 "Unknown node type %d\n", node->type);
1009 return;
1010 }
1011 if (node->doc == NULL) {
1012 if (!ctxt->check) {
1013 xmlCtxtDumpSpaces(ctxt);
1014 }
1015 fprintf(ctxt->output, "PBM: doc == NULL !!!\n");
1016 }
1017 ctxt->depth++;
1018 if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
1019 xmlCtxtDumpNamespaceList(ctxt, node->nsDef);
1020 if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
1021 xmlCtxtDumpAttrList(ctxt, node->properties);
1022 if (node->type != XML_ENTITY_REF_NODE) {
1023 if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
1024 if (!ctxt->check) {
1025 xmlCtxtDumpSpaces(ctxt);
1026 fprintf(ctxt->output, "content=");
1027 xmlCtxtDumpString(ctxt, node->content);
1028 fprintf(ctxt->output, "\n");
1029 }
1030 }
1031 } else {
1032 xmlEntityPtr ent;
1033
1034 ent = xmlGetDocEntity(node->doc, node->name);
1035 if (ent != NULL)
1036 xmlCtxtDumpEntity(ctxt, ent);
1037 }
1038 ctxt->depth--;
1039
1040 /*
1041 * Do a bit of checking
1042 */
1043 xmlCtxtGenericNodeCheck(ctxt, node);
1044}
1045
1054static void
1055xmlCtxtDumpNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
1056{
1057 if (node == NULL) {
1058 if (!ctxt->check) {
1059 xmlCtxtDumpSpaces(ctxt);
1060 fprintf(ctxt->output, "node is NULL\n");
1061 }
1062 return;
1063 }
1064 xmlCtxtDumpOneNode(ctxt, node);
1065 if ((node->type != XML_NAMESPACE_DECL) &&
1066 (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
1067 ctxt->depth++;
1068 xmlCtxtDumpNodeList(ctxt, node->children);
1069 ctxt->depth--;
1070 }
1071}
1072
1081static void
1082xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
1083{
1084 while (node != NULL) {
1085 xmlCtxtDumpNode(ctxt, node);
1086 node = node->next;
1087 }
1088}
1089
1090static void
1091xmlCtxtDumpDocHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1092{
1093 if (doc == NULL) {
1094 if (!ctxt->check)
1095 fprintf(ctxt->output, "DOCUMENT == NULL !\n");
1096 return;
1097 }
1098 ctxt->node = (xmlNodePtr) doc;
1099
1100 switch (doc->type) {
1101 case XML_ELEMENT_NODE:
1102 xmlDebugErr(ctxt, XML_CHECK_FOUND_ELEMENT,
1103 "Misplaced ELEMENT node\n");
1104 break;
1105 case XML_ATTRIBUTE_NODE:
1106 xmlDebugErr(ctxt, XML_CHECK_FOUND_ATTRIBUTE,
1107 "Misplaced ATTRIBUTE node\n");
1108 break;
1109 case XML_TEXT_NODE:
1110 xmlDebugErr(ctxt, XML_CHECK_FOUND_TEXT,
1111 "Misplaced TEXT node\n");
1112 break;
1114 xmlDebugErr(ctxt, XML_CHECK_FOUND_CDATA,
1115 "Misplaced CDATA node\n");
1116 break;
1118 xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITYREF,
1119 "Misplaced ENTITYREF node\n");
1120 break;
1121 case XML_ENTITY_NODE:
1122 xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITY,
1123 "Misplaced ENTITY node\n");
1124 break;
1125 case XML_PI_NODE:
1126 xmlDebugErr(ctxt, XML_CHECK_FOUND_PI,
1127 "Misplaced PI node\n");
1128 break;
1129 case XML_COMMENT_NODE:
1130 xmlDebugErr(ctxt, XML_CHECK_FOUND_COMMENT,
1131 "Misplaced COMMENT node\n");
1132 break;
1133 case XML_DOCUMENT_NODE:
1134 if (!ctxt->check)
1135 fprintf(ctxt->output, "DOCUMENT\n");
1136 break;
1138 if (!ctxt->check)
1139 fprintf(ctxt->output, "HTML DOCUMENT\n");
1140 break;
1142 xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE,
1143 "Misplaced DOCTYPE node\n");
1144 break;
1146 xmlDebugErr(ctxt, XML_CHECK_FOUND_FRAGMENT,
1147 "Misplaced FRAGMENT node\n");
1148 break;
1149 case XML_NOTATION_NODE:
1150 xmlDebugErr(ctxt, XML_CHECK_FOUND_NOTATION,
1151 "Misplaced NOTATION node\n");
1152 break;
1153 default:
1154 xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
1155 "Unknown node type %d\n", doc->type);
1156 }
1157}
1158
1166static void
1167xmlCtxtDumpDocumentHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1168{
1169 if (doc == NULL) return;
1170 xmlCtxtDumpDocHead(ctxt, doc);
1171 if (!ctxt->check) {
1172 if (doc->name != NULL) {
1173 fprintf(ctxt->output, "name=");
1174 xmlCtxtDumpString(ctxt, BAD_CAST doc->name);
1175 fprintf(ctxt->output, "\n");
1176 }
1177 if (doc->version != NULL) {
1178 fprintf(ctxt->output, "version=");
1179 xmlCtxtDumpString(ctxt, doc->version);
1180 fprintf(ctxt->output, "\n");
1181 }
1182 if (doc->encoding != NULL) {
1183 fprintf(ctxt->output, "encoding=");
1184 xmlCtxtDumpString(ctxt, doc->encoding);
1185 fprintf(ctxt->output, "\n");
1186 }
1187 if (doc->URL != NULL) {
1188 fprintf(ctxt->output, "URL=");
1189 xmlCtxtDumpString(ctxt, doc->URL);
1190 fprintf(ctxt->output, "\n");
1191 }
1192 if (doc->standalone)
1193 fprintf(ctxt->output, "standalone=true\n");
1194 }
1195 if (doc->oldNs != NULL)
1196 xmlCtxtDumpNamespaceList(ctxt, doc->oldNs);
1197}
1198
1206static void
1207xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1208{
1209 if (doc == NULL) {
1210 if (!ctxt->check)
1211 fprintf(ctxt->output, "DOCUMENT == NULL !\n");
1212 return;
1213 }
1214 xmlCtxtDumpDocumentHead(ctxt, doc);
1215 if (((doc->type == XML_DOCUMENT_NODE) ||
1216 (doc->type == XML_HTML_DOCUMENT_NODE))
1217 && (doc->children != NULL)) {
1218 ctxt->depth++;
1219 xmlCtxtDumpNodeList(ctxt, doc->children);
1220 ctxt->depth--;
1221 }
1222}
1223
1224static void
1225xmlCtxtDumpEntityCallback(void *payload, void *data,
1227{
1228 xmlEntityPtr cur = (xmlEntityPtr) payload;
1229 xmlDebugCtxtPtr ctxt = (xmlDebugCtxtPtr) data;
1230 if (cur == NULL) {
1231 if (!ctxt->check)
1232 fprintf(ctxt->output, "Entity is NULL");
1233 return;
1234 }
1235 if (!ctxt->check) {
1236 fprintf(ctxt->output, "%s : ", (char *) cur->name);
1237 switch (cur->etype) {
1239 fprintf(ctxt->output, "INTERNAL GENERAL, ");
1240 break;
1242 fprintf(ctxt->output, "EXTERNAL PARSED, ");
1243 break;
1245 fprintf(ctxt->output, "EXTERNAL UNPARSED, ");
1246 break;
1248 fprintf(ctxt->output, "INTERNAL PARAMETER, ");
1249 break;
1251 fprintf(ctxt->output, "EXTERNAL PARAMETER, ");
1252 break;
1253 default:
1254 xmlDebugErr2(ctxt, XML_CHECK_ENTITY_TYPE,
1255 "Unknown entity type %d\n", cur->etype);
1256 }
1257 if (cur->ExternalID != NULL)
1258 fprintf(ctxt->output, "ID \"%s\"", (char *) cur->ExternalID);
1259 if (cur->SystemID != NULL)
1260 fprintf(ctxt->output, "SYSTEM \"%s\"", (char *) cur->SystemID);
1261 if (cur->orig != NULL)
1262 fprintf(ctxt->output, "\n orig \"%s\"", (char *) cur->orig);
1263 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL))
1264 fprintf(ctxt->output, "\n content \"%s\"",
1265 (char *) cur->content);
1266 fprintf(ctxt->output, "\n");
1267 }
1268}
1269
1277static void
1278xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1279{
1280 if (doc == NULL) return;
1281 xmlCtxtDumpDocHead(ctxt, doc);
1282 if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
1284 doc->intSubset->entities;
1285
1286 if (!ctxt->check)
1287 fprintf(ctxt->output, "Entities in internal subset\n");
1288 xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt);
1289 } else
1290 fprintf(ctxt->output, "No entities in internal subset\n");
1291 if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
1293 doc->extSubset->entities;
1294
1295 if (!ctxt->check)
1296 fprintf(ctxt->output, "Entities in external subset\n");
1297 xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt);
1298 } else if (!ctxt->check)
1299 fprintf(ctxt->output, "No entities in external subset\n");
1300}
1301
1309static void
1310xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
1311{
1312 if (dtd == NULL) {
1313 if (!ctxt->check)
1314 fprintf(ctxt->output, "DTD is NULL\n");
1315 return;
1316 }
1317 xmlCtxtDumpDtdNode(ctxt, dtd);
1318 if (dtd->children == NULL)
1319 fprintf(ctxt->output, " DTD is empty\n");
1320 else {
1321 ctxt->depth++;
1322 xmlCtxtDumpNodeList(ctxt, dtd->children);
1323 ctxt->depth--;
1324 }
1325}
1326
1327/************************************************************************
1328 * *
1329 * Public entry points for dump *
1330 * *
1331 ************************************************************************/
1332
1340void
1341xmlDebugDumpString(FILE * output, const xmlChar * str)
1342{
1343 int i;
1344
1345 if (output == NULL)
1346 output = stdout;
1347 if (str == NULL) {
1348 fprintf(output, "(NULL)");
1349 return;
1350 }
1351 for (i = 0; i < 40; i++)
1352 if (str[i] == 0)
1353 return;
1354 else if (IS_BLANK_CH(str[i]))
1355 fputc(' ', output);
1356 else if (str[i] >= 0x80)
1357 fprintf(output, "#%X", str[i]);
1358 else
1359 fputc(str[i], output);
1360 fprintf(output, "...");
1361}
1362
1371void
1372xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
1373 xmlDebugCtxt ctxt;
1374
1375 if (output == NULL) return;
1376 xmlCtxtDumpInitCtxt(&ctxt);
1377 ctxt.output = output;
1378 ctxt.depth = depth;
1379 xmlCtxtDumpAttr(&ctxt, attr);
1380 xmlCtxtDumpCleanCtxt(&ctxt);
1381}
1382
1383
1391void
1392xmlDebugDumpEntities(FILE * output, xmlDocPtr doc)
1393{
1394 xmlDebugCtxt ctxt;
1395
1396 if (output == NULL) return;
1397 xmlCtxtDumpInitCtxt(&ctxt);
1398 ctxt.output = output;
1399 xmlCtxtDumpEntities(&ctxt, doc);
1400 xmlCtxtDumpCleanCtxt(&ctxt);
1401}
1402
1411void
1412xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
1413{
1414 xmlDebugCtxt ctxt;
1415
1416 if (output == NULL) return;
1417 xmlCtxtDumpInitCtxt(&ctxt);
1418 ctxt.output = output;
1419 ctxt.depth = depth;
1420 xmlCtxtDumpAttrList(&ctxt, attr);
1421 xmlCtxtDumpCleanCtxt(&ctxt);
1422}
1423
1432void
1433xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
1434{
1435 xmlDebugCtxt ctxt;
1436
1437 if (output == NULL) return;
1438 xmlCtxtDumpInitCtxt(&ctxt);
1439 ctxt.output = output;
1440 ctxt.depth = depth;
1441 xmlCtxtDumpOneNode(&ctxt, node);
1442 xmlCtxtDumpCleanCtxt(&ctxt);
1443}
1444
1453void
1454xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
1455{
1456 xmlDebugCtxt ctxt;
1457
1458 if (output == NULL)
1459 output = stdout;
1460 xmlCtxtDumpInitCtxt(&ctxt);
1461 ctxt.output = output;
1462 ctxt.depth = depth;
1463 xmlCtxtDumpNode(&ctxt, node);
1464 xmlCtxtDumpCleanCtxt(&ctxt);
1465}
1466
1475void
1476xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
1477{
1478 xmlDebugCtxt ctxt;
1479
1480 if (output == NULL)
1481 output = stdout;
1482 xmlCtxtDumpInitCtxt(&ctxt);
1483 ctxt.output = output;
1484 ctxt.depth = depth;
1485 xmlCtxtDumpNodeList(&ctxt, node);
1486 xmlCtxtDumpCleanCtxt(&ctxt);
1487}
1488
1496void
1497xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
1498{
1499 xmlDebugCtxt ctxt;
1500
1501 if (output == NULL)
1502 output = stdout;
1503 xmlCtxtDumpInitCtxt(&ctxt);
1504 ctxt.options |= DUMP_TEXT_TYPE;
1505 ctxt.output = output;
1506 xmlCtxtDumpDocumentHead(&ctxt, doc);
1507 xmlCtxtDumpCleanCtxt(&ctxt);
1508}
1509
1517void
1518xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
1519{
1520 xmlDebugCtxt ctxt;
1521
1522 if (output == NULL)
1523 output = stdout;
1524 xmlCtxtDumpInitCtxt(&ctxt);
1525 ctxt.options |= DUMP_TEXT_TYPE;
1526 ctxt.output = output;
1527 xmlCtxtDumpDocument(&ctxt, doc);
1528 xmlCtxtDumpCleanCtxt(&ctxt);
1529}
1530
1538void
1539xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
1540{
1541 xmlDebugCtxt ctxt;
1542
1543 if (output == NULL)
1544 output = stdout;
1545 xmlCtxtDumpInitCtxt(&ctxt);
1546 ctxt.options |= DUMP_TEXT_TYPE;
1547 ctxt.output = output;
1548 xmlCtxtDumpDTD(&ctxt, dtd);
1549 xmlCtxtDumpCleanCtxt(&ctxt);
1550}
1551
1552/************************************************************************
1553 * *
1554 * Public entry points for checkings *
1555 * *
1556 ************************************************************************/
1557
1568int
1569xmlDebugCheckDocument(FILE * output, xmlDocPtr doc)
1570{
1571 xmlDebugCtxt ctxt;
1572
1573 if (output == NULL)
1574 output = stdout;
1575 xmlCtxtDumpInitCtxt(&ctxt);
1576 ctxt.output = output;
1577 ctxt.check = 1;
1578 xmlCtxtDumpDocument(&ctxt, doc);
1579 xmlCtxtDumpCleanCtxt(&ctxt);
1580 return(ctxt.errors);
1581}
1582
1583/************************************************************************
1584 * *
1585 * Helpers for Shell *
1586 * *
1587 ************************************************************************/
1588
1597int
1598xmlLsCountNode(xmlNodePtr node) {
1599 int ret = 0;
1601
1602 if (node == NULL)
1603 return(0);
1604
1605 switch (node->type) {
1606 case XML_ELEMENT_NODE:
1607 list = node->children;
1608 break;
1609 case XML_DOCUMENT_NODE:
1611 list = ((xmlDocPtr) node)->children;
1612 break;
1613 case XML_ATTRIBUTE_NODE:
1614 list = ((xmlAttrPtr) node)->children;
1615 break;
1616 case XML_TEXT_NODE:
1618 case XML_PI_NODE:
1619 case XML_COMMENT_NODE:
1620 if (node->content != NULL) {
1621 ret = xmlStrlen(node->content);
1622 }
1623 break;
1626 case XML_ENTITY_NODE:
1628 case XML_NOTATION_NODE:
1629 case XML_DTD_NODE:
1630 case XML_ELEMENT_DECL:
1631 case XML_ATTRIBUTE_DECL:
1632 case XML_ENTITY_DECL:
1633 case XML_NAMESPACE_DECL:
1634 case XML_XINCLUDE_START:
1635 case XML_XINCLUDE_END:
1636 ret = 1;
1637 break;
1638 }
1639 for (;list != NULL;ret++)
1640 list = list->next;
1641 return(ret);
1642}
1643
1651void
1652xmlLsOneNode(FILE *output, xmlNodePtr node) {
1653 if (output == NULL) return;
1654 if (node == NULL) {
1655 fprintf(output, "NULL\n");
1656 return;
1657 }
1658 switch (node->type) {
1659 case XML_ELEMENT_NODE:
1660 fprintf(output, "-");
1661 break;
1662 case XML_ATTRIBUTE_NODE:
1663 fprintf(output, "a");
1664 break;
1665 case XML_TEXT_NODE:
1666 fprintf(output, "t");
1667 break;
1669 fprintf(output, "C");
1670 break;
1672 fprintf(output, "e");
1673 break;
1674 case XML_ENTITY_NODE:
1675 fprintf(output, "E");
1676 break;
1677 case XML_PI_NODE:
1678 fprintf(output, "p");
1679 break;
1680 case XML_COMMENT_NODE:
1681 fprintf(output, "c");
1682 break;
1683 case XML_DOCUMENT_NODE:
1684 fprintf(output, "d");
1685 break;
1687 fprintf(output, "h");
1688 break;
1690 fprintf(output, "T");
1691 break;
1693 fprintf(output, "F");
1694 break;
1695 case XML_NOTATION_NODE:
1696 fprintf(output, "N");
1697 break;
1698 case XML_NAMESPACE_DECL:
1699 fprintf(output, "n");
1700 break;
1701 default:
1702 fprintf(output, "?");
1703 }
1704 if (node->type != XML_NAMESPACE_DECL) {
1705 if (node->properties != NULL)
1706 fprintf(output, "a");
1707 else
1708 fprintf(output, "-");
1709 if (node->nsDef != NULL)
1710 fprintf(output, "n");
1711 else
1712 fprintf(output, "-");
1713 }
1714
1715 fprintf(output, " %8d ", xmlLsCountNode(node));
1716
1717 switch (node->type) {
1718 case XML_ELEMENT_NODE:
1719 if (node->name != NULL) {
1720 if ((node->ns != NULL) && (node->ns->prefix != NULL))
1721 fprintf(output, "%s:", node->ns->prefix);
1722 fprintf(output, "%s", (const char *) node->name);
1723 }
1724 break;
1725 case XML_ATTRIBUTE_NODE:
1726 if (node->name != NULL)
1727 fprintf(output, "%s", (const char *) node->name);
1728 break;
1729 case XML_TEXT_NODE:
1730 if (node->content != NULL) {
1731 xmlDebugDumpString(output, node->content);
1732 }
1733 break;
1735 break;
1737 if (node->name != NULL)
1738 fprintf(output, "%s", (const char *) node->name);
1739 break;
1740 case XML_ENTITY_NODE:
1741 if (node->name != NULL)
1742 fprintf(output, "%s", (const char *) node->name);
1743 break;
1744 case XML_PI_NODE:
1745 if (node->name != NULL)
1746 fprintf(output, "%s", (const char *) node->name);
1747 break;
1748 case XML_COMMENT_NODE:
1749 break;
1750 case XML_DOCUMENT_NODE:
1751 break;
1753 break;
1755 break;
1757 break;
1758 case XML_NOTATION_NODE:
1759 break;
1760 case XML_NAMESPACE_DECL: {
1762
1763 if (ns->prefix == NULL)
1764 fprintf(output, "default -> %s", (char *)ns->href);
1765 else
1766 fprintf(output, "%s -> %s", (char *)ns->prefix,
1767 (char *)ns->href);
1768 break;
1769 }
1770 default:
1771 if (node->name != NULL)
1772 fprintf(output, "%s", (const char *) node->name);
1773 }
1774 fprintf(output, "\n");
1775}
1776
1785const char *
1786xmlBoolToText(int boolval)
1787{
1788 if (boolval)
1789 return("True");
1790 else
1791 return("False");
1792}
1793
1794#ifdef LIBXML_XPATH_ENABLED
1795/****************************************************************
1796 * *
1797 * The XML shell related functions *
1798 * *
1799 ****************************************************************/
1800
1801
1802
1803/*
1804 * TODO: Improvement/cleanups for the XML shell
1805 * - allow to shell out an editor on a subpart
1806 * - cleanup function registrations (with help) and calling
1807 * - provide registration routines
1808 */
1809
1817void
1818xmlShellPrintXPathError(int errorType, const char *arg)
1819{
1820 const char *default_arg = "Result";
1821
1822 if (!arg)
1823 arg = default_arg;
1824
1825 switch (errorType) {
1826 case XPATH_UNDEFINED:
1828 "%s: no such node\n", arg);
1829 break;
1830
1831 case XPATH_BOOLEAN:
1833 "%s is a Boolean\n", arg);
1834 break;
1835 case XPATH_NUMBER:
1837 "%s is a number\n", arg);
1838 break;
1839 case XPATH_STRING:
1841 "%s is a string\n", arg);
1842 break;
1843#ifdef LIBXML_XPTR_LOCS_ENABLED
1844 case XPATH_POINT:
1846 "%s is a point\n", arg);
1847 break;
1848 case XPATH_RANGE:
1850 "%s is a range\n", arg);
1851 break;
1852 case XPATH_LOCATIONSET:
1854 "%s is a range\n", arg);
1855 break;
1856#endif /* LIBXML_XPTR_LOCS_ENABLED */
1857 case XPATH_USERS:
1859 "%s is user-defined\n", arg);
1860 break;
1861 case XPATH_XSLT_TREE:
1863 "%s is an XSLT value tree\n", arg);
1864 break;
1865 }
1866#if 0
1868 "Try casting the result string function (xpath builtin)\n",
1869 arg);
1870#endif
1871}
1872
1873
1874#ifdef LIBXML_OUTPUT_ENABLED
1882static void
1883xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node)
1884{
1885 FILE *fp;
1886
1887 if (!node)
1888 return;
1889 if (ctxt == NULL)
1890 fp = stdout;
1891 else
1892 fp = ctxt->output;
1893
1894 if (node->type == XML_DOCUMENT_NODE)
1895 xmlDocDump(fp, (xmlDocPtr) node);
1896 else if (node->type == XML_ATTRIBUTE_NODE)
1897 xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0);
1898 else
1899 xmlElemDump(fp, node->doc, node);
1900
1901 fprintf(fp, "\n");
1902}
1903
1910void
1911xmlShellPrintNode(xmlNodePtr node)
1912{
1913 xmlShellPrintNodeCtxt(NULL, node);
1914}
1915#endif /* LIBXML_OUTPUT_ENABLED */
1916
1924static void
1925xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
1926{
1927 if (!ctxt)
1928 return;
1929
1930 if (list != NULL) {
1931 switch (list->type) {
1932 case XPATH_NODESET:{
1933#ifdef LIBXML_OUTPUT_ENABLED
1934 int indx;
1935
1936 if (list->nodesetval) {
1937 for (indx = 0; indx < list->nodesetval->nodeNr;
1938 indx++) {
1939 xmlShellPrintNodeCtxt(ctxt,
1940 list->nodesetval->nodeTab[indx]);
1941 }
1942 } else {
1944 "Empty node set\n");
1945 }
1946 break;
1947#else
1949 "Node set\n");
1950#endif /* LIBXML_OUTPUT_ENABLED */
1951 }
1952 case XPATH_BOOLEAN:
1954 "Is a Boolean:%s\n",
1955 xmlBoolToText(list->boolval));
1956 break;
1957 case XPATH_NUMBER:
1959 "Is a number:%0g\n", list->floatval);
1960 break;
1961 case XPATH_STRING:
1963 "Is a string:%s\n", list->stringval);
1964 break;
1965
1966 default:
1967 xmlShellPrintXPathError(list->type, NULL);
1968 }
1969 }
1970}
1971
1978void
1979xmlShellPrintXPathResult(xmlXPathObjectPtr list)
1980{
1981 xmlShellPrintXPathResultCtxt(NULL, list);
1982}
1983
1996int
1997xmlShellList(xmlShellCtxtPtr ctxt,
2000{
2002 if (!ctxt)
2003 return (0);
2004 if (node == NULL) {
2005 fprintf(ctxt->output, "NULL\n");
2006 return (0);
2007 }
2008 if ((node->type == XML_DOCUMENT_NODE) ||
2009 (node->type == XML_HTML_DOCUMENT_NODE)) {
2010 cur = ((xmlDocPtr) node)->children;
2011 } else if (node->type == XML_NAMESPACE_DECL) {
2012 xmlLsOneNode(ctxt->output, node);
2013 return (0);
2014 } else if (node->children != NULL) {
2015 cur = node->children;
2016 } else {
2017 xmlLsOneNode(ctxt->output, node);
2018 return (0);
2019 }
2020 while (cur != NULL) {
2021 xmlLsOneNode(ctxt->output, cur);
2022 cur = cur->next;
2023 }
2024 return (0);
2025}
2026
2039int
2040xmlShellBase(xmlShellCtxtPtr ctxt,
2043{
2044 xmlChar *base;
2045 if (!ctxt)
2046 return 0;
2047 if (node == NULL) {
2048 fprintf(ctxt->output, "NULL\n");
2049 return (0);
2050 }
2051
2052 base = xmlNodeGetBase(node->doc, node);
2053
2054 if (base == NULL) {
2055 fprintf(ctxt->output, " No base found !!!\n");
2056 } else {
2057 fprintf(ctxt->output, "%s\n", base);
2058 xmlFree(base);
2059 }
2060 return (0);
2061}
2062
2063#ifdef LIBXML_TREE_ENABLED
2076static int
2077xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2080{
2081 xmlNodeSetBase(node, (xmlChar*) arg);
2082 return (0);
2083}
2084#endif
2085
2086#ifdef LIBXML_XPATH_ENABLED
2100static int
2101xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg,
2103{
2104 xmlChar* nsListDup;
2105 xmlChar* prefix;
2106 xmlChar* href;
2107 xmlChar* next;
2108
2109 nsListDup = xmlStrdup((xmlChar *) arg);
2110 next = nsListDup;
2111 while(next != NULL) {
2112 /* skip spaces */
2113 /*while((*next) == ' ') next++;*/
2114 if((*next) == '\0') break;
2115
2116 /* find prefix */
2117 prefix = next;
2118 next = (xmlChar*)xmlStrchr(next, '=');
2119 if(next == NULL) {
2120 fprintf(ctxt->output, "setns: prefix=[nsuri] required\n");
2121 xmlFree(nsListDup);
2122 return(-1);
2123 }
2124 *(next++) = '\0';
2125
2126 /* find href */
2127 href = next;
2128 next = (xmlChar*)xmlStrchr(next, ' ');
2129 if(next != NULL) {
2130 *(next++) = '\0';
2131 }
2132
2133 /* do register namespace */
2134 if(xmlXPathRegisterNs(ctxt->pctxt, prefix, href) != 0) {
2135 fprintf(ctxt->output,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
2136 xmlFree(nsListDup);
2137 return(-1);
2138 }
2139 }
2140
2141 xmlFree(nsListDup);
2142 return(0);
2143}
2156static int
2157xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
2159{
2160 xmlNsPtr ns;
2161
2162 if ((root == NULL) || (root->type != XML_ELEMENT_NODE) ||
2163 (root->nsDef == NULL) || (ctxt == NULL) || (ctxt->pctxt == NULL))
2164 return(-1);
2165 ns = root->nsDef;
2166 while (ns != NULL) {
2167 if (ns->prefix == NULL)
2168 xmlXPathRegisterNs(ctxt->pctxt, BAD_CAST "defaultns", ns->href);
2169 else
2170 xmlXPathRegisterNs(ctxt->pctxt, ns->prefix, ns->href);
2171 ns = ns->next;
2172 }
2173 return(0);
2174}
2175#endif
2176
2189static int
2190xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2192{
2193 if (!ctxt)
2194 return (0);
2195 if (node == NULL)
2196 return (0);
2197 if (arg == NULL)
2198 return (0);
2199#ifdef LIBXML_REGEXP_ENABLED
2200 if ((xmlStrchr((xmlChar *) arg, '?')) ||
2201 (xmlStrchr((xmlChar *) arg, '*')) ||
2202 (xmlStrchr((xmlChar *) arg, '.')) ||
2203 (xmlStrchr((xmlChar *) arg, '['))) {
2204 }
2205#endif
2206 while (node != NULL) {
2207 if (node->type == XML_COMMENT_NODE) {
2208 if (xmlStrstr(node->content, (xmlChar *) arg)) {
2209
2210 fprintf(ctxt->output, "%s : ", xmlGetNodePath(node));
2211 xmlShellList(ctxt, NULL, node, NULL);
2212 }
2213 } else if (node->type == XML_TEXT_NODE) {
2214 if (xmlStrstr(node->content, (xmlChar *) arg)) {
2215
2216 fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent));
2217 xmlShellList(ctxt, NULL, node->parent, NULL);
2218 }
2219 }
2220
2221 /*
2222 * Browse the full subtree, deep first
2223 */
2224
2225 if ((node->type == XML_DOCUMENT_NODE) ||
2226 (node->type == XML_HTML_DOCUMENT_NODE)) {
2227 node = ((xmlDocPtr) node)->children;
2228 } else if ((node->children != NULL)
2229 && (node->type != XML_ENTITY_REF_NODE)) {
2230 /* deep first */
2231 node = node->children;
2232 } else if (node->next != NULL) {
2233 /* then siblings */
2234 node = node->next;
2235 } else {
2236 /* go up to parents->next if needed */
2237 while (node != NULL) {
2238 if (node->parent != NULL) {
2239 node = node->parent;
2240 }
2241 if (node->next != NULL) {
2242 node = node->next;
2243 break;
2244 }
2245 if (node->parent == NULL) {
2246 node = NULL;
2247 break;
2248 }
2249 }
2250 }
2251 }
2252 return (0);
2253}
2254
2267int
2268xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2271{
2272 if (!ctxt)
2273 return (0);
2274 if (node == NULL) {
2275 fprintf(ctxt->output, "NULL\n");
2276 return (0);
2277 }
2278 if ((node->type == XML_DOCUMENT_NODE) ||
2279 (node->type == XML_HTML_DOCUMENT_NODE)) {
2280 xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node);
2281 } else if (node->type == XML_ATTRIBUTE_NODE) {
2282 xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0);
2283 } else {
2284 xmlDebugDumpOneNode(ctxt->output, node, 0);
2285 }
2286 return (0);
2287}
2288
2301static int
2302xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2303 char *value, xmlNodePtr node,
2305{
2308
2309 if (!ctxt)
2310 return (0);
2311 if (node == NULL) {
2312 fprintf(ctxt->output, "NULL\n");
2313 return (0);
2314 }
2315 if (value == NULL) {
2316 fprintf(ctxt->output, "NULL\n");
2317 return (0);
2318 }
2319
2321 if (ret == XML_ERR_OK) {
2322 if (node->children != NULL) {
2323 xmlFreeNodeList(node->children);
2324 node->children = NULL;
2325 node->last = NULL;
2326 }
2328 } else {
2329 fprintf(ctxt->output, "failed to parse content\n");
2330 }
2331 return (0);
2332}
2333
2334#ifdef LIBXML_SCHEMAS_ENABLED
2347static int
2348xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
2351{
2352 xmlRelaxNGPtr relaxngschemas;
2353 xmlRelaxNGParserCtxtPtr ctxt;
2354 xmlRelaxNGValidCtxtPtr vctxt;
2355 int ret;
2356
2357 ctxt = xmlRelaxNGNewParserCtxt(schemas);
2358 xmlRelaxNGSetParserErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
2359 relaxngschemas = xmlRelaxNGParse(ctxt);
2360 xmlRelaxNGFreeParserCtxt(ctxt);
2361 if (relaxngschemas == NULL) {
2363 "Relax-NG schema %s failed to compile\n", schemas);
2364 return(-1);
2365 }
2366 vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2367 xmlRelaxNGSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL);
2368 ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc);
2369 if (ret == 0) {
2370 fprintf(stderr, "%s validates\n", sctxt->filename);
2371 } else if (ret > 0) {
2372 fprintf(stderr, "%s fails to validate\n", sctxt->filename);
2373 } else {
2374 fprintf(stderr, "%s validation generated an internal error\n",
2375 sctxt->filename);
2376 }
2377 xmlRelaxNGFreeValidCtxt(vctxt);
2378 if (relaxngschemas != NULL)
2379 xmlRelaxNGFree(relaxngschemas);
2380 return(0);
2381}
2382#endif
2383
2384#ifdef LIBXML_OUTPUT_ENABLED
2397int
2398xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
2400{
2401 if (!ctxt)
2402 return (0);
2403 if (node == NULL) {
2404 fprintf(ctxt->output, "NULL\n");
2405 return (0);
2406 }
2407 if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
2408#ifdef LIBXML_HTML_ENABLED
2409 if (node->type == XML_HTML_DOCUMENT_NODE)
2410 htmlDocDump(ctxt->output, (htmlDocPtr) node);
2411 else
2412 htmlNodeDumpFile(ctxt->output, ctxt->doc, node);
2413#else
2414 if (node->type == XML_DOCUMENT_NODE)
2415 xmlDocDump(ctxt->output, (xmlDocPtr) node);
2416 else
2417 xmlElemDump(ctxt->output, ctxt->doc, node);
2418#endif /* LIBXML_HTML_ENABLED */
2419 } else {
2420 if (node->type == XML_DOCUMENT_NODE)
2421 xmlDocDump(ctxt->output, (xmlDocPtr) node);
2422 else
2423 xmlElemDump(ctxt->output, ctxt->doc, node);
2424 }
2425 fprintf(ctxt->output, "\n");
2426 return (0);
2427}
2428#endif /* LIBXML_OUTPUT_ENABLED */
2429
2442int
2443xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
2446{
2447 xmlDocPtr doc;
2448 int html = 0;
2449
2450 if ((ctxt == NULL) || (filename == NULL)) return(-1);
2451 if (ctxt->doc != NULL)
2452 html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
2453
2454 if (html) {
2455#ifdef LIBXML_HTML_ENABLED
2456 doc = htmlParseFile(filename, NULL);
2457#else
2458 fprintf(ctxt->output, "HTML support not compiled in\n");
2459 doc = NULL;
2460#endif /* LIBXML_HTML_ENABLED */
2461 } else {
2462 doc = xmlReadFile(filename,NULL,0);
2463 }
2464 if (doc != NULL) {
2465 if (ctxt->loaded == 1) {
2466 xmlFreeDoc(ctxt->doc);
2467 }
2468 ctxt->loaded = 1;
2469#ifdef LIBXML_XPATH_ENABLED
2470 xmlXPathFreeContext(ctxt->pctxt);
2471#endif /* LIBXML_XPATH_ENABLED */
2472 xmlFree(ctxt->filename);
2473 ctxt->doc = doc;
2474 ctxt->node = (xmlNodePtr) doc;
2475#ifdef LIBXML_XPATH_ENABLED
2476 ctxt->pctxt = xmlXPathNewContext(doc);
2477#endif /* LIBXML_XPATH_ENABLED */
2478 ctxt->filename = (char *) xmlCanonicPath((xmlChar *) filename);
2479 } else
2480 return (-1);
2481 return (0);
2482}
2483
2484#ifdef LIBXML_OUTPUT_ENABLED
2498int
2499xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
2501{
2502 if (node == NULL)
2503 return (-1);
2504 if ((filename == NULL) || (filename[0] == 0)) {
2505 return (-1);
2506 }
2507#ifdef W_OK
2508 if (access((char *) filename, W_OK)) {
2510 "Cannot write to %s\n", filename);
2511 return (-1);
2512 }
2513#endif
2514 switch (node->type) {
2515 case XML_DOCUMENT_NODE:
2516 if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
2518 "Failed to write to %s\n", filename);
2519 return (-1);
2520 }
2521 break;
2523#ifdef LIBXML_HTML_ENABLED
2524 if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
2526 "Failed to write to %s\n", filename);
2527 return (-1);
2528 }
2529#else
2530 if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
2532 "Failed to write to %s\n", filename);
2533 return (-1);
2534 }
2535#endif /* LIBXML_HTML_ENABLED */
2536 break;
2537 default:{
2538 FILE *f;
2539
2540 f = fopen((char *) filename, "w");
2541 if (f == NULL) {
2543 "Failed to write to %s\n", filename);
2544 return (-1);
2545 }
2546 xmlElemDump(f, ctxt->doc, node);
2547 fclose(f);
2548 }
2549 }
2550 return (0);
2551}
2552
2565int
2566xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
2569{
2570 if ((ctxt == NULL) || (ctxt->doc == NULL))
2571 return (-1);
2572 if ((filename == NULL) || (filename[0] == 0))
2573 filename = ctxt->filename;
2574 if (filename == NULL)
2575 return (-1);
2576#ifdef W_OK
2577 if (access((char *) filename, W_OK)) {
2579 "Cannot save to %s\n", filename);
2580 return (-1);
2581 }
2582#endif
2583 switch (ctxt->doc->type) {
2584 case XML_DOCUMENT_NODE:
2585 if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
2587 "Failed to save to %s\n", filename);
2588 }
2589 break;
2591#ifdef LIBXML_HTML_ENABLED
2592 if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
2594 "Failed to save to %s\n", filename);
2595 }
2596#else
2597 if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
2599 "Failed to save to %s\n", filename);
2600 }
2601#endif /* LIBXML_HTML_ENABLED */
2602 break;
2603 default:
2605 "To save to subparts of a document use the 'write' command\n");
2606 return (-1);
2607
2608 }
2609 return (0);
2610}
2611#endif /* LIBXML_OUTPUT_ENABLED */
2612
2613#ifdef LIBXML_VALID_ENABLED
2627int
2628xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
2631{
2632 xmlValidCtxt vctxt;
2633 int res = -1;
2634
2635 if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1);
2636 vctxt.userData = NULL;
2637 vctxt.error = xmlGenericError;
2638 vctxt.warning = xmlGenericError;
2639
2640 if ((dtd == NULL) || (dtd[0] == 0)) {
2641 res = xmlValidateDocument(&vctxt, ctxt->doc);
2642 } else {
2643 xmlDtdPtr subset;
2644
2645 subset = xmlParseDTD(NULL, (xmlChar *) dtd);
2646 if (subset != NULL) {
2647 res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
2648
2649 xmlFreeDtd(subset);
2650 }
2651 }
2652 return (res);
2653}
2654#endif /* LIBXML_VALID_ENABLED */
2655
2669int
2670xmlShellDu(xmlShellCtxtPtr ctxt,
2673{
2675 int indent = 0, i;
2676
2677 if (!ctxt)
2678 return (-1);
2679
2680 if (tree == NULL)
2681 return (-1);
2682 node = tree;
2683 while (node != NULL) {
2684 if ((node->type == XML_DOCUMENT_NODE) ||
2685 (node->type == XML_HTML_DOCUMENT_NODE)) {
2686 fprintf(ctxt->output, "/\n");
2687 } else if (node->type == XML_ELEMENT_NODE) {
2688 for (i = 0; i < indent; i++)
2689 fprintf(ctxt->output, " ");
2690 if ((node->ns) && (node->ns->prefix))
2691 fprintf(ctxt->output, "%s:", node->ns->prefix);
2692 fprintf(ctxt->output, "%s\n", node->name);
2693 } else {
2694 }
2695
2696 /*
2697 * Browse the full subtree, deep first
2698 */
2699
2700 if ((node->type == XML_DOCUMENT_NODE) ||
2701 (node->type == XML_HTML_DOCUMENT_NODE)) {
2702 node = ((xmlDocPtr) node)->children;
2703 } else if ((node->children != NULL)
2704 && (node->type != XML_ENTITY_REF_NODE)) {
2705 /* deep first */
2706 node = node->children;
2707 indent++;
2708 } else if ((node != tree) && (node->next != NULL)) {
2709 /* then siblings */
2710 node = node->next;
2711 } else if (node != tree) {
2712 /* go up to parents->next if needed */
2713 while (node != tree) {
2714 if (node->parent != NULL) {
2715 node = node->parent;
2716 indent--;
2717 }
2718 if ((node != tree) && (node->next != NULL)) {
2719 node = node->next;
2720 break;
2721 }
2722 if (node->parent == NULL) {
2723 node = NULL;
2724 break;
2725 }
2726 if (node == tree) {
2727 node = NULL;
2728 break;
2729 }
2730 }
2731 /* exit condition */
2732 if (node == tree)
2733 node = NULL;
2734 } else
2735 node = NULL;
2736 }
2737 return (0);
2738}
2739
2754int
2755xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
2757{
2758 xmlChar *path;
2759
2760 if ((node == NULL) || (buffer == NULL))
2761 return (-1);
2762
2763 path = xmlGetNodePath(node);
2764 if (path == NULL)
2765 return (-1);
2766
2767 /*
2768 * This test prevents buffer overflow, because this routine
2769 * is only called by xmlShell, in which the second argument is
2770 * 500 chars long.
2771 * It is a dirty hack before a cleaner solution is found.
2772 * Documentation should mention that the second argument must
2773 * be at least 500 chars long, and could be stripped if too long.
2774 */
2775 snprintf(buffer, 499, "%s", path);
2776 buffer[499] = '0';
2777 xmlFree(path);
2778
2779 return (0);
2780}
2781
2793void
2794xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
2795 FILE * output)
2796{
2797 char prompt[500] = "/ > ";
2798 char *cmdline = NULL, *cur;
2799 char command[100];
2800 char arg[400];
2801 int i;
2802 xmlShellCtxtPtr ctxt;
2803 xmlXPathObjectPtr list;
2804
2805 if (doc == NULL)
2806 return;
2807 if (filename == NULL)
2808 return;
2809 if (input == NULL)
2810 return;
2811 if (output == NULL)
2812 output = stdout;
2813 ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
2814 if (ctxt == NULL)
2815 return;
2816 ctxt->loaded = 0;
2817 ctxt->doc = doc;
2818 ctxt->input = input;
2819 ctxt->output = output;
2820 ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
2821 ctxt->node = (xmlNodePtr) ctxt->doc;
2822
2824 ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
2825 if (ctxt->pctxt == NULL) {
2826 xmlFree(ctxt);
2827 return;
2828 }
2829#endif /* LIBXML_XPATH_ENABLED */
2830 while (1) {
2831 if (ctxt->node == (xmlNodePtr) ctxt->doc)
2832 snprintf(prompt, sizeof(prompt), "%s > ", "/");
2833 else if ((ctxt->node != NULL) && (ctxt->node->name) &&
2834 (ctxt->node->ns) && (ctxt->node->ns->prefix))
2835 snprintf(prompt, sizeof(prompt), "%s:%s > ",
2836 (ctxt->node->ns->prefix), ctxt->node->name);
2837 else if ((ctxt->node != NULL) && (ctxt->node->name))
2838 snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
2839 else
2840 snprintf(prompt, sizeof(prompt), "? > ");
2841 prompt[sizeof(prompt) - 1] = 0;
2842
2843 /*
2844 * Get a new command line
2845 */
2846 cmdline = ctxt->input(prompt);
2847 if (cmdline == NULL)
2848 break;
2849
2850 /*
2851 * Parse the command itself
2852 */
2853 cur = cmdline;
2854 while ((*cur == ' ') || (*cur == '\t'))
2855 cur++;
2856 i = 0;
2857 while ((*cur != ' ') && (*cur != '\t') &&
2858 (*cur != '\n') && (*cur != '\r')) {
2859 if (*cur == 0)
2860 break;
2861 command[i++] = *cur++;
2862 }
2863 command[i] = 0;
2864 if (i == 0)
2865 continue;
2866
2867 /*
2868 * Parse the argument
2869 */
2870 while ((*cur == ' ') || (*cur == '\t'))
2871 cur++;
2872 i = 0;
2873 while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
2874 if (*cur == 0)
2875 break;
2876 arg[i++] = *cur++;
2877 }
2878 arg[i] = 0;
2879
2880 /*
2881 * start interpreting the command
2882 */
2883 if (!strcmp(command, "exit"))
2884 break;
2885 if (!strcmp(command, "quit"))
2886 break;
2887 if (!strcmp(command, "bye"))
2888 break;
2889 if (!strcmp(command, "help")) {
2890 fprintf(ctxt->output, "\tbase display XML base of the node\n");
2891 fprintf(ctxt->output, "\tsetbase URI change the XML base of the node\n");
2892 fprintf(ctxt->output, "\tbye leave shell\n");
2893 fprintf(ctxt->output, "\tcat [node] display node or current node\n");
2894 fprintf(ctxt->output, "\tcd [path] change directory to path or to root\n");
2895 fprintf(ctxt->output, "\tdir [path] dumps information about the node (namespace, attributes, content)\n");
2896 fprintf(ctxt->output, "\tdu [path] show the structure of the subtree under path or the current node\n");
2897 fprintf(ctxt->output, "\texit leave shell\n");
2898 fprintf(ctxt->output, "\thelp display this help\n");
2899 fprintf(ctxt->output, "\tfree display memory usage\n");
2900 fprintf(ctxt->output, "\tload [name] load a new document with name\n");
2901 fprintf(ctxt->output, "\tls [path] list contents of path or the current directory\n");
2902 fprintf(ctxt->output, "\tset xml_fragment replace the current node content with the fragment parsed in context\n");
2903#ifdef LIBXML_XPATH_ENABLED
2904 fprintf(ctxt->output, "\txpath expr evaluate the XPath expression in that context and print the result\n");
2905 fprintf(ctxt->output, "\tsetns nsreg register a namespace to a prefix in the XPath evaluation context\n");
2906 fprintf(ctxt->output, "\t format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix)\n");
2907 fprintf(ctxt->output, "\tsetrootns register all namespace found on the root element\n");
2908 fprintf(ctxt->output, "\t the default namespace if any uses 'defaultns' prefix\n");
2909#endif /* LIBXML_XPATH_ENABLED */
2910 fprintf(ctxt->output, "\tpwd display current working directory\n");
2911 fprintf(ctxt->output, "\twhereis display absolute path of [path] or current working directory\n");
2912 fprintf(ctxt->output, "\tquit leave shell\n");
2913#ifdef LIBXML_OUTPUT_ENABLED
2914 fprintf(ctxt->output, "\tsave [name] save this document to name or the original name\n");
2915 fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n");
2916#endif /* LIBXML_OUTPUT_ENABLED */
2917#ifdef LIBXML_VALID_ENABLED
2918 fprintf(ctxt->output, "\tvalidate check the document for errors\n");
2919#endif /* LIBXML_VALID_ENABLED */
2920#ifdef LIBXML_SCHEMAS_ENABLED
2921 fprintf(ctxt->output, "\trelaxng rng validate the document against the Relax-NG schemas\n");
2922#endif
2923 fprintf(ctxt->output, "\tgrep string search for a string in the subtree\n");
2924#ifdef LIBXML_VALID_ENABLED
2925 } else if (!strcmp(command, "validate")) {
2926 xmlShellValidate(ctxt, arg, NULL, NULL);
2927#endif /* LIBXML_VALID_ENABLED */
2928 } else if (!strcmp(command, "load")) {
2929 xmlShellLoad(ctxt, arg, NULL, NULL);
2930#ifdef LIBXML_SCHEMAS_ENABLED
2931 } else if (!strcmp(command, "relaxng")) {
2932 xmlShellRNGValidate(ctxt, arg, NULL, NULL);
2933#endif
2934#ifdef LIBXML_OUTPUT_ENABLED
2935 } else if (!strcmp(command, "save")) {
2936 xmlShellSave(ctxt, arg, NULL, NULL);
2937 } else if (!strcmp(command, "write")) {
2938 if (arg[0] == 0)
2940 "Write command requires a filename argument\n");
2941 else
2942 xmlShellWrite(ctxt, arg, ctxt->node, NULL);
2943#endif /* LIBXML_OUTPUT_ENABLED */
2944 } else if (!strcmp(command, "grep")) {
2945 xmlShellGrep(ctxt, arg, ctxt->node, NULL);
2946 } else if (!strcmp(command, "free")) {
2947 if (arg[0] == 0) {
2948 xmlMemShow(ctxt->output, 0);
2949 } else {
2950 int len = 0;
2951
2952 sscanf(arg, "%d", &len);
2953 xmlMemShow(ctxt->output, len);
2954 }
2955 } else if (!strcmp(command, "pwd")) {
2956 char dir[500];
2957
2958 if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
2959 fprintf(ctxt->output, "%s\n", dir);
2960 } else if (!strcmp(command, "du")) {
2961 if (arg[0] == 0) {
2962 xmlShellDu(ctxt, NULL, ctxt->node, NULL);
2963 } else {
2964 ctxt->pctxt->node = ctxt->node;
2965#ifdef LIBXML_XPATH_ENABLED
2966 ctxt->pctxt->node = ctxt->node;
2967 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
2968#else
2969 list = NULL;
2970#endif /* LIBXML_XPATH_ENABLED */
2971 if (list != NULL) {
2972 switch (list->type) {
2973 case XPATH_UNDEFINED:
2975 "%s: no such node\n", arg);
2976 break;
2977 case XPATH_NODESET:{
2978 int indx;
2979
2980 if (list->nodesetval == NULL)
2981 break;
2982
2983 for (indx = 0;
2984 indx < list->nodesetval->nodeNr;
2985 indx++)
2986 xmlShellDu(ctxt, NULL,
2987 list->nodesetval->
2988 nodeTab[indx], NULL);
2989 break;
2990 }
2991 case XPATH_BOOLEAN:
2993 "%s is a Boolean\n", arg);
2994 break;
2995 case XPATH_NUMBER:
2997 "%s is a number\n", arg);
2998 break;
2999 case XPATH_STRING:
3001 "%s is a string\n", arg);
3002 break;
3003#ifdef LIBXML_XPTR_LOCS_ENABLED
3004 case XPATH_POINT:
3006 "%s is a point\n", arg);
3007 break;
3008 case XPATH_RANGE:
3010 "%s is a range\n", arg);
3011 break;
3012 case XPATH_LOCATIONSET:
3014 "%s is a range\n", arg);
3015 break;
3016#endif /* LIBXML_XPTR_LOCS_ENABLED */
3017 case XPATH_USERS:
3019 "%s is user-defined\n", arg);
3020 break;
3021 case XPATH_XSLT_TREE:
3023 "%s is an XSLT value tree\n",
3024 arg);
3025 break;
3026 }
3027#ifdef LIBXML_XPATH_ENABLED
3028 xmlXPathFreeObject(list);
3029#endif
3030 } else {
3032 "%s: no such node\n", arg);
3033 }
3034 ctxt->pctxt->node = NULL;
3035 }
3036 } else if (!strcmp(command, "base")) {
3037 xmlShellBase(ctxt, NULL, ctxt->node, NULL);
3038 } else if (!strcmp(command, "set")) {
3039 xmlShellSetContent(ctxt, arg, ctxt->node, NULL);
3040#ifdef LIBXML_XPATH_ENABLED
3041 } else if (!strcmp(command, "setns")) {
3042 if (arg[0] == 0) {
3044 "setns: prefix=[nsuri] required\n");
3045 } else {
3046 xmlShellRegisterNamespace(ctxt, arg, NULL, NULL);
3047 }
3048 } else if (!strcmp(command, "setrootns")) {
3050
3051 root = xmlDocGetRootElement(ctxt->doc);
3052 xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL);
3053 } else if (!strcmp(command, "xpath")) {
3054 if (arg[0] == 0) {
3056 "xpath: expression required\n");
3057 } else {
3058 ctxt->pctxt->node = ctxt->node;
3059 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3060 xmlXPathDebugDumpObject(ctxt->output, list, 0);
3061 xmlXPathFreeObject(list);
3062 }
3063#endif /* LIBXML_XPATH_ENABLED */
3064#ifdef LIBXML_TREE_ENABLED
3065 } else if (!strcmp(command, "setbase")) {
3066 xmlShellSetBase(ctxt, arg, ctxt->node, NULL);
3067#endif
3068 } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
3069 int dir = (!strcmp(command, "dir"));
3070
3071 if (arg[0] == 0) {
3072 if (dir)
3073 xmlShellDir(ctxt, NULL, ctxt->node, NULL);
3074 else
3075 xmlShellList(ctxt, NULL, ctxt->node, NULL);
3076 } else {
3077 ctxt->pctxt->node = ctxt->node;
3078#ifdef LIBXML_XPATH_ENABLED
3079 ctxt->pctxt->node = ctxt->node;
3080 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3081#else
3082 list = NULL;
3083#endif /* LIBXML_XPATH_ENABLED */
3084 if (list != NULL) {
3085 switch (list->type) {
3086 case XPATH_UNDEFINED:
3088 "%s: no such node\n", arg);
3089 break;
3090 case XPATH_NODESET:{
3091 int indx;
3092
3093 if (list->nodesetval == NULL)
3094 break;
3095
3096 for (indx = 0;
3097 indx < list->nodesetval->nodeNr;
3098 indx++) {
3099 if (dir)
3100 xmlShellDir(ctxt, NULL,
3101 list->nodesetval->
3102 nodeTab[indx], NULL);
3103 else
3104 xmlShellList(ctxt, NULL,
3105 list->nodesetval->
3106 nodeTab[indx], NULL);
3107 }
3108 break;
3109 }
3110 case XPATH_BOOLEAN:
3112 "%s is a Boolean\n", arg);
3113 break;
3114 case XPATH_NUMBER:
3116 "%s is a number\n", arg);
3117 break;
3118 case XPATH_STRING:
3120 "%s is a string\n", arg);
3121 break;
3122#ifdef LIBXML_XPTR_LOCS_ENABLED
3123 case XPATH_POINT:
3125 "%s is a point\n", arg);
3126 break;
3127 case XPATH_RANGE:
3129 "%s is a range\n", arg);
3130 break;
3131 case XPATH_LOCATIONSET:
3133 "%s is a range\n", arg);
3134 break;
3135#endif /* LIBXML_XPTR_LOCS_ENABLED */
3136 case XPATH_USERS:
3138 "%s is user-defined\n", arg);
3139 break;
3140 case XPATH_XSLT_TREE:
3142 "%s is an XSLT value tree\n",
3143 arg);
3144 break;
3145 }
3146#ifdef LIBXML_XPATH_ENABLED
3147 xmlXPathFreeObject(list);
3148#endif
3149 } else {
3151 "%s: no such node\n", arg);
3152 }
3153 ctxt->pctxt->node = NULL;
3154 }
3155 } else if (!strcmp(command, "whereis")) {
3156 char dir[500];
3157
3158 if (arg[0] == 0) {
3159 if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
3160 fprintf(ctxt->output, "%s\n", dir);
3161 } else {
3162 ctxt->pctxt->node = ctxt->node;
3163#ifdef LIBXML_XPATH_ENABLED
3164 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3165#else
3166 list = NULL;
3167#endif /* LIBXML_XPATH_ENABLED */
3168 if (list != NULL) {
3169 switch (list->type) {
3170 case XPATH_UNDEFINED:
3172 "%s: no such node\n", arg);
3173 break;
3174 case XPATH_NODESET:{
3175 int indx;
3176
3177 if (list->nodesetval == NULL)
3178 break;
3179
3180 for (indx = 0;
3181 indx < list->nodesetval->nodeNr;
3182 indx++) {
3183 if (!xmlShellPwd(ctxt, dir, list->nodesetval->
3184 nodeTab[indx], NULL))
3185 fprintf(ctxt->output, "%s\n", dir);
3186 }
3187 break;
3188 }
3189 case XPATH_BOOLEAN:
3191 "%s is a Boolean\n", arg);
3192 break;
3193 case XPATH_NUMBER:
3195 "%s is a number\n", arg);
3196 break;
3197 case XPATH_STRING:
3199 "%s is a string\n", arg);
3200 break;
3201#ifdef LIBXML_XPTR_LOCS_ENABLED
3202 case XPATH_POINT:
3204 "%s is a point\n", arg);
3205 break;
3206 case XPATH_RANGE:
3208 "%s is a range\n", arg);
3209 break;
3210 case XPATH_LOCATIONSET:
3212 "%s is a range\n", arg);
3213 break;
3214#endif /* LIBXML_XPTR_LOCS_ENABLED */
3215 case XPATH_USERS:
3217 "%s is user-defined\n", arg);
3218 break;
3219 case XPATH_XSLT_TREE:
3221 "%s is an XSLT value tree\n",
3222 arg);
3223 break;
3224 }
3225#ifdef LIBXML_XPATH_ENABLED
3226 xmlXPathFreeObject(list);
3227#endif
3228 } else {
3230 "%s: no such node\n", arg);
3231 }
3232 ctxt->pctxt->node = NULL;
3233 }
3234 } else if (!strcmp(command, "cd")) {
3235 if (arg[0] == 0) {
3236 ctxt->node = (xmlNodePtr) ctxt->doc;
3237 } else {
3238#ifdef LIBXML_XPATH_ENABLED
3239 int l;
3240
3241 ctxt->pctxt->node = ctxt->node;
3242 l = strlen(arg);
3243 if ((l >= 2) && (arg[l - 1] == '/'))
3244 arg[l - 1] = 0;
3245 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3246#else
3247 list = NULL;
3248#endif /* LIBXML_XPATH_ENABLED */
3249 if (list != NULL) {
3250 switch (list->type) {
3251 case XPATH_UNDEFINED:
3253 "%s: no such node\n", arg);
3254 break;
3255 case XPATH_NODESET:
3256 if (list->nodesetval != NULL) {
3257 if (list->nodesetval->nodeNr == 1) {
3258 ctxt->node = list->nodesetval->nodeTab[0];
3259 if ((ctxt->node != NULL) &&
3260 (ctxt->node->type ==
3263 "cannot cd to namespace\n");
3264 ctxt->node = NULL;
3265 }
3266 } else
3268 "%s is a %d Node Set\n",
3269 arg,
3270 list->nodesetval->nodeNr);
3271 } else
3273 "%s is an empty Node Set\n",
3274 arg);
3275 break;
3276 case XPATH_BOOLEAN:
3278 "%s is a Boolean\n", arg);
3279 break;
3280 case XPATH_NUMBER:
3282 "%s is a number\n", arg);
3283 break;
3284 case XPATH_STRING:
3286 "%s is a string\n", arg);
3287 break;
3288#ifdef LIBXML_XPTR_LOCS_ENABLED
3289 case XPATH_POINT:
3291 "%s is a point\n", arg);
3292 break;
3293 case XPATH_RANGE:
3295 "%s is a range\n", arg);
3296 break;
3297 case XPATH_LOCATIONSET:
3299 "%s is a range\n", arg);
3300 break;
3301#endif /* LIBXML_XPTR_LOCS_ENABLED */
3302 case XPATH_USERS:
3304 "%s is user-defined\n", arg);
3305 break;
3306 case XPATH_XSLT_TREE:
3308 "%s is an XSLT value tree\n",
3309 arg);
3310 break;
3311 }
3312#ifdef LIBXML_XPATH_ENABLED
3313 xmlXPathFreeObject(list);
3314#endif
3315 } else {
3317 "%s: no such node\n", arg);
3318 }
3319 ctxt->pctxt->node = NULL;
3320 }
3321#ifdef LIBXML_OUTPUT_ENABLED
3322 } else if (!strcmp(command, "cat")) {
3323 if (arg[0] == 0) {
3324 xmlShellCat(ctxt, NULL, ctxt->node, NULL);
3325 } else {
3326 ctxt->pctxt->node = ctxt->node;
3327#ifdef LIBXML_XPATH_ENABLED
3328 ctxt->pctxt->node = ctxt->node;
3329 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3330#else
3331 list = NULL;
3332#endif /* LIBXML_XPATH_ENABLED */
3333 if (list != NULL) {
3334 switch (list->type) {
3335 case XPATH_UNDEFINED:
3337 "%s: no such node\n", arg);
3338 break;
3339 case XPATH_NODESET:{
3340 int indx;
3341
3342 if (list->nodesetval == NULL)
3343 break;
3344
3345 for (indx = 0;
3346 indx < list->nodesetval->nodeNr;
3347 indx++) {
3348 if (i > 0)
3349 fprintf(ctxt->output, " -------\n");
3350 xmlShellCat(ctxt, NULL,
3351 list->nodesetval->
3352 nodeTab[indx], NULL);
3353 }
3354 break;
3355 }
3356 case XPATH_BOOLEAN:
3358 "%s is a Boolean\n", arg);
3359 break;
3360 case XPATH_NUMBER:
3362 "%s is a number\n", arg);
3363 break;
3364 case XPATH_STRING:
3366 "%s is a string\n", arg);
3367 break;
3368#ifdef LIBXML_XPTR_LOCS_ENABLED
3369 case XPATH_POINT:
3371 "%s is a point\n", arg);
3372 break;
3373 case XPATH_RANGE:
3375 "%s is a range\n", arg);
3376 break;
3377 case XPATH_LOCATIONSET:
3379 "%s is a range\n", arg);
3380 break;
3381#endif /* LIBXML_XPTR_LOCS_ENABLED */
3382 case XPATH_USERS:
3384 "%s is user-defined\n", arg);
3385 break;
3386 case XPATH_XSLT_TREE:
3388 "%s is an XSLT value tree\n",
3389 arg);
3390 break;
3391 }
3392#ifdef LIBXML_XPATH_ENABLED
3393 xmlXPathFreeObject(list);
3394#endif
3395 } else {
3397 "%s: no such node\n", arg);
3398 }
3399 ctxt->pctxt->node = NULL;
3400 }
3401#endif /* LIBXML_OUTPUT_ENABLED */
3402 } else {
3404 "Unknown command %s\n", command);
3405 }
3406 free(cmdline); /* not xmlFree here ! */
3407 cmdline = NULL;
3408 }
3409#ifdef LIBXML_XPATH_ENABLED
3410 xmlXPathFreeContext(ctxt->pctxt);
3411#endif /* LIBXML_XPATH_ENABLED */
3412 if (ctxt->loaded) {
3413 xmlFreeDoc(ctxt->doc);
3414 }
3415 if (ctxt->filename != NULL)
3416 xmlFree(ctxt->filename);
3417 xmlFree(ctxt);
3418 if (cmdline != NULL)
3419 free(cmdline); /* not xmlFree here ! */
3420}
3421
3422#endif /* LIBXML_XPATH_ENABLED */
3423
3424#endif /* LIBXML_DEBUG_ENABLED */
static struct _test_info results[8]
Definition: SetCursorPos.c:31
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
unsigned int dir
Definition: maze.c:112
#define msg(x)
Definition: auth_time.c:54
struct _root root
struct _tree tree
r l[0]
Definition: byte_order.h:168
Definition: list.h:37
struct list * next
Definition: list.h:38
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
static const WCHAR indent[]
Definition: object.c:1156
#define check(expected, result)
Definition: dplayx.c:32
XMLPUBFUN xmlEntityPtr XMLCALL xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name)
@ XML_EXTERNAL_GENERAL_PARSED_ENTITY
Definition: entities.h:26
@ XML_INTERNAL_PREDEFINED_ENTITY
Definition: entities.h:30
@ XML_EXTERNAL_GENERAL_UNPARSED_ENTITY
Definition: entities.h:27
@ XML_INTERNAL_GENERAL_ENTITY
Definition: entities.h:25
@ XML_INTERNAL_PARAMETER_ENTITY
Definition: entities.h:28
@ XML_EXTERNAL_PARAMETER_ENTITY
Definition: entities.h:29
xmlEntitiesTable * xmlEntitiesTablePtr
Definition: entities.h:71
FxCollectionEntry * cur
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ATTRIBUTE_UNUSED
Definition: i386-dis.c:36
@ extra
Definition: id3.c:95
#define stdout
Definition: stdio.h:99
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
const char * filename
Definition: ioapi.h:137
#define f
Definition: ke_i.h:83
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
static size_t elem
Definition: string.c:68
#define shift
Definition: input.c:1755
XMLPUBVAR const xmlChar xmlStringComment[]
XMLPUBVAR const xmlChar xmlStringTextNoenc[]
XMLPUBVAR const xmlChar xmlStringText[]
#define IS_BLANK_CH(c)
static unsigned __int64 next
Definition: rand_nt.c:6
#define list
Definition: rosglue.h:35
const WCHAR * str
#define W_OK
Definition: io.h:170
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:867
XMLPUBFUN int XMLCALL xmlDictOwns(xmlDictPtr dict, const xmlChar *str)
Definition: dict.c:1220
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:353
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:337
XMLPUBFUN void XMLCALL xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data)
Definition: hash.c:859
XMLPUBFUN xmlDocPtr XMLCALL xmlReadFile(const char *URL, const char *encoding, int options)
Definition: parser.c:15229
@ XML_PARSE_SAX1
Definition: parser.h:1102
@ XML_PARSE_NODICT
Definition: parser.h:1105
XMLPUBFUN xmlParserErrors XMLCALL xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen, int options, xmlNodePtr *lst)
Definition: parser.c:13496
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
@ XML_ATTRIBUTE_NMTOKENS
Definition: tree.h:214
@ XML_ATTRIBUTE_IDREF
Definition: tree.h:209
@ XML_ATTRIBUTE_ENTITIES
Definition: tree.h:212
@ XML_ATTRIBUTE_IDREFS
Definition: tree.h:210
@ XML_ATTRIBUTE_ID
Definition: tree.h:208
@ XML_ATTRIBUTE_NOTATION
Definition: tree.h:216
@ XML_ATTRIBUTE_ENUMERATION
Definition: tree.h:215
@ XML_ATTRIBUTE_CDATA
Definition: tree.h:207
@ XML_ATTRIBUTE_NMTOKEN
Definition: tree.h:213
@ XML_ATTRIBUTE_ENTITY
Definition: tree.h:211
XMLPUBFUN void XMLCALL xmlFreeDtd(xmlDtdPtr cur)
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
@ XML_ATTRIBUTE_REQUIRED
Definition: tree.h:227
@ XML_ATTRIBUTE_IMPLIED
Definition: tree.h:228
@ XML_ATTRIBUTE_NONE
Definition: tree.h:226
@ XML_ATTRIBUTE_FIXED
Definition: tree.h:229
xmlNode * xmlNodePtr
Definition: tree.h:488
xmlDoc * xmlDocPtr
Definition: tree.h:550
@ XML_DOCUMENT_TYPE_NODE
Definition: tree.h:169
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_ENTITY_DECL
Definition: tree.h:176
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_CDATA_SECTION_NODE
Definition: tree.h:163
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_XINCLUDE_START
Definition: tree.h:178
@ XML_ENTITY_NODE
Definition: tree.h:165
@ XML_PI_NODE
Definition: tree.h:166
@ XML_XINCLUDE_END
Definition: tree.h:179
@ XML_DOCUMENT_FRAG_NODE
Definition: tree.h:170
@ XML_COMMENT_NODE
Definition: tree.h:167
@ XML_DTD_NODE
Definition: tree.h:173
@ XML_NAMESPACE_DECL
Definition: tree.h:177
@ XML_HTML_DOCUMENT_NODE
Definition: tree.h:172
@ XML_ELEMENT_NODE
Definition: tree.h:160
@ XML_ELEMENT_DECL
Definition: tree.h:174
@ XML_ENTITY_REF_NODE
Definition: tree.h:164
@ XML_NOTATION_NODE
Definition: tree.h:171
@ XML_ATTRIBUTE_DECL
Definition: tree.h:175
xmlAttr * xmlAttrPtr
Definition: tree.h:433
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
xmlEntity * xmlEntityPtr
Definition: tree.h:49
XMLPUBFUN void XMLCALL xmlFreeNodeList(xmlNodePtr cur)
xmlNs * xmlNsPtr
Definition: tree.h:388
@ XML_ELEMENT_TYPE_MIXED
Definition: tree.h:326
@ XML_ELEMENT_TYPE_EMPTY
Definition: tree.h:324
@ XML_ELEMENT_TYPE_UNDEFINED
Definition: tree.h:323
@ XML_ELEMENT_TYPE_ELEMENT
Definition: tree.h:327
@ XML_ELEMENT_TYPE_ANY
Definition: tree.h:325
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur)
TCHAR * cmdline
Definition: stretchblt.cpp:32
Definition: tree.h:434
Definition: dict.c:111
Definition: tree.h:551
const xmlChar * URL
Definition: tree.h:577
char * name
Definition: tree.h:554
struct _xmlDtd * intSubset
Definition: tree.h:570
const xmlChar * encoding
Definition: tree.h:574
const xmlChar * version
Definition: tree.h:573
struct _xmlNs * oldNs
Definition: tree.h:572
int standalone
Definition: tree.h:564
struct _xmlDict * dict
Definition: tree.h:580
struct _xmlNode * children
Definition: tree.h:555
xmlElementType type
Definition: tree.h:553
struct _xmlDtd * extSubset
Definition: tree.h:571
Definition: tree.h:406
xmlElementType type
Definition: tree.h:408
const xmlChar * name
Definition: tree.h:409
struct _xmlNode * children
Definition: tree.h:410
const xmlChar * SystemID
Definition: tree.h:423
const xmlChar * ExternalID
Definition: tree.h:422
const xmlChar * SystemID
Definition: entities.h:54
xmlChar * content
Definition: entities.h:50
const xmlChar * URI
Definition: entities.h:57
xmlEntityType etype
Definition: entities.h:52
const xmlChar * name
Definition: entities.h:41
const xmlChar * ExternalID
Definition: entities.h:53
xmlElementType type
Definition: entities.h:40
Definition: tree.h:489
Definition: tree.h:389
Definition: cookie.c:202
WCHAR * name
Definition: cookie.c:203
Definition: name.c:39
Definition: mxnamespace.c:45
BSTR prefix
Definition: mxnamespace.c:46
Definition: dlist.c:348
void * next
Definition: dlist.c:360
Definition: pdh_main.c:94
XMLPUBFUN xmlChar *XMLCALL xmlCanonicPath(const xmlChar *path)
Definition: uri.c:2380
XMLPUBFUN void XMLCALL xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int englob)
Definition: valid.c:1285
typedeftypedef void(XMLCDECL *) typedef void(XMLCDECL *) struct _xmlValidCtx xmlValidCtxt)
Definition: valid.h:80
int ret
#define snprintf
Definition: wintirpc.h:48
@ XML_ERR_ERROR
Definition: xmlerror.h:27
@ XML_FROM_CHECK
Definition: xmlerror.h:61
xmlParserErrors
Definition: xmlerror.h:99
@ XML_CHECK_NO_DICT
Definition: xmlerror.h:825
@ XML_CHECK_NOT_NCNAME
Definition: xmlerror.h:826
@ XML_CHECK_FOUND_CDATA
Definition: xmlerror.h:795
@ XML_CHECK_FOUND_ELEMENT
Definition: xmlerror.h:792
@ XML_CHECK_FOUND_ATTRIBUTE
Definition: xmlerror.h:793
@ XML_CHECK_WRONG_NEXT
Definition: xmlerror.h:813
@ XML_ERR_OK
Definition: xmlerror.h:100
@ XML_CHECK_FOUND_PI
Definition: xmlerror.h:798
@ XML_CHECK_NO_HREF
Definition: xmlerror.h:820
@ XML_CHECK_FOUND_NOTATION
Definition: xmlerror.h:802
@ XML_CHECK_ENTITY_TYPE
Definition: xmlerror.h:804
@ XML_CHECK_NO_PARENT
Definition: xmlerror.h:805
@ XML_CHECK_FOUND_DOCTYPE
Definition: xmlerror.h:800
@ XML_CHECK_WRONG_DOC
Definition: xmlerror.h:809
@ XML_CHECK_OUTSIDE_DICT
Definition: xmlerror.h:827
@ XML_CHECK_NS_SCOPE
Definition: xmlerror.h:822
@ XML_CHECK_NO_DOC
Definition: xmlerror.h:806
@ XML_CHECK_NS_ANCESTOR
Definition: xmlerror.h:823
@ XML_CHECK_NO_PREV
Definition: xmlerror.h:810
@ XML_CHECK_NO_NEXT
Definition: xmlerror.h:812
@ XML_CHECK_WRONG_NAME
Definition: xmlerror.h:828
@ XML_CHECK_FOUND_FRAGMENT
Definition: xmlerror.h:801
@ XML_CHECK_NO_NAME
Definition: xmlerror.h:807
@ XML_CHECK_FOUND_TEXT
Definition: xmlerror.h:794
@ XML_CHECK_FOUND_COMMENT
Definition: xmlerror.h:799
@ XML_CHECK_NOT_ELEM_DECL
Definition: xmlerror.h:817
@ XML_CHECK_WRONG_PARENT
Definition: xmlerror.h:821
@ XML_CHECK_NOT_NS_DECL
Definition: xmlerror.h:819
@ XML_CHECK_NO_ELEM
Definition: xmlerror.h:808
@ XML_CHECK_FOUND_ENTITY
Definition: xmlerror.h:797
@ XML_CHECK_NOT_ATTR_DECL
Definition: xmlerror.h:816
@ XML_CHECK_NOT_UTF8
Definition: xmlerror.h:824
@ XML_CHECK_NOT_ENTITY_DECL
Definition: xmlerror.h:818
@ XML_CHECK_WRONG_PREV
Definition: xmlerror.h:811
@ XML_CHECK_FOUND_ENTITYREF
Definition: xmlerror.h:796
@ XML_CHECK_NAME_NOT_NULL
Definition: xmlerror.h:829
@ XML_CHECK_NOT_DTD
Definition: xmlerror.h:814
@ XML_CHECK_UNKNOWN_NODE
Definition: xmlerror.h:803
XMLPUBFUN void XMLCALL xmlMemShow(FILE *fp, int nr)
Definition: xmlmemory.c:865
XMLPUBFUN const xmlChar *XMLCALL xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:325
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:345
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
#define BAD_CAST
Definition: xmlstring.h:35
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160
XMLPUBFUN int XMLCALL xmlCheckUTF8(const unsigned char *utf)
Definition: xmlstring.c:779
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:426
unsigned char xmlChar
Definition: xmlstring.h:28
#define LIBXML_XPATH_ENABLED
Definition: xmlversion.h:238
#define LIBXML_ATTR_FORMAT(fmt, args)
Definition: xmlversion.h:486
#define const
Definition: zconf.h:233