ReactOS  0.4.15-dev-3303-g1ade494
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 #ifdef HAVE_STDLIB_H
16 #include <stdlib.h>
17 #endif
18 #ifdef HAVE_STRING_H
19 #include <string.h>
20 #endif
21 #include <libxml/xmlmemory.h>
22 #include <libxml/tree.h>
23 #include <libxml/parser.h>
24 #include <libxml/parserInternals.h>
25 #include <libxml/valid.h>
26 #include <libxml/debugXML.h>
27 #include <libxml/HTMLtree.h>
28 #include <libxml/HTMLparser.h>
29 #include <libxml/xmlerror.h>
30 #include <libxml/globals.h>
31 #include <libxml/xpathInternals.h>
32 #include <libxml/uri.h>
33 #ifdef LIBXML_SCHEMAS_ENABLED
34 #include <libxml/relaxng.h>
35 #endif
36 
37 #define DUMP_TEXT_TYPE 1
38 
39 typedef struct _xmlDebugCtxt xmlDebugCtxt;
40 typedef xmlDebugCtxt *xmlDebugCtxtPtr;
41 struct _xmlDebugCtxt {
42  FILE *output; /* the output file */
43  char shift[101]; /* used for indenting */
44  int depth; /* current depth */
45  xmlDocPtr doc; /* current document */
46  xmlNodePtr node; /* current node */
47  xmlDictPtr dict; /* the doc dictionary */
48  int check; /* do just checkings */
49  int errors; /* number of errors found */
50  int nodict; /* if the document has no dictionary */
51  int options; /* options */
52 };
53 
54 static void xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node);
55 
56 static void
57 xmlCtxtDumpInitCtxt(xmlDebugCtxtPtr ctxt)
58 {
59  int i;
60 
61  ctxt->depth = 0;
62  ctxt->check = 0;
63  ctxt->errors = 0;
64  ctxt->output = stdout;
65  ctxt->doc = NULL;
66  ctxt->node = NULL;
67  ctxt->dict = NULL;
68  ctxt->nodict = 0;
69  ctxt->options = 0;
70  for (i = 0; i < 100; i++)
71  ctxt->shift[i] = ' ';
72  ctxt->shift[100] = 0;
73 }
74 
75 static void
76 xmlCtxtDumpCleanCtxt(xmlDebugCtxtPtr ctxt ATTRIBUTE_UNUSED)
77 {
78  /* remove the ATTRIBUTE_UNUSED when this is added */
79 }
80 
92 static int
93 xmlNsCheckScope(xmlNodePtr node, xmlNsPtr ns)
94 {
95  xmlNsPtr cur;
96 
97  if ((node == NULL) || (ns == NULL))
98  return(-1);
99 
100  if ((node->type != XML_ELEMENT_NODE) &&
101  (node->type != XML_ATTRIBUTE_NODE) &&
102  (node->type != XML_DOCUMENT_NODE) &&
103  (node->type != XML_TEXT_NODE) &&
104  (node->type != XML_HTML_DOCUMENT_NODE) &&
105  (node->type != XML_XINCLUDE_START))
106  return(-2);
107 
108  while ((node != NULL) &&
109  ((node->type == XML_ELEMENT_NODE) ||
110  (node->type == XML_ATTRIBUTE_NODE) ||
111  (node->type == XML_TEXT_NODE) ||
112  (node->type == XML_XINCLUDE_START))) {
113  if ((node->type == XML_ELEMENT_NODE) ||
114  (node->type == XML_XINCLUDE_START)) {
115  cur = node->nsDef;
116  while (cur != NULL) {
117  if (cur == ns)
118  return(1);
119  if (xmlStrEqual(cur->prefix, ns->prefix))
120  return(-2);
121  cur = cur->next;
122  }
123  }
124  node = node->parent;
125  }
126  /* the xml namespace may be declared on the document node */
127  if ((node != NULL) &&
128  ((node->type == XML_DOCUMENT_NODE) ||
129  (node->type == XML_HTML_DOCUMENT_NODE))) {
130  xmlNsPtr oldNs = ((xmlDocPtr) node)->oldNs;
131  if (oldNs == ns)
132  return(1);
133  }
134  return(-3);
135 }
136 
137 static void
138 xmlCtxtDumpSpaces(xmlDebugCtxtPtr ctxt)
139 {
140  if (ctxt->check)
141  return;
142  if ((ctxt->output != NULL) && (ctxt->depth > 0)) {
143  if (ctxt->depth < 50)
144  fprintf(ctxt->output, "%s", &ctxt->shift[100 - 2 * ctxt->depth]);
145  else
146  fprintf(ctxt->output, "%s", ctxt->shift);
147  }
148 }
149 
157 static void
158 xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg)
159 {
160  ctxt->errors++;
161  __xmlRaiseError(NULL, NULL, NULL,
162  NULL, ctxt->node, XML_FROM_CHECK,
163  error, XML_ERR_ERROR, NULL, 0,
164  NULL, NULL, NULL, 0, 0,
165  "%s", msg);
166 }
167 static void LIBXML_ATTR_FORMAT(3,0)
168 xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
169 {
170  ctxt->errors++;
171  __xmlRaiseError(NULL, NULL, NULL,
172  NULL, ctxt->node, XML_FROM_CHECK,
173  error, XML_ERR_ERROR, NULL, 0,
174  NULL, NULL, NULL, 0, 0,
175  msg, extra);
176 }
177 static void LIBXML_ATTR_FORMAT(3,0)
178 xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
179 {
180  ctxt->errors++;
181  __xmlRaiseError(NULL, NULL, NULL,
182  NULL, ctxt->node, XML_FROM_CHECK,
183  error, XML_ERR_ERROR, NULL, 0,
184  NULL, NULL, NULL, 0, 0,
185  msg, extra);
186 }
187 
196 static void
197 xmlCtxtNsCheckScope(xmlDebugCtxtPtr ctxt, xmlNodePtr node, xmlNsPtr ns)
198 {
199  int ret;
200 
201  ret = xmlNsCheckScope(node, ns);
202  if (ret == -2) {
203  if (ns->prefix == NULL)
204  xmlDebugErr(ctxt, XML_CHECK_NS_SCOPE,
205  "Reference to default namespace not in scope\n");
206  else
207  xmlDebugErr3(ctxt, XML_CHECK_NS_SCOPE,
208  "Reference to namespace '%s' not in scope\n",
209  (char *) ns->prefix);
210  }
211  if (ret == -3) {
212  if (ns->prefix == NULL)
213  xmlDebugErr(ctxt, XML_CHECK_NS_ANCESTOR,
214  "Reference to default namespace not on ancestor\n");
215  else
216  xmlDebugErr3(ctxt, XML_CHECK_NS_ANCESTOR,
217  "Reference to namespace '%s' not on ancestor\n",
218  (char *) ns->prefix);
219  }
220 }
221 
229 static void
230 xmlCtxtCheckString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
231 {
232  if (str == NULL) return;
233  if (ctxt->check) {
234  if (!xmlCheckUTF8(str)) {
235  xmlDebugErr3(ctxt, XML_CHECK_NOT_UTF8,
236  "String is not UTF-8 %s", (const char *) str);
237  }
238  }
239 }
240 
249 static void
250 xmlCtxtCheckName(xmlDebugCtxtPtr ctxt, const xmlChar * name)
251 {
252  if (ctxt->check) {
253  if (name == NULL) {
254  xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL");
255  return;
256  }
257 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
258  if (xmlValidateName(name, 0)) {
259  xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
260  "Name is not an NCName '%s'", (const char *) name);
261  }
262 #endif
263  if ((ctxt->dict != NULL) &&
264  (!xmlDictOwns(ctxt->dict, name)) &&
265  ((ctxt->doc == NULL) ||
266  ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) {
267  xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT,
268  "Name is not from the document dictionary '%s'",
269  (const char *) name);
270  }
271  }
272 }
273 
274 static void
275 xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) {
276  xmlDocPtr doc;
277  xmlDictPtr dict;
278 
279  doc = node->doc;
280 
281  if (node->parent == NULL)
282  xmlDebugErr(ctxt, XML_CHECK_NO_PARENT,
283  "Node has no parent\n");
284  if (node->doc == NULL) {
285  xmlDebugErr(ctxt, XML_CHECK_NO_DOC,
286  "Node has no doc\n");
287  dict = NULL;
288  } else {
289  dict = doc->dict;
290  if ((dict == NULL) && (ctxt->nodict == 0)) {
291 #if 0
292  /* deactivated right now as it raises too many errors */
293  if (doc->type == XML_DOCUMENT_NODE)
294  xmlDebugErr(ctxt, XML_CHECK_NO_DICT,
295  "Document has no dictionary\n");
296 #endif
297  ctxt->nodict = 1;
298  }
299  if (ctxt->doc == NULL)
300  ctxt->doc = doc;
301 
302  if (ctxt->dict == NULL) {
303  ctxt->dict = dict;
304  }
305  }
306  if ((node->parent != NULL) && (node->doc != node->parent->doc) &&
307  (!xmlStrEqual(node->name, BAD_CAST "pseudoroot")))
308  xmlDebugErr(ctxt, XML_CHECK_WRONG_DOC,
309  "Node doc differs from parent's one\n");
310  if (node->prev == NULL) {
311  if (node->type == XML_ATTRIBUTE_NODE) {
312  if ((node->parent != NULL) &&
313  (node != (xmlNodePtr) node->parent->properties))
314  xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
315  "Attr has no prev and not first of attr list\n");
316 
317  } else if ((node->parent != NULL) && (node->parent->children != node))
318  xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
319  "Node has no prev and not first of parent list\n");
320  } else {
321  if (node->prev->next != node)
322  xmlDebugErr(ctxt, XML_CHECK_WRONG_PREV,
323  "Node prev->next : back link wrong\n");
324  }
325  if (node->next == NULL) {
326  if ((node->parent != NULL) && (node->type != XML_ATTRIBUTE_NODE) &&
327  (node->parent->last != node) &&
328  (node->parent->type == XML_ELEMENT_NODE))
329  xmlDebugErr(ctxt, XML_CHECK_NO_NEXT,
330  "Node has no next and not last of parent list\n");
331  } else {
332  if (node->next->prev != node)
333  xmlDebugErr(ctxt, XML_CHECK_WRONG_NEXT,
334  "Node next->prev : forward link wrong\n");
335  if (node->next->parent != node->parent)
336  xmlDebugErr(ctxt, XML_CHECK_WRONG_PARENT,
337  "Node next->prev : forward link wrong\n");
338  }
339  if (node->type == XML_ELEMENT_NODE) {
340  xmlNsPtr ns;
341 
342  ns = node->nsDef;
343  while (ns != NULL) {
344  xmlCtxtNsCheckScope(ctxt, node, ns);
345  ns = ns->next;
346  }
347  if (node->ns != NULL)
348  xmlCtxtNsCheckScope(ctxt, node, node->ns);
349  } else if (node->type == XML_ATTRIBUTE_NODE) {
350  if (node->ns != NULL)
351  xmlCtxtNsCheckScope(ctxt, node, node->ns);
352  }
353 
354  if ((node->type != XML_ELEMENT_NODE) &&
355  (node->type != XML_ATTRIBUTE_NODE) &&
356  (node->type != XML_ELEMENT_DECL) &&
357  (node->type != XML_ATTRIBUTE_DECL) &&
358  (node->type != XML_DTD_NODE) &&
359  (node->type != XML_HTML_DOCUMENT_NODE) &&
360  (node->type != XML_DOCUMENT_NODE)) {
361  if (node->content != NULL)
362  xmlCtxtCheckString(ctxt, (const xmlChar *) node->content);
363  }
364  switch (node->type) {
365  case XML_ELEMENT_NODE:
366  case XML_ATTRIBUTE_NODE:
367  xmlCtxtCheckName(ctxt, node->name);
368  break;
369  case XML_TEXT_NODE:
370  if ((node->name == xmlStringText) ||
371  (node->name == xmlStringTextNoenc))
372  break;
373  /* some case of entity substitution can lead to this */
374  if ((ctxt->dict != NULL) &&
375  (node->name == xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
376  7)))
377  break;
378 
379  xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
380  "Text node has wrong name '%s'",
381  (const char *) node->name);
382  break;
383  case XML_COMMENT_NODE:
384  if (node->name == xmlStringComment)
385  break;
386  xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
387  "Comment node has wrong name '%s'",
388  (const char *) node->name);
389  break;
390  case XML_PI_NODE:
391  xmlCtxtCheckName(ctxt, node->name);
392  break;
394  if (node->name == NULL)
395  break;
396  xmlDebugErr3(ctxt, XML_CHECK_NAME_NOT_NULL,
397  "CData section has non NULL name '%s'",
398  (const char *) node->name);
399  break;
400  case XML_ENTITY_REF_NODE:
401  case XML_ENTITY_NODE:
404  case XML_NOTATION_NODE:
405  case XML_DTD_NODE:
406  case XML_ELEMENT_DECL:
407  case XML_ATTRIBUTE_DECL:
408  case XML_ENTITY_DECL:
409  case XML_NAMESPACE_DECL:
410  case XML_XINCLUDE_START:
411  case XML_XINCLUDE_END:
412 #ifdef LIBXML_DOCB_ENABLED
413  case XML_DOCB_DOCUMENT_NODE:
414 #endif
415  case XML_DOCUMENT_NODE:
417  break;
418  }
419 }
420 
421 static void
422 xmlCtxtDumpString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
423 {
424  int i;
425 
426  if (ctxt->check) {
427  return;
428  }
429  /* TODO: check UTF8 content of the string */
430  if (str == NULL) {
431  fprintf(ctxt->output, "(NULL)");
432  return;
433  }
434  for (i = 0; i < 40; i++)
435  if (str[i] == 0)
436  return;
437  else if (IS_BLANK_CH(str[i]))
438  fputc(' ', ctxt->output);
439  else if (str[i] >= 0x80)
440  fprintf(ctxt->output, "#%X", str[i]);
441  else
442  fputc(str[i], ctxt->output);
443  fprintf(ctxt->output, "...");
444 }
445 
446 static void
447 xmlCtxtDumpDtdNode(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
448 {
449  xmlCtxtDumpSpaces(ctxt);
450 
451  if (dtd == NULL) {
452  if (!ctxt->check)
453  fprintf(ctxt->output, "DTD node is NULL\n");
454  return;
455  }
456 
457  if (dtd->type != XML_DTD_NODE) {
458  xmlDebugErr(ctxt, XML_CHECK_NOT_DTD,
459  "Node is not a DTD");
460  return;
461  }
462  if (!ctxt->check) {
463  if (dtd->name != NULL)
464  fprintf(ctxt->output, "DTD(%s)", (char *) dtd->name);
465  else
466  fprintf(ctxt->output, "DTD");
467  if (dtd->ExternalID != NULL)
468  fprintf(ctxt->output, ", PUBLIC %s", (char *) dtd->ExternalID);
469  if (dtd->SystemID != NULL)
470  fprintf(ctxt->output, ", SYSTEM %s", (char *) dtd->SystemID);
471  fprintf(ctxt->output, "\n");
472  }
473  /*
474  * Do a bit of checking
475  */
476  xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) dtd);
477 }
478 
479 static void
480 xmlCtxtDumpAttrDecl(xmlDebugCtxtPtr ctxt, xmlAttributePtr attr)
481 {
482  xmlCtxtDumpSpaces(ctxt);
483 
484  if (attr == NULL) {
485  if (!ctxt->check)
486  fprintf(ctxt->output, "Attribute declaration is NULL\n");
487  return;
488  }
489  if (attr->type != XML_ATTRIBUTE_DECL) {
490  xmlDebugErr(ctxt, XML_CHECK_NOT_ATTR_DECL,
491  "Node is not an attribute declaration");
492  return;
493  }
494  if (attr->name != NULL) {
495  if (!ctxt->check)
496  fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name);
497  } else
498  xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
499  "Node attribute declaration has no name");
500  if (attr->elem != NULL) {
501  if (!ctxt->check)
502  fprintf(ctxt->output, " for %s", (char *) attr->elem);
503  } else
504  xmlDebugErr(ctxt, XML_CHECK_NO_ELEM,
505  "Node attribute declaration has no element name");
506  if (!ctxt->check) {
507  switch (attr->atype) {
508  case XML_ATTRIBUTE_CDATA:
509  fprintf(ctxt->output, " CDATA");
510  break;
511  case XML_ATTRIBUTE_ID:
512  fprintf(ctxt->output, " ID");
513  break;
514  case XML_ATTRIBUTE_IDREF:
515  fprintf(ctxt->output, " IDREF");
516  break;
518  fprintf(ctxt->output, " IDREFS");
519  break;
521  fprintf(ctxt->output, " ENTITY");
522  break;
524  fprintf(ctxt->output, " ENTITIES");
525  break;
527  fprintf(ctxt->output, " NMTOKEN");
528  break;
530  fprintf(ctxt->output, " NMTOKENS");
531  break;
533  fprintf(ctxt->output, " ENUMERATION");
534  break;
536  fprintf(ctxt->output, " NOTATION ");
537  break;
538  }
539  if (attr->tree != NULL) {
540  int indx;
541  xmlEnumerationPtr cur = attr->tree;
542 
543  for (indx = 0; indx < 5; indx++) {
544  if (indx != 0)
545  fprintf(ctxt->output, "|%s", (char *) cur->name);
546  else
547  fprintf(ctxt->output, " (%s", (char *) cur->name);
548  cur = cur->next;
549  if (cur == NULL)
550  break;
551  }
552  if (cur == NULL)
553  fprintf(ctxt->output, ")");
554  else
555  fprintf(ctxt->output, "...)");
556  }
557  switch (attr->def) {
558  case XML_ATTRIBUTE_NONE:
559  break;
561  fprintf(ctxt->output, " REQUIRED");
562  break;
564  fprintf(ctxt->output, " IMPLIED");
565  break;
566  case XML_ATTRIBUTE_FIXED:
567  fprintf(ctxt->output, " FIXED");
568  break;
569  }
570  if (attr->defaultValue != NULL) {
571  fprintf(ctxt->output, "\"");
572  xmlCtxtDumpString(ctxt, attr->defaultValue);
573  fprintf(ctxt->output, "\"");
574  }
575  fprintf(ctxt->output, "\n");
576  }
577 
578  /*
579  * Do a bit of checking
580  */
581  xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
582 }
583 
584 static void
585 xmlCtxtDumpElemDecl(xmlDebugCtxtPtr ctxt, xmlElementPtr elem)
586 {
587  xmlCtxtDumpSpaces(ctxt);
588 
589  if (elem == NULL) {
590  if (!ctxt->check)
591  fprintf(ctxt->output, "Element declaration is NULL\n");
592  return;
593  }
594  if (elem->type != XML_ELEMENT_DECL) {
595  xmlDebugErr(ctxt, XML_CHECK_NOT_ELEM_DECL,
596  "Node is not an element declaration");
597  return;
598  }
599  if (elem->name != NULL) {
600  if (!ctxt->check) {
601  fprintf(ctxt->output, "ELEMDECL(");
602  xmlCtxtDumpString(ctxt, elem->name);
603  fprintf(ctxt->output, ")");
604  }
605  } else
606  xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
607  "Element declaration has no name");
608  if (!ctxt->check) {
609  switch (elem->etype) {
611  fprintf(ctxt->output, ", UNDEFINED");
612  break;
614  fprintf(ctxt->output, ", EMPTY");
615  break;
617  fprintf(ctxt->output, ", ANY");
618  break;
620  fprintf(ctxt->output, ", MIXED ");
621  break;
623  fprintf(ctxt->output, ", MIXED ");
624  break;
625  }
626  if ((elem->type != XML_ELEMENT_NODE) && (elem->content != NULL)) {
627  char buf[5001];
628 
629  buf[0] = 0;
630  xmlSnprintfElementContent(buf, 5000, elem->content, 1);
631  buf[5000] = 0;
632  fprintf(ctxt->output, "%s", buf);
633  }
634  fprintf(ctxt->output, "\n");
635  }
636 
637  /*
638  * Do a bit of checking
639  */
640  xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) elem);
641 }
642 
643 static void
644 xmlCtxtDumpEntityDecl(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
645 {
646  xmlCtxtDumpSpaces(ctxt);
647 
648  if (ent == NULL) {
649  if (!ctxt->check)
650  fprintf(ctxt->output, "Entity declaration is NULL\n");
651  return;
652  }
653  if (ent->type != XML_ENTITY_DECL) {
654  xmlDebugErr(ctxt, XML_CHECK_NOT_ENTITY_DECL,
655  "Node is not an entity declaration");
656  return;
657  }
658  if (ent->name != NULL) {
659  if (!ctxt->check) {
660  fprintf(ctxt->output, "ENTITYDECL(");
661  xmlCtxtDumpString(ctxt, ent->name);
662  fprintf(ctxt->output, ")");
663  }
664  } else
665  xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
666  "Entity declaration has no name");
667  if (!ctxt->check) {
668  switch (ent->etype) {
670  fprintf(ctxt->output, ", internal\n");
671  break;
673  fprintf(ctxt->output, ", external parsed\n");
674  break;
676  fprintf(ctxt->output, ", unparsed\n");
677  break;
679  fprintf(ctxt->output, ", parameter\n");
680  break;
682  fprintf(ctxt->output, ", external parameter\n");
683  break;
685  fprintf(ctxt->output, ", predefined\n");
686  break;
687  }
688  if (ent->ExternalID) {
689  xmlCtxtDumpSpaces(ctxt);
690  fprintf(ctxt->output, " ExternalID=%s\n",
691  (char *) ent->ExternalID);
692  }
693  if (ent->SystemID) {
694  xmlCtxtDumpSpaces(ctxt);
695  fprintf(ctxt->output, " SystemID=%s\n",
696  (char *) ent->SystemID);
697  }
698  if (ent->URI != NULL) {
699  xmlCtxtDumpSpaces(ctxt);
700  fprintf(ctxt->output, " URI=%s\n", (char *) ent->URI);
701  }
702  if (ent->content) {
703  xmlCtxtDumpSpaces(ctxt);
704  fprintf(ctxt->output, " content=");
705  xmlCtxtDumpString(ctxt, ent->content);
706  fprintf(ctxt->output, "\n");
707  }
708  }
709 
710  /*
711  * Do a bit of checking
712  */
713  xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) ent);
714 }
715 
716 static void
717 xmlCtxtDumpNamespace(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
718 {
719  xmlCtxtDumpSpaces(ctxt);
720 
721  if (ns == NULL) {
722  if (!ctxt->check)
723  fprintf(ctxt->output, "namespace node is NULL\n");
724  return;
725  }
726  if (ns->type != XML_NAMESPACE_DECL) {
727  xmlDebugErr(ctxt, XML_CHECK_NOT_NS_DECL,
728  "Node is not a namespace declaration");
729  return;
730  }
731  if (ns->href == NULL) {
732  if (ns->prefix != NULL)
733  xmlDebugErr3(ctxt, XML_CHECK_NO_HREF,
734  "Incomplete namespace %s href=NULL\n",
735  (char *) ns->prefix);
736  else
737  xmlDebugErr(ctxt, XML_CHECK_NO_HREF,
738  "Incomplete default namespace href=NULL\n");
739  } else {
740  if (!ctxt->check) {
741  if (ns->prefix != NULL)
742  fprintf(ctxt->output, "namespace %s href=",
743  (char *) ns->prefix);
744  else
745  fprintf(ctxt->output, "default namespace href=");
746 
747  xmlCtxtDumpString(ctxt, ns->href);
748  fprintf(ctxt->output, "\n");
749  }
750  }
751 }
752 
753 static void
754 xmlCtxtDumpNamespaceList(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
755 {
756  while (ns != NULL) {
757  xmlCtxtDumpNamespace(ctxt, ns);
758  ns = ns->next;
759  }
760 }
761 
762 static void
763 xmlCtxtDumpEntity(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
764 {
765  xmlCtxtDumpSpaces(ctxt);
766 
767  if (ent == NULL) {
768  if (!ctxt->check)
769  fprintf(ctxt->output, "Entity is NULL\n");
770  return;
771  }
772  if (!ctxt->check) {
773  switch (ent->etype) {
775  fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY ");
776  break;
778  fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
779  break;
781  fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
782  break;
784  fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY ");
785  break;
787  fprintf(ctxt->output, "EXTERNAL_PARAMETER_ENTITY ");
788  break;
789  default:
790  fprintf(ctxt->output, "ENTITY_%d ! ", (int) ent->etype);
791  }
792  fprintf(ctxt->output, "%s\n", ent->name);
793  if (ent->ExternalID) {
794  xmlCtxtDumpSpaces(ctxt);
795  fprintf(ctxt->output, "ExternalID=%s\n",
796  (char *) ent->ExternalID);
797  }
798  if (ent->SystemID) {
799  xmlCtxtDumpSpaces(ctxt);
800  fprintf(ctxt->output, "SystemID=%s\n", (char *) ent->SystemID);
801  }
802  if (ent->URI) {
803  xmlCtxtDumpSpaces(ctxt);
804  fprintf(ctxt->output, "URI=%s\n", (char *) ent->URI);
805  }
806  if (ent->content) {
807  xmlCtxtDumpSpaces(ctxt);
808  fprintf(ctxt->output, "content=");
809  xmlCtxtDumpString(ctxt, ent->content);
810  fprintf(ctxt->output, "\n");
811  }
812  }
813 }
814 
823 static void
824 xmlCtxtDumpAttr(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
825 {
826  xmlCtxtDumpSpaces(ctxt);
827 
828  if (attr == NULL) {
829  if (!ctxt->check)
830  fprintf(ctxt->output, "Attr is NULL");
831  return;
832  }
833  if (!ctxt->check) {
834  fprintf(ctxt->output, "ATTRIBUTE ");
835  xmlCtxtDumpString(ctxt, attr->name);
836  fprintf(ctxt->output, "\n");
837  if (attr->children != NULL) {
838  ctxt->depth++;
839  xmlCtxtDumpNodeList(ctxt, attr->children);
840  ctxt->depth--;
841  }
842  }
843  if (attr->name == NULL)
844  xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
845  "Attribute has no name");
846 
847  /*
848  * Do a bit of checking
849  */
850  xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
851 }
852 
861 static void
862 xmlCtxtDumpAttrList(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
863 {
864  while (attr != NULL) {
865  xmlCtxtDumpAttr(ctxt, attr);
866  attr = attr->next;
867  }
868 }
869 
878 static void
879 xmlCtxtDumpOneNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
880 {
881  if (node == NULL) {
882  if (!ctxt->check) {
883  xmlCtxtDumpSpaces(ctxt);
884  fprintf(ctxt->output, "node is NULL\n");
885  }
886  return;
887  }
888  ctxt->node = node;
889 
890  switch (node->type) {
891  case XML_ELEMENT_NODE:
892  if (!ctxt->check) {
893  xmlCtxtDumpSpaces(ctxt);
894  fprintf(ctxt->output, "ELEMENT ");
895  if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
896  xmlCtxtDumpString(ctxt, node->ns->prefix);
897  fprintf(ctxt->output, ":");
898  }
899  xmlCtxtDumpString(ctxt, node->name);
900  fprintf(ctxt->output, "\n");
901  }
902  break;
903  case XML_ATTRIBUTE_NODE:
904  if (!ctxt->check)
905  xmlCtxtDumpSpaces(ctxt);
906  fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
907  xmlCtxtGenericNodeCheck(ctxt, node);
908  return;
909  case XML_TEXT_NODE:
910  if (!ctxt->check) {
911  xmlCtxtDumpSpaces(ctxt);
912  if (node->name == (const xmlChar *) xmlStringTextNoenc)
913  fprintf(ctxt->output, "TEXT no enc");
914  else
915  fprintf(ctxt->output, "TEXT");
916  if (ctxt->options & DUMP_TEXT_TYPE) {
917  if (node->content == (xmlChar *) &(node->properties))
918  fprintf(ctxt->output, " compact\n");
919  else if (xmlDictOwns(ctxt->dict, node->content) == 1)
920  fprintf(ctxt->output, " interned\n");
921  else
922  fprintf(ctxt->output, "\n");
923  } else
924  fprintf(ctxt->output, "\n");
925  }
926  break;
928  if (!ctxt->check) {
929  xmlCtxtDumpSpaces(ctxt);
930  fprintf(ctxt->output, "CDATA_SECTION\n");
931  }
932  break;
933  case XML_ENTITY_REF_NODE:
934  if (!ctxt->check) {
935  xmlCtxtDumpSpaces(ctxt);
936  fprintf(ctxt->output, "ENTITY_REF(%s)\n",
937  (char *) node->name);
938  }
939  break;
940  case XML_ENTITY_NODE:
941  if (!ctxt->check) {
942  xmlCtxtDumpSpaces(ctxt);
943  fprintf(ctxt->output, "ENTITY\n");
944  }
945  break;
946  case XML_PI_NODE:
947  if (!ctxt->check) {
948  xmlCtxtDumpSpaces(ctxt);
949  fprintf(ctxt->output, "PI %s\n", (char *) node->name);
950  }
951  break;
952  case XML_COMMENT_NODE:
953  if (!ctxt->check) {
954  xmlCtxtDumpSpaces(ctxt);
955  fprintf(ctxt->output, "COMMENT\n");
956  }
957  break;
958  case XML_DOCUMENT_NODE:
960  if (!ctxt->check) {
961  xmlCtxtDumpSpaces(ctxt);
962  }
963  fprintf(ctxt->output, "Error, DOCUMENT found here\n");
964  xmlCtxtGenericNodeCheck(ctxt, node);
965  return;
967  if (!ctxt->check) {
968  xmlCtxtDumpSpaces(ctxt);
969  fprintf(ctxt->output, "DOCUMENT_TYPE\n");
970  }
971  break;
973  if (!ctxt->check) {
974  xmlCtxtDumpSpaces(ctxt);
975  fprintf(ctxt->output, "DOCUMENT_FRAG\n");
976  }
977  break;
978  case XML_NOTATION_NODE:
979  if (!ctxt->check) {
980  xmlCtxtDumpSpaces(ctxt);
981  fprintf(ctxt->output, "NOTATION\n");
982  }
983  break;
984  case XML_DTD_NODE:
985  xmlCtxtDumpDtdNode(ctxt, (xmlDtdPtr) node);
986  return;
987  case XML_ELEMENT_DECL:
988  xmlCtxtDumpElemDecl(ctxt, (xmlElementPtr) node);
989  return;
990  case XML_ATTRIBUTE_DECL:
991  xmlCtxtDumpAttrDecl(ctxt, (xmlAttributePtr) node);
992  return;
993  case XML_ENTITY_DECL:
994  xmlCtxtDumpEntityDecl(ctxt, (xmlEntityPtr) node);
995  return;
996  case XML_NAMESPACE_DECL:
997  xmlCtxtDumpNamespace(ctxt, (xmlNsPtr) node);
998  return;
999  case XML_XINCLUDE_START:
1000  if (!ctxt->check) {
1001  xmlCtxtDumpSpaces(ctxt);
1002  fprintf(ctxt->output, "INCLUDE START\n");
1003  }
1004  return;
1005  case XML_XINCLUDE_END:
1006  if (!ctxt->check) {
1007  xmlCtxtDumpSpaces(ctxt);
1008  fprintf(ctxt->output, "INCLUDE END\n");
1009  }
1010  return;
1011  default:
1012  if (!ctxt->check)
1013  xmlCtxtDumpSpaces(ctxt);
1014  xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
1015  "Unknown node type %d\n", node->type);
1016  return;
1017  }
1018  if (node->doc == NULL) {
1019  if (!ctxt->check) {
1020  xmlCtxtDumpSpaces(ctxt);
1021  }
1022  fprintf(ctxt->output, "PBM: doc == NULL !!!\n");
1023  }
1024  ctxt->depth++;
1025  if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
1026  xmlCtxtDumpNamespaceList(ctxt, node->nsDef);
1027  if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
1028  xmlCtxtDumpAttrList(ctxt, node->properties);
1029  if (node->type != XML_ENTITY_REF_NODE) {
1030  if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
1031  if (!ctxt->check) {
1032  xmlCtxtDumpSpaces(ctxt);
1033  fprintf(ctxt->output, "content=");
1034  xmlCtxtDumpString(ctxt, node->content);
1035  fprintf(ctxt->output, "\n");
1036  }
1037  }
1038  } else {
1039  xmlEntityPtr ent;
1040 
1041  ent = xmlGetDocEntity(node->doc, node->name);
1042  if (ent != NULL)
1043  xmlCtxtDumpEntity(ctxt, ent);
1044  }
1045  ctxt->depth--;
1046 
1047  /*
1048  * Do a bit of checking
1049  */
1050  xmlCtxtGenericNodeCheck(ctxt, node);
1051 }
1052 
1061 static void
1062 xmlCtxtDumpNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
1063 {
1064  if (node == NULL) {
1065  if (!ctxt->check) {
1066  xmlCtxtDumpSpaces(ctxt);
1067  fprintf(ctxt->output, "node is NULL\n");
1068  }
1069  return;
1070  }
1071  xmlCtxtDumpOneNode(ctxt, node);
1072  if ((node->type != XML_NAMESPACE_DECL) &&
1073  (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
1074  ctxt->depth++;
1075  xmlCtxtDumpNodeList(ctxt, node->children);
1076  ctxt->depth--;
1077  }
1078 }
1079 
1088 static void
1089 xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
1090 {
1091  while (node != NULL) {
1092  xmlCtxtDumpNode(ctxt, node);
1093  node = node->next;
1094  }
1095 }
1096 
1097 static void
1098 xmlCtxtDumpDocHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1099 {
1100  if (doc == NULL) {
1101  if (!ctxt->check)
1102  fprintf(ctxt->output, "DOCUMENT == NULL !\n");
1103  return;
1104  }
1105  ctxt->node = (xmlNodePtr) doc;
1106 
1107  switch (doc->type) {
1108  case XML_ELEMENT_NODE:
1109  xmlDebugErr(ctxt, XML_CHECK_FOUND_ELEMENT,
1110  "Misplaced ELEMENT node\n");
1111  break;
1112  case XML_ATTRIBUTE_NODE:
1113  xmlDebugErr(ctxt, XML_CHECK_FOUND_ATTRIBUTE,
1114  "Misplaced ATTRIBUTE node\n");
1115  break;
1116  case XML_TEXT_NODE:
1117  xmlDebugErr(ctxt, XML_CHECK_FOUND_TEXT,
1118  "Misplaced TEXT node\n");
1119  break;
1121  xmlDebugErr(ctxt, XML_CHECK_FOUND_CDATA,
1122  "Misplaced CDATA node\n");
1123  break;
1124  case XML_ENTITY_REF_NODE:
1125  xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITYREF,
1126  "Misplaced ENTITYREF node\n");
1127  break;
1128  case XML_ENTITY_NODE:
1129  xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITY,
1130  "Misplaced ENTITY node\n");
1131  break;
1132  case XML_PI_NODE:
1133  xmlDebugErr(ctxt, XML_CHECK_FOUND_PI,
1134  "Misplaced PI node\n");
1135  break;
1136  case XML_COMMENT_NODE:
1137  xmlDebugErr(ctxt, XML_CHECK_FOUND_COMMENT,
1138  "Misplaced COMMENT node\n");
1139  break;
1140  case XML_DOCUMENT_NODE:
1141  if (!ctxt->check)
1142  fprintf(ctxt->output, "DOCUMENT\n");
1143  break;
1145  if (!ctxt->check)
1146  fprintf(ctxt->output, "HTML DOCUMENT\n");
1147  break;
1149  xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE,
1150  "Misplaced DOCTYPE node\n");
1151  break;
1153  xmlDebugErr(ctxt, XML_CHECK_FOUND_FRAGMENT,
1154  "Misplaced FRAGMENT node\n");
1155  break;
1156  case XML_NOTATION_NODE:
1157  xmlDebugErr(ctxt, XML_CHECK_FOUND_NOTATION,
1158  "Misplaced NOTATION node\n");
1159  break;
1160  default:
1161  xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
1162  "Unknown node type %d\n", doc->type);
1163  }
1164 }
1165 
1173 static void
1174 xmlCtxtDumpDocumentHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1175 {
1176  if (doc == NULL) return;
1177  xmlCtxtDumpDocHead(ctxt, doc);
1178  if (!ctxt->check) {
1179  if (doc->name != NULL) {
1180  fprintf(ctxt->output, "name=");
1181  xmlCtxtDumpString(ctxt, BAD_CAST doc->name);
1182  fprintf(ctxt->output, "\n");
1183  }
1184  if (doc->version != NULL) {
1185  fprintf(ctxt->output, "version=");
1186  xmlCtxtDumpString(ctxt, doc->version);
1187  fprintf(ctxt->output, "\n");
1188  }
1189  if (doc->encoding != NULL) {
1190  fprintf(ctxt->output, "encoding=");
1191  xmlCtxtDumpString(ctxt, doc->encoding);
1192  fprintf(ctxt->output, "\n");
1193  }
1194  if (doc->URL != NULL) {
1195  fprintf(ctxt->output, "URL=");
1196  xmlCtxtDumpString(ctxt, doc->URL);
1197  fprintf(ctxt->output, "\n");
1198  }
1199  if (doc->standalone)
1200  fprintf(ctxt->output, "standalone=true\n");
1201  }
1202  if (doc->oldNs != NULL)
1203  xmlCtxtDumpNamespaceList(ctxt, doc->oldNs);
1204 }
1205 
1213 static void
1214 xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1215 {
1216  if (doc == NULL) {
1217  if (!ctxt->check)
1218  fprintf(ctxt->output, "DOCUMENT == NULL !\n");
1219  return;
1220  }
1221  xmlCtxtDumpDocumentHead(ctxt, doc);
1222  if (((doc->type == XML_DOCUMENT_NODE) ||
1223  (doc->type == XML_HTML_DOCUMENT_NODE))
1224  && (doc->children != NULL)) {
1225  ctxt->depth++;
1226  xmlCtxtDumpNodeList(ctxt, doc->children);
1227  ctxt->depth--;
1228  }
1229 }
1230 
1231 static void
1232 xmlCtxtDumpEntityCallback(void *payload, void *data,
1233  const xmlChar *name ATTRIBUTE_UNUSED)
1234 {
1235  xmlEntityPtr cur = (xmlEntityPtr) payload;
1236  xmlDebugCtxtPtr ctxt = (xmlDebugCtxtPtr) data;
1237  if (cur == NULL) {
1238  if (!ctxt->check)
1239  fprintf(ctxt->output, "Entity is NULL");
1240  return;
1241  }
1242  if (!ctxt->check) {
1243  fprintf(ctxt->output, "%s : ", (char *) cur->name);
1244  switch (cur->etype) {
1246  fprintf(ctxt->output, "INTERNAL GENERAL, ");
1247  break;
1249  fprintf(ctxt->output, "EXTERNAL PARSED, ");
1250  break;
1252  fprintf(ctxt->output, "EXTERNAL UNPARSED, ");
1253  break;
1255  fprintf(ctxt->output, "INTERNAL PARAMETER, ");
1256  break;
1258  fprintf(ctxt->output, "EXTERNAL PARAMETER, ");
1259  break;
1260  default:
1261  xmlDebugErr2(ctxt, XML_CHECK_ENTITY_TYPE,
1262  "Unknown entity type %d\n", cur->etype);
1263  }
1264  if (cur->ExternalID != NULL)
1265  fprintf(ctxt->output, "ID \"%s\"", (char *) cur->ExternalID);
1266  if (cur->SystemID != NULL)
1267  fprintf(ctxt->output, "SYSTEM \"%s\"", (char *) cur->SystemID);
1268  if (cur->orig != NULL)
1269  fprintf(ctxt->output, "\n orig \"%s\"", (char *) cur->orig);
1270  if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL))
1271  fprintf(ctxt->output, "\n content \"%s\"",
1272  (char *) cur->content);
1273  fprintf(ctxt->output, "\n");
1274  }
1275 }
1276 
1284 static void
1285 xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
1286 {
1287  if (doc == NULL) return;
1288  xmlCtxtDumpDocHead(ctxt, doc);
1289  if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
1291  doc->intSubset->entities;
1292 
1293  if (!ctxt->check)
1294  fprintf(ctxt->output, "Entities in internal subset\n");
1295  xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt);
1296  } else
1297  fprintf(ctxt->output, "No entities in internal subset\n");
1298  if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
1300  doc->extSubset->entities;
1301 
1302  if (!ctxt->check)
1303  fprintf(ctxt->output, "Entities in external subset\n");
1304  xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt);
1305  } else if (!ctxt->check)
1306  fprintf(ctxt->output, "No entities in external subset\n");
1307 }
1308 
1316 static void
1317 xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
1318 {
1319  if (dtd == NULL) {
1320  if (!ctxt->check)
1321  fprintf(ctxt->output, "DTD is NULL\n");
1322  return;
1323  }
1324  xmlCtxtDumpDtdNode(ctxt, dtd);
1325  if (dtd->children == NULL)
1326  fprintf(ctxt->output, " DTD is empty\n");
1327  else {
1328  ctxt->depth++;
1329  xmlCtxtDumpNodeList(ctxt, dtd->children);
1330  ctxt->depth--;
1331  }
1332 }
1333 
1334 /************************************************************************
1335  * *
1336  * Public entry points for dump *
1337  * *
1338  ************************************************************************/
1339 
1347 void
1348 xmlDebugDumpString(FILE * output, const xmlChar * str)
1349 {
1350  int i;
1351 
1352  if (output == NULL)
1353  output = stdout;
1354  if (str == NULL) {
1355  fprintf(output, "(NULL)");
1356  return;
1357  }
1358  for (i = 0; i < 40; i++)
1359  if (str[i] == 0)
1360  return;
1361  else if (IS_BLANK_CH(str[i]))
1362  fputc(' ', output);
1363  else if (str[i] >= 0x80)
1364  fprintf(output, "#%X", str[i]);
1365  else
1366  fputc(str[i], output);
1367  fprintf(output, "...");
1368 }
1369 
1378 void
1379 xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
1380  xmlDebugCtxt ctxt;
1381 
1382  if (output == NULL) return;
1383  xmlCtxtDumpInitCtxt(&ctxt);
1384  ctxt.output = output;
1385  ctxt.depth = depth;
1386  xmlCtxtDumpAttr(&ctxt, attr);
1387  xmlCtxtDumpCleanCtxt(&ctxt);
1388 }
1389 
1390 
1398 void
1399 xmlDebugDumpEntities(FILE * output, xmlDocPtr doc)
1400 {
1401  xmlDebugCtxt ctxt;
1402 
1403  if (output == NULL) return;
1404  xmlCtxtDumpInitCtxt(&ctxt);
1405  ctxt.output = output;
1406  xmlCtxtDumpEntities(&ctxt, doc);
1407  xmlCtxtDumpCleanCtxt(&ctxt);
1408 }
1409 
1418 void
1419 xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
1420 {
1421  xmlDebugCtxt ctxt;
1422 
1423  if (output == NULL) return;
1424  xmlCtxtDumpInitCtxt(&ctxt);
1425  ctxt.output = output;
1426  ctxt.depth = depth;
1427  xmlCtxtDumpAttrList(&ctxt, attr);
1428  xmlCtxtDumpCleanCtxt(&ctxt);
1429 }
1430 
1439 void
1440 xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
1441 {
1442  xmlDebugCtxt ctxt;
1443 
1444  if (output == NULL) return;
1445  xmlCtxtDumpInitCtxt(&ctxt);
1446  ctxt.output = output;
1447  ctxt.depth = depth;
1448  xmlCtxtDumpOneNode(&ctxt, node);
1449  xmlCtxtDumpCleanCtxt(&ctxt);
1450 }
1451 
1460 void
1461 xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
1462 {
1463  xmlDebugCtxt ctxt;
1464 
1465  if (output == NULL)
1466  output = stdout;
1467  xmlCtxtDumpInitCtxt(&ctxt);
1468  ctxt.output = output;
1469  ctxt.depth = depth;
1470  xmlCtxtDumpNode(&ctxt, node);
1471  xmlCtxtDumpCleanCtxt(&ctxt);
1472 }
1473 
1482 void
1483 xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
1484 {
1485  xmlDebugCtxt ctxt;
1486 
1487  if (output == NULL)
1488  output = stdout;
1489  xmlCtxtDumpInitCtxt(&ctxt);
1490  ctxt.output = output;
1491  ctxt.depth = depth;
1492  xmlCtxtDumpNodeList(&ctxt, node);
1493  xmlCtxtDumpCleanCtxt(&ctxt);
1494 }
1495 
1503 void
1504 xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
1505 {
1506  xmlDebugCtxt ctxt;
1507 
1508  if (output == NULL)
1509  output = stdout;
1510  xmlCtxtDumpInitCtxt(&ctxt);
1511  ctxt.options |= DUMP_TEXT_TYPE;
1512  ctxt.output = output;
1513  xmlCtxtDumpDocumentHead(&ctxt, doc);
1514  xmlCtxtDumpCleanCtxt(&ctxt);
1515 }
1516 
1524 void
1525 xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
1526 {
1527  xmlDebugCtxt ctxt;
1528 
1529  if (output == NULL)
1530  output = stdout;
1531  xmlCtxtDumpInitCtxt(&ctxt);
1532  ctxt.options |= DUMP_TEXT_TYPE;
1533  ctxt.output = output;
1534  xmlCtxtDumpDocument(&ctxt, doc);
1535  xmlCtxtDumpCleanCtxt(&ctxt);
1536 }
1537 
1545 void
1546 xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
1547 {
1548  xmlDebugCtxt ctxt;
1549 
1550  if (output == NULL)
1551  output = stdout;
1552  xmlCtxtDumpInitCtxt(&ctxt);
1553  ctxt.options |= DUMP_TEXT_TYPE;
1554  ctxt.output = output;
1555  xmlCtxtDumpDTD(&ctxt, dtd);
1556  xmlCtxtDumpCleanCtxt(&ctxt);
1557 }
1558 
1559 /************************************************************************
1560  * *
1561  * Public entry points for checkings *
1562  * *
1563  ************************************************************************/
1564 
1575 int
1576 xmlDebugCheckDocument(FILE * output, xmlDocPtr doc)
1577 {
1578  xmlDebugCtxt ctxt;
1579 
1580  if (output == NULL)
1581  output = stdout;
1582  xmlCtxtDumpInitCtxt(&ctxt);
1583  ctxt.output = output;
1584  ctxt.check = 1;
1585  xmlCtxtDumpDocument(&ctxt, doc);
1586  xmlCtxtDumpCleanCtxt(&ctxt);
1587  return(ctxt.errors);
1588 }
1589 
1590 /************************************************************************
1591  * *
1592  * Helpers for Shell *
1593  * *
1594  ************************************************************************/
1595 
1604 int
1605 xmlLsCountNode(xmlNodePtr node) {
1606  int ret = 0;
1607  xmlNodePtr list = NULL;
1608 
1609  if (node == NULL)
1610  return(0);
1611 
1612  switch (node->type) {
1613  case XML_ELEMENT_NODE:
1614  list = node->children;
1615  break;
1616  case XML_DOCUMENT_NODE:
1618 #ifdef LIBXML_DOCB_ENABLED
1619  case XML_DOCB_DOCUMENT_NODE:
1620 #endif
1621  list = ((xmlDocPtr) node)->children;
1622  break;
1623  case XML_ATTRIBUTE_NODE:
1624  list = ((xmlAttrPtr) node)->children;
1625  break;
1626  case XML_TEXT_NODE:
1628  case XML_PI_NODE:
1629  case XML_COMMENT_NODE:
1630  if (node->content != NULL) {
1631  ret = xmlStrlen(node->content);
1632  }
1633  break;
1634  case XML_ENTITY_REF_NODE:
1636  case XML_ENTITY_NODE:
1638  case XML_NOTATION_NODE:
1639  case XML_DTD_NODE:
1640  case XML_ELEMENT_DECL:
1641  case XML_ATTRIBUTE_DECL:
1642  case XML_ENTITY_DECL:
1643  case XML_NAMESPACE_DECL:
1644  case XML_XINCLUDE_START:
1645  case XML_XINCLUDE_END:
1646  ret = 1;
1647  break;
1648  }
1649  for (;list != NULL;ret++)
1650  list = list->next;
1651  return(ret);
1652 }
1653 
1661 void
1662 xmlLsOneNode(FILE *output, xmlNodePtr node) {
1663  if (output == NULL) return;
1664  if (node == NULL) {
1665  fprintf(output, "NULL\n");
1666  return;
1667  }
1668  switch (node->type) {
1669  case XML_ELEMENT_NODE:
1670  fprintf(output, "-");
1671  break;
1672  case XML_ATTRIBUTE_NODE:
1673  fprintf(output, "a");
1674  break;
1675  case XML_TEXT_NODE:
1676  fprintf(output, "t");
1677  break;
1679  fprintf(output, "C");
1680  break;
1681  case XML_ENTITY_REF_NODE:
1682  fprintf(output, "e");
1683  break;
1684  case XML_ENTITY_NODE:
1685  fprintf(output, "E");
1686  break;
1687  case XML_PI_NODE:
1688  fprintf(output, "p");
1689  break;
1690  case XML_COMMENT_NODE:
1691  fprintf(output, "c");
1692  break;
1693  case XML_DOCUMENT_NODE:
1694  fprintf(output, "d");
1695  break;
1697  fprintf(output, "h");
1698  break;
1700  fprintf(output, "T");
1701  break;
1703  fprintf(output, "F");
1704  break;
1705  case XML_NOTATION_NODE:
1706  fprintf(output, "N");
1707  break;
1708  case XML_NAMESPACE_DECL:
1709  fprintf(output, "n");
1710  break;
1711  default:
1712  fprintf(output, "?");
1713  }
1714  if (node->type != XML_NAMESPACE_DECL) {
1715  if (node->properties != NULL)
1716  fprintf(output, "a");
1717  else
1718  fprintf(output, "-");
1719  if (node->nsDef != NULL)
1720  fprintf(output, "n");
1721  else
1722  fprintf(output, "-");
1723  }
1724 
1725  fprintf(output, " %8d ", xmlLsCountNode(node));
1726 
1727  switch (node->type) {
1728  case XML_ELEMENT_NODE:
1729  if (node->name != NULL) {
1730  if ((node->ns != NULL) && (node->ns->prefix != NULL))
1731  fprintf(output, "%s:", node->ns->prefix);
1732  fprintf(output, "%s", (const char *) node->name);
1733  }
1734  break;
1735  case XML_ATTRIBUTE_NODE:
1736  if (node->name != NULL)
1737  fprintf(output, "%s", (const char *) node->name);
1738  break;
1739  case XML_TEXT_NODE:
1740  if (node->content != NULL) {
1741  xmlDebugDumpString(output, node->content);
1742  }
1743  break;
1745  break;
1746  case XML_ENTITY_REF_NODE:
1747  if (node->name != NULL)
1748  fprintf(output, "%s", (const char *) node->name);
1749  break;
1750  case XML_ENTITY_NODE:
1751  if (node->name != NULL)
1752  fprintf(output, "%s", (const char *) node->name);
1753  break;
1754  case XML_PI_NODE:
1755  if (node->name != NULL)
1756  fprintf(output, "%s", (const char *) node->name);
1757  break;
1758  case XML_COMMENT_NODE:
1759  break;
1760  case XML_DOCUMENT_NODE:
1761  break;
1763  break;
1765  break;
1767  break;
1768  case XML_NOTATION_NODE:
1769  break;
1770  case XML_NAMESPACE_DECL: {
1771  xmlNsPtr ns = (xmlNsPtr) node;
1772 
1773  if (ns->prefix == NULL)
1774  fprintf(output, "default -> %s", (char *)ns->href);
1775  else
1776  fprintf(output, "%s -> %s", (char *)ns->prefix,
1777  (char *)ns->href);
1778  break;
1779  }
1780  default:
1781  if (node->name != NULL)
1782  fprintf(output, "%s", (const char *) node->name);
1783  }
1784  fprintf(output, "\n");
1785 }
1786 
1795 const char *
1796 xmlBoolToText(int boolval)
1797 {
1798  if (boolval)
1799  return("True");
1800  else
1801  return("False");
1802 }
1803 
1804 #ifdef LIBXML_XPATH_ENABLED
1805 /****************************************************************
1806  * *
1807  * The XML shell related functions *
1808  * *
1809  ****************************************************************/
1810 
1811 
1812 
1813 /*
1814  * TODO: Improvement/cleanups for the XML shell
1815  * - allow to shell out an editor on a subpart
1816  * - cleanup function registrations (with help) and calling
1817  * - provide registration routines
1818  */
1819 
1827 void
1828 xmlShellPrintXPathError(int errorType, const char *arg)
1829 {
1830  const char *default_arg = "Result";
1831 
1832  if (!arg)
1833  arg = default_arg;
1834 
1835  switch (errorType) {
1836  case XPATH_UNDEFINED:
1838  "%s: no such node\n", arg);
1839  break;
1840 
1841  case XPATH_BOOLEAN:
1843  "%s is a Boolean\n", arg);
1844  break;
1845  case XPATH_NUMBER:
1847  "%s is a number\n", arg);
1848  break;
1849  case XPATH_STRING:
1851  "%s is a string\n", arg);
1852  break;
1853  case XPATH_POINT:
1855  "%s is a point\n", arg);
1856  break;
1857  case XPATH_RANGE:
1859  "%s is a range\n", arg);
1860  break;
1861  case XPATH_LOCATIONSET:
1863  "%s is a range\n", arg);
1864  break;
1865  case XPATH_USERS:
1867  "%s is user-defined\n", arg);
1868  break;
1869  case XPATH_XSLT_TREE:
1871  "%s is an XSLT value tree\n", arg);
1872  break;
1873  }
1874 #if 0
1876  "Try casting the result string function (xpath builtin)\n",
1877  arg);
1878 #endif
1879 }
1880 
1881 
1882 #ifdef LIBXML_OUTPUT_ENABLED
1883 
1890 static void
1891 xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node)
1892 {
1893  FILE *fp;
1894 
1895  if (!node)
1896  return;
1897  if (ctxt == NULL)
1898  fp = stdout;
1899  else
1900  fp = ctxt->output;
1901 
1902  if (node->type == XML_DOCUMENT_NODE)
1903  xmlDocDump(fp, (xmlDocPtr) node);
1904  else if (node->type == XML_ATTRIBUTE_NODE)
1905  xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0);
1906  else
1907  xmlElemDump(fp, node->doc, node);
1908 
1909  fprintf(fp, "\n");
1910 }
1911 
1918 void
1919 xmlShellPrintNode(xmlNodePtr node)
1920 {
1921  xmlShellPrintNodeCtxt(NULL, node);
1922 }
1923 #endif /* LIBXML_OUTPUT_ENABLED */
1924 
1932 static void
1933 xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
1934 {
1935  if (!ctxt)
1936  return;
1937 
1938  if (list != NULL) {
1939  switch (list->type) {
1940  case XPATH_NODESET:{
1941 #ifdef LIBXML_OUTPUT_ENABLED
1942  int indx;
1943 
1944  if (list->nodesetval) {
1945  for (indx = 0; indx < list->nodesetval->nodeNr;
1946  indx++) {
1947  xmlShellPrintNodeCtxt(ctxt,
1948  list->nodesetval->nodeTab[indx]);
1949  }
1950  } else {
1952  "Empty node set\n");
1953  }
1954  break;
1955 #else
1957  "Node set\n");
1958 #endif /* LIBXML_OUTPUT_ENABLED */
1959  }
1960  case XPATH_BOOLEAN:
1962  "Is a Boolean:%s\n",
1963  xmlBoolToText(list->boolval));
1964  break;
1965  case XPATH_NUMBER:
1967  "Is a number:%0g\n", list->floatval);
1968  break;
1969  case XPATH_STRING:
1971  "Is a string:%s\n", list->stringval);
1972  break;
1973 
1974  default:
1975  xmlShellPrintXPathError(list->type, NULL);
1976  }
1977  }
1978 }
1979 
1986 void
1987 xmlShellPrintXPathResult(xmlXPathObjectPtr list)
1988 {
1989  xmlShellPrintXPathResultCtxt(NULL, list);
1990 }
1991 
2004 int
2005 xmlShellList(xmlShellCtxtPtr ctxt,
2008 {
2009  xmlNodePtr cur;
2010  if (!ctxt)
2011  return (0);
2012  if (node == NULL) {
2013  fprintf(ctxt->output, "NULL\n");
2014  return (0);
2015  }
2016  if ((node->type == XML_DOCUMENT_NODE) ||
2017  (node->type == XML_HTML_DOCUMENT_NODE)) {
2018  cur = ((xmlDocPtr) node)->children;
2019  } else if (node->type == XML_NAMESPACE_DECL) {
2020  xmlLsOneNode(ctxt->output, node);
2021  return (0);
2022  } else if (node->children != NULL) {
2023  cur = node->children;
2024  } else {
2025  xmlLsOneNode(ctxt->output, node);
2026  return (0);
2027  }
2028  while (cur != NULL) {
2029  xmlLsOneNode(ctxt->output, cur);
2030  cur = cur->next;
2031  }
2032  return (0);
2033 }
2034 
2047 int
2048 xmlShellBase(xmlShellCtxtPtr ctxt,
2051 {
2052  xmlChar *base;
2053  if (!ctxt)
2054  return 0;
2055  if (node == NULL) {
2056  fprintf(ctxt->output, "NULL\n");
2057  return (0);
2058  }
2059 
2060  base = xmlNodeGetBase(node->doc, node);
2061 
2062  if (base == NULL) {
2063  fprintf(ctxt->output, " No base found !!!\n");
2064  } else {
2065  fprintf(ctxt->output, "%s\n", base);
2066  xmlFree(base);
2067  }
2068  return (0);
2069 }
2070 
2071 #ifdef LIBXML_TREE_ENABLED
2072 
2084 static int
2085 xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2088 {
2089  xmlNodeSetBase(node, (xmlChar*) arg);
2090  return (0);
2091 }
2092 #endif
2093 
2094 #ifdef LIBXML_XPATH_ENABLED
2095 
2108 static int
2109 xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg,
2111 {
2112  xmlChar* nsListDup;
2113  xmlChar* prefix;
2114  xmlChar* href;
2115  xmlChar* next;
2116 
2117  nsListDup = xmlStrdup((xmlChar *) arg);
2118  next = nsListDup;
2119  while(next != NULL) {
2120  /* skip spaces */
2121  /*while((*next) == ' ') next++;*/
2122  if((*next) == '\0') break;
2123 
2124  /* find prefix */
2125  prefix = next;
2126  next = (xmlChar*)xmlStrchr(next, '=');
2127  if(next == NULL) {
2128  fprintf(ctxt->output, "setns: prefix=[nsuri] required\n");
2129  xmlFree(nsListDup);
2130  return(-1);
2131  }
2132  *(next++) = '\0';
2133 
2134  /* find href */
2135  href = next;
2136  next = (xmlChar*)xmlStrchr(next, ' ');
2137  if(next != NULL) {
2138  *(next++) = '\0';
2139  }
2140 
2141  /* do register namespace */
2142  if(xmlXPathRegisterNs(ctxt->pctxt, prefix, href) != 0) {
2143  fprintf(ctxt->output,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
2144  xmlFree(nsListDup);
2145  return(-1);
2146  }
2147  }
2148 
2149  xmlFree(nsListDup);
2150  return(0);
2151 }
2164 static int
2165 xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
2167 {
2168  xmlNsPtr ns;
2169 
2170  if ((root == NULL) || (root->type != XML_ELEMENT_NODE) ||
2171  (root->nsDef == NULL) || (ctxt == NULL) || (ctxt->pctxt == NULL))
2172  return(-1);
2173  ns = root->nsDef;
2174  while (ns != NULL) {
2175  if (ns->prefix == NULL)
2176  xmlXPathRegisterNs(ctxt->pctxt, BAD_CAST "defaultns", ns->href);
2177  else
2178  xmlXPathRegisterNs(ctxt->pctxt, ns->prefix, ns->href);
2179  ns = ns->next;
2180  }
2181  return(0);
2182 }
2183 #endif
2184 
2197 static int
2198 xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2200 {
2201  if (!ctxt)
2202  return (0);
2203  if (node == NULL)
2204  return (0);
2205  if (arg == NULL)
2206  return (0);
2207 #ifdef LIBXML_REGEXP_ENABLED
2208  if ((xmlStrchr((xmlChar *) arg, '?')) ||
2209  (xmlStrchr((xmlChar *) arg, '*')) ||
2210  (xmlStrchr((xmlChar *) arg, '.')) ||
2211  (xmlStrchr((xmlChar *) arg, '['))) {
2212  }
2213 #endif
2214  while (node != NULL) {
2215  if (node->type == XML_COMMENT_NODE) {
2216  if (xmlStrstr(node->content, (xmlChar *) arg)) {
2217 
2218  fprintf(ctxt->output, "%s : ", xmlGetNodePath(node));
2219  xmlShellList(ctxt, NULL, node, NULL);
2220  }
2221  } else if (node->type == XML_TEXT_NODE) {
2222  if (xmlStrstr(node->content, (xmlChar *) arg)) {
2223 
2224  fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent));
2225  xmlShellList(ctxt, NULL, node->parent, NULL);
2226  }
2227  }
2228 
2229  /*
2230  * Browse the full subtree, deep first
2231  */
2232 
2233  if ((node->type == XML_DOCUMENT_NODE) ||
2234  (node->type == XML_HTML_DOCUMENT_NODE)) {
2235  node = ((xmlDocPtr) node)->children;
2236  } else if ((node->children != NULL)
2237  && (node->type != XML_ENTITY_REF_NODE)) {
2238  /* deep first */
2239  node = node->children;
2240  } else if (node->next != NULL) {
2241  /* then siblings */
2242  node = node->next;
2243  } else {
2244  /* go up to parents->next if needed */
2245  while (node != NULL) {
2246  if (node->parent != NULL) {
2247  node = node->parent;
2248  }
2249  if (node->next != NULL) {
2250  node = node->next;
2251  break;
2252  }
2253  if (node->parent == NULL) {
2254  node = NULL;
2255  break;
2256  }
2257  }
2258  }
2259  }
2260  return (0);
2261 }
2262 
2275 int
2276 xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2279 {
2280  if (!ctxt)
2281  return (0);
2282  if (node == NULL) {
2283  fprintf(ctxt->output, "NULL\n");
2284  return (0);
2285  }
2286  if ((node->type == XML_DOCUMENT_NODE) ||
2287  (node->type == XML_HTML_DOCUMENT_NODE)) {
2288  xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node);
2289  } else if (node->type == XML_ATTRIBUTE_NODE) {
2290  xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0);
2291  } else {
2292  xmlDebugDumpOneNode(ctxt->output, node, 0);
2293  }
2294  return (0);
2295 }
2296 
2309 static int
2310 xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2311  char *value, xmlNodePtr node,
2313 {
2316 
2317  if (!ctxt)
2318  return (0);
2319  if (node == NULL) {
2320  fprintf(ctxt->output, "NULL\n");
2321  return (0);
2322  }
2323  if (value == NULL) {
2324  fprintf(ctxt->output, "NULL\n");
2325  return (0);
2326  }
2327 
2329  if (ret == XML_ERR_OK) {
2330  if (node->children != NULL) {
2331  xmlFreeNodeList(node->children);
2332  node->children = NULL;
2333  node->last = NULL;
2334  }
2336  } else {
2337  fprintf(ctxt->output, "failed to parse content\n");
2338  }
2339  return (0);
2340 }
2341 
2342 #ifdef LIBXML_SCHEMAS_ENABLED
2343 
2355 static int
2356 xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
2359 {
2360  xmlRelaxNGPtr relaxngschemas;
2361  xmlRelaxNGParserCtxtPtr ctxt;
2362  xmlRelaxNGValidCtxtPtr vctxt;
2363  int ret;
2364 
2365  ctxt = xmlRelaxNGNewParserCtxt(schemas);
2366  xmlRelaxNGSetParserErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
2367  relaxngschemas = xmlRelaxNGParse(ctxt);
2368  xmlRelaxNGFreeParserCtxt(ctxt);
2369  if (relaxngschemas == NULL) {
2371  "Relax-NG schema %s failed to compile\n", schemas);
2372  return(-1);
2373  }
2374  vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2375  xmlRelaxNGSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL);
2376  ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc);
2377  if (ret == 0) {
2378  fprintf(stderr, "%s validates\n", sctxt->filename);
2379  } else if (ret > 0) {
2380  fprintf(stderr, "%s fails to validate\n", sctxt->filename);
2381  } else {
2382  fprintf(stderr, "%s validation generated an internal error\n",
2383  sctxt->filename);
2384  }
2385  xmlRelaxNGFreeValidCtxt(vctxt);
2386  if (relaxngschemas != NULL)
2387  xmlRelaxNGFree(relaxngschemas);
2388  return(0);
2389 }
2390 #endif
2391 
2392 #ifdef LIBXML_OUTPUT_ENABLED
2393 
2405 int
2406 xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
2408 {
2409  if (!ctxt)
2410  return (0);
2411  if (node == NULL) {
2412  fprintf(ctxt->output, "NULL\n");
2413  return (0);
2414  }
2415  if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
2416 #ifdef LIBXML_HTML_ENABLED
2417  if (node->type == XML_HTML_DOCUMENT_NODE)
2418  htmlDocDump(ctxt->output, (htmlDocPtr) node);
2419  else
2420  htmlNodeDumpFile(ctxt->output, ctxt->doc, node);
2421 #else
2422  if (node->type == XML_DOCUMENT_NODE)
2423  xmlDocDump(ctxt->output, (xmlDocPtr) node);
2424  else
2425  xmlElemDump(ctxt->output, ctxt->doc, node);
2426 #endif /* LIBXML_HTML_ENABLED */
2427  } else {
2428  if (node->type == XML_DOCUMENT_NODE)
2429  xmlDocDump(ctxt->output, (xmlDocPtr) node);
2430  else
2431  xmlElemDump(ctxt->output, ctxt->doc, node);
2432  }
2433  fprintf(ctxt->output, "\n");
2434  return (0);
2435 }
2436 #endif /* LIBXML_OUTPUT_ENABLED */
2437 
2450 int
2451 xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
2454 {
2455  xmlDocPtr doc;
2456  int html = 0;
2457 
2458  if ((ctxt == NULL) || (filename == NULL)) return(-1);
2459  if (ctxt->doc != NULL)
2460  html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
2461 
2462  if (html) {
2463 #ifdef LIBXML_HTML_ENABLED
2464  doc = htmlParseFile(filename, NULL);
2465 #else
2466  fprintf(ctxt->output, "HTML support not compiled in\n");
2467  doc = NULL;
2468 #endif /* LIBXML_HTML_ENABLED */
2469  } else {
2470  doc = xmlReadFile(filename,NULL,0);
2471  }
2472  if (doc != NULL) {
2473  if (ctxt->loaded == 1) {
2474  xmlFreeDoc(ctxt->doc);
2475  }
2476  ctxt->loaded = 1;
2477 #ifdef LIBXML_XPATH_ENABLED
2478  xmlXPathFreeContext(ctxt->pctxt);
2479 #endif /* LIBXML_XPATH_ENABLED */
2480  xmlFree(ctxt->filename);
2481  ctxt->doc = doc;
2482  ctxt->node = (xmlNodePtr) doc;
2483 #ifdef LIBXML_XPATH_ENABLED
2484  ctxt->pctxt = xmlXPathNewContext(doc);
2485 #endif /* LIBXML_XPATH_ENABLED */
2486  ctxt->filename = (char *) xmlCanonicPath((xmlChar *) filename);
2487  } else
2488  return (-1);
2489  return (0);
2490 }
2491 
2492 #ifdef LIBXML_OUTPUT_ENABLED
2493 
2506 int
2507 xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
2509 {
2510  if (node == NULL)
2511  return (-1);
2512  if ((filename == NULL) || (filename[0] == 0)) {
2513  return (-1);
2514  }
2515 #ifdef W_OK
2516  if (access((char *) filename, W_OK)) {
2518  "Cannot write to %s\n", filename);
2519  return (-1);
2520  }
2521 #endif
2522  switch (node->type) {
2523  case XML_DOCUMENT_NODE:
2524  if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
2526  "Failed to write to %s\n", filename);
2527  return (-1);
2528  }
2529  break;
2531 #ifdef LIBXML_HTML_ENABLED
2532  if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
2534  "Failed to write to %s\n", filename);
2535  return (-1);
2536  }
2537 #else
2538  if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
2540  "Failed to write to %s\n", filename);
2541  return (-1);
2542  }
2543 #endif /* LIBXML_HTML_ENABLED */
2544  break;
2545  default:{
2546  FILE *f;
2547 
2548  f = fopen((char *) filename, "w");
2549  if (f == NULL) {
2551  "Failed to write to %s\n", filename);
2552  return (-1);
2553  }
2554  xmlElemDump(f, ctxt->doc, node);
2555  fclose(f);
2556  }
2557  }
2558  return (0);
2559 }
2560 
2573 int
2574 xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
2577 {
2578  if ((ctxt == NULL) || (ctxt->doc == NULL))
2579  return (-1);
2580  if ((filename == NULL) || (filename[0] == 0))
2581  filename = ctxt->filename;
2582  if (filename == NULL)
2583  return (-1);
2584 #ifdef W_OK
2585  if (access((char *) filename, W_OK)) {
2587  "Cannot save to %s\n", filename);
2588  return (-1);
2589  }
2590 #endif
2591  switch (ctxt->doc->type) {
2592  case XML_DOCUMENT_NODE:
2593  if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
2595  "Failed to save to %s\n", filename);
2596  }
2597  break;
2599 #ifdef LIBXML_HTML_ENABLED
2600  if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
2602  "Failed to save to %s\n", filename);
2603  }
2604 #else
2605  if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
2607  "Failed to save to %s\n", filename);
2608  }
2609 #endif /* LIBXML_HTML_ENABLED */
2610  break;
2611  default:
2613  "To save to subparts of a document use the 'write' command\n");
2614  return (-1);
2615 
2616  }
2617  return (0);
2618 }
2619 #endif /* LIBXML_OUTPUT_ENABLED */
2620 
2621 #ifdef LIBXML_VALID_ENABLED
2622 
2635 int
2636 xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
2639 {
2640  xmlValidCtxt vctxt;
2641  int res = -1;
2642 
2643  if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1);
2644  vctxt.userData = NULL;
2645  vctxt.error = xmlGenericError;
2646  vctxt.warning = xmlGenericError;
2647 
2648  if ((dtd == NULL) || (dtd[0] == 0)) {
2649  res = xmlValidateDocument(&vctxt, ctxt->doc);
2650  } else {
2651  xmlDtdPtr subset;
2652 
2653  subset = xmlParseDTD(NULL, (xmlChar *) dtd);
2654  if (subset != NULL) {
2655  res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
2656 
2657  xmlFreeDtd(subset);
2658  }
2659  }
2660  return (res);
2661 }
2662 #endif /* LIBXML_VALID_ENABLED */
2663 
2677 int
2678 xmlShellDu(xmlShellCtxtPtr ctxt,
2681 {
2682  xmlNodePtr node;
2683  int indent = 0, i;
2684 
2685  if (!ctxt)
2686  return (-1);
2687 
2688  if (tree == NULL)
2689  return (-1);
2690  node = tree;
2691  while (node != NULL) {
2692  if ((node->type == XML_DOCUMENT_NODE) ||
2693  (node->type == XML_HTML_DOCUMENT_NODE)) {
2694  fprintf(ctxt->output, "/\n");
2695  } else if (node->type == XML_ELEMENT_NODE) {
2696  for (i = 0; i < indent; i++)
2697  fprintf(ctxt->output, " ");
2698  if ((node->ns) && (node->ns->prefix))
2699  fprintf(ctxt->output, "%s:", node->ns->prefix);
2700  fprintf(ctxt->output, "%s\n", node->name);
2701  } else {
2702  }
2703 
2704  /*
2705  * Browse the full subtree, deep first
2706  */
2707 
2708  if ((node->type == XML_DOCUMENT_NODE) ||
2709  (node->type == XML_HTML_DOCUMENT_NODE)) {
2710  node = ((xmlDocPtr) node)->children;
2711  } else if ((node->children != NULL)
2712  && (node->type != XML_ENTITY_REF_NODE)) {
2713  /* deep first */
2714  node = node->children;
2715  indent++;
2716  } else if ((node != tree) && (node->next != NULL)) {
2717  /* then siblings */
2718  node = node->next;
2719  } else if (node != tree) {
2720  /* go up to parents->next if needed */
2721  while (node != tree) {
2722  if (node->parent != NULL) {
2723  node = node->parent;
2724  indent--;
2725  }
2726  if ((node != tree) && (node->next != NULL)) {
2727  node = node->next;
2728  break;
2729  }
2730  if (node->parent == NULL) {
2731  node = NULL;
2732  break;
2733  }
2734  if (node == tree) {
2735  node = NULL;
2736  break;
2737  }
2738  }
2739  /* exit condition */
2740  if (node == tree)
2741  node = NULL;
2742  } else
2743  node = NULL;
2744  }
2745  return (0);
2746 }
2747 
2762 int
2763 xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
2765 {
2766  xmlChar *path;
2767 
2768  if ((node == NULL) || (buffer == NULL))
2769  return (-1);
2770 
2771  path = xmlGetNodePath(node);
2772  if (path == NULL)
2773  return (-1);
2774 
2775  /*
2776  * This test prevents buffer overflow, because this routine
2777  * is only called by xmlShell, in which the second argument is
2778  * 500 chars long.
2779  * It is a dirty hack before a cleaner solution is found.
2780  * Documentation should mention that the second argument must
2781  * be at least 500 chars long, and could be stripped if too long.
2782  */
2783  snprintf(buffer, 499, "%s", path);
2784  buffer[499] = '0';
2785  xmlFree(path);
2786 
2787  return (0);
2788 }
2789 
2801 void
2802 xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
2803  FILE * output)
2804 {
2805  char prompt[500] = "/ > ";
2806  char *cmdline = NULL, *cur;
2807  char command[100];
2808  char arg[400];
2809  int i;
2810  xmlShellCtxtPtr ctxt;
2811  xmlXPathObjectPtr list;
2812 
2813  if (doc == NULL)
2814  return;
2815  if (filename == NULL)
2816  return;
2817  if (input == NULL)
2818  return;
2819  if (output == NULL)
2820  output = stdout;
2821  ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
2822  if (ctxt == NULL)
2823  return;
2824  ctxt->loaded = 0;
2825  ctxt->doc = doc;
2826  ctxt->input = input;
2827  ctxt->output = output;
2828  ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
2829  ctxt->node = (xmlNodePtr) ctxt->doc;
2830 
2831 #ifdef LIBXML_XPATH_ENABLED
2832  ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
2833  if (ctxt->pctxt == NULL) {
2834  xmlFree(ctxt);
2835  return;
2836  }
2837 #endif /* LIBXML_XPATH_ENABLED */
2838  while (1) {
2839  if (ctxt->node == (xmlNodePtr) ctxt->doc)
2840  snprintf(prompt, sizeof(prompt), "%s > ", "/");
2841  else if ((ctxt->node != NULL) && (ctxt->node->name) &&
2842  (ctxt->node->ns) && (ctxt->node->ns->prefix))
2843  snprintf(prompt, sizeof(prompt), "%s:%s > ",
2844  (ctxt->node->ns->prefix), ctxt->node->name);
2845  else if ((ctxt->node != NULL) && (ctxt->node->name))
2846  snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
2847  else
2848  snprintf(prompt, sizeof(prompt), "? > ");
2849  prompt[sizeof(prompt) - 1] = 0;
2850 
2851  /*
2852  * Get a new command line
2853  */
2854  cmdline = ctxt->input(prompt);
2855  if (cmdline == NULL)
2856  break;
2857 
2858  /*
2859  * Parse the command itself
2860  */
2861  cur = cmdline;
2862  while ((*cur == ' ') || (*cur == '\t'))
2863  cur++;
2864  i = 0;
2865  while ((*cur != ' ') && (*cur != '\t') &&
2866  (*cur != '\n') && (*cur != '\r')) {
2867  if (*cur == 0)
2868  break;
2869  command[i++] = *cur++;
2870  }
2871  command[i] = 0;
2872  if (i == 0)
2873  continue;
2874 
2875  /*
2876  * Parse the argument
2877  */
2878  while ((*cur == ' ') || (*cur == '\t'))
2879  cur++;
2880  i = 0;
2881  while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
2882  if (*cur == 0)
2883  break;
2884  arg[i++] = *cur++;
2885  }
2886  arg[i] = 0;
2887 
2888  /*
2889  * start interpreting the command
2890  */
2891  if (!strcmp(command, "exit"))
2892  break;
2893  if (!strcmp(command, "quit"))
2894  break;
2895  if (!strcmp(command, "bye"))
2896  break;
2897  if (!strcmp(command, "help")) {
2898  fprintf(ctxt->output, "\tbase display XML base of the node\n");
2899  fprintf(ctxt->output, "\tsetbase URI change the XML base of the node\n");
2900  fprintf(ctxt->output, "\tbye leave shell\n");
2901  fprintf(ctxt->output, "\tcat [node] display node or current node\n");
2902  fprintf(ctxt->output, "\tcd [path] change directory to path or to root\n");
2903  fprintf(ctxt->output, "\tdir [path] dumps information about the node (namespace, attributes, content)\n");
2904  fprintf(ctxt->output, "\tdu [path] show the structure of the subtree under path or the current node\n");
2905  fprintf(ctxt->output, "\texit leave shell\n");
2906  fprintf(ctxt->output, "\thelp display this help\n");
2907  fprintf(ctxt->output, "\tfree display memory usage\n");
2908  fprintf(ctxt->output, "\tload [name] load a new document with name\n");
2909  fprintf(ctxt->output, "\tls [path] list contents of path or the current directory\n");
2910  fprintf(ctxt->output, "\tset xml_fragment replace the current node content with the fragment parsed in context\n");
2911 #ifdef LIBXML_XPATH_ENABLED
2912  fprintf(ctxt->output, "\txpath expr evaluate the XPath expression in that context and print the result\n");
2913  fprintf(ctxt->output, "\tsetns nsreg register a namespace to a prefix in the XPath evaluation context\n");
2914  fprintf(ctxt->output, "\t format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix)\n");
2915  fprintf(ctxt->output, "\tsetrootns register all namespace found on the root element\n");
2916  fprintf(ctxt->output, "\t the default namespace if any uses 'defaultns' prefix\n");
2917 #endif /* LIBXML_XPATH_ENABLED */
2918  fprintf(ctxt->output, "\tpwd display current working directory\n");
2919  fprintf(ctxt->output, "\twhereis display absolute path of [path] or current working directory\n");
2920  fprintf(ctxt->output, "\tquit leave shell\n");
2921 #ifdef LIBXML_OUTPUT_ENABLED
2922  fprintf(ctxt->output, "\tsave [name] save this document to name or the original name\n");
2923  fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n");
2924 #endif /* LIBXML_OUTPUT_ENABLED */
2925 #ifdef LIBXML_VALID_ENABLED
2926  fprintf(ctxt->output, "\tvalidate check the document for errors\n");
2927 #endif /* LIBXML_VALID_ENABLED */
2928 #ifdef LIBXML_SCHEMAS_ENABLED
2929  fprintf(ctxt->output, "\trelaxng rng validate the document against the Relax-NG schemas\n");
2930 #endif
2931  fprintf(ctxt->output, "\tgrep string search for a string in the subtree\n");
2932 #ifdef LIBXML_VALID_ENABLED
2933  } else if (!strcmp(command, "validate")) {
2934  xmlShellValidate(ctxt, arg, NULL, NULL);
2935 #endif /* LIBXML_VALID_ENABLED */
2936  } else if (!strcmp(command, "load")) {
2937  xmlShellLoad(ctxt, arg, NULL, NULL);
2938 #ifdef LIBXML_SCHEMAS_ENABLED
2939  } else if (!strcmp(command, "relaxng")) {
2940  xmlShellRNGValidate(ctxt, arg, NULL, NULL);
2941 #endif
2942 #ifdef LIBXML_OUTPUT_ENABLED
2943  } else if (!strcmp(command, "save")) {
2944  xmlShellSave(ctxt, arg, NULL, NULL);
2945  } else if (!strcmp(command, "write")) {
2946  if (arg[0] == 0)
2948  "Write command requires a filename argument\n");
2949  else
2950  xmlShellWrite(ctxt, arg, ctxt->node, NULL);
2951 #endif /* LIBXML_OUTPUT_ENABLED */
2952  } else if (!strcmp(command, "grep")) {
2953  xmlShellGrep(ctxt, arg, ctxt->node, NULL);
2954  } else if (!strcmp(command, "free")) {
2955  if (arg[0] == 0) {
2956  xmlMemShow(ctxt->output, 0);
2957  } else {
2958  int len = 0;
2959 
2960  sscanf(arg, "%d", &len);
2961  xmlMemShow(ctxt->output, len);
2962  }
2963  } else if (!strcmp(command, "pwd")) {
2964  char dir[500];
2965 
2966  if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
2967  fprintf(ctxt->output, "%s\n", dir);
2968  } else if (!strcmp(command, "du")) {
2969  if (arg[0] == 0) {
2970  xmlShellDu(ctxt, NULL, ctxt->node, NULL);
2971  } else {
2972  ctxt->pctxt->node = ctxt->node;
2973 #ifdef LIBXML_XPATH_ENABLED
2974  ctxt->pctxt->node = ctxt->node;
2975  list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
2976 #else
2977  list = NULL;
2978 #endif /* LIBXML_XPATH_ENABLED */
2979  if (list != NULL) {
2980  switch (list->type) {
2981  case XPATH_UNDEFINED:
2983  "%s: no such node\n", arg);
2984  break;
2985  case XPATH_NODESET:{
2986  int indx;
2987 
2988  if (list->nodesetval == NULL)
2989  break;
2990 
2991  for (indx = 0;
2992  indx < list->nodesetval->nodeNr;
2993  indx++)
2994  xmlShellDu(ctxt, NULL,
2995  list->nodesetval->
2996  nodeTab[indx], NULL);
2997  break;
2998  }
2999  case XPATH_BOOLEAN:
3001  "%s is a Boolean\n", arg);
3002  break;
3003  case XPATH_NUMBER:
3005  "%s is a number\n", arg);
3006  break;
3007  case XPATH_STRING:
3009  "%s is a string\n", arg);
3010  break;
3011  case XPATH_POINT:
3013  "%s is a point\n", arg);
3014  break;
3015  case XPATH_RANGE:
3017  "%s is a range\n", arg);
3018  break;
3019  case XPATH_LOCATIONSET:
3021  "%s is a range\n", arg);
3022  break;
3023  case XPATH_USERS:
3025  "%s is user-defined\n", arg);
3026  break;
3027  case XPATH_XSLT_TREE:
3029  "%s is an XSLT value tree\n",
3030  arg);
3031  break;
3032  }
3033 #ifdef LIBXML_XPATH_ENABLED
3034  xmlXPathFreeObject(list);
3035 #endif
3036  } else {
3038  "%s: no such node\n", arg);
3039  }
3040  ctxt->pctxt->node = NULL;
3041  }
3042  } else if (!strcmp(command, "base")) {
3043  xmlShellBase(ctxt, NULL, ctxt->node, NULL);
3044  } else if (!strcmp(command, "set")) {
3045  xmlShellSetContent(ctxt, arg, ctxt->node, NULL);
3046 #ifdef LIBXML_XPATH_ENABLED
3047  } else if (!strcmp(command, "setns")) {
3048  if (arg[0] == 0) {
3050  "setns: prefix=[nsuri] required\n");
3051  } else {
3052  xmlShellRegisterNamespace(ctxt, arg, NULL, NULL);
3053  }
3054  } else if (!strcmp(command, "setrootns")) {
3055  xmlNodePtr root;
3056 
3057  root = xmlDocGetRootElement(ctxt->doc);
3058  xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL);
3059  } else if (!strcmp(command, "xpath")) {
3060  if (arg[0] == 0) {
3062  "xpath: expression required\n");
3063  } else {
3064  ctxt->pctxt->node = ctxt->node;
3065  list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3066  xmlXPathDebugDumpObject(ctxt->output, list, 0);
3067  xmlXPathFreeObject(list);
3068  }
3069 #endif /* LIBXML_XPATH_ENABLED */
3070 #ifdef LIBXML_TREE_ENABLED
3071  } else if (!strcmp(command, "setbase")) {
3072  xmlShellSetBase(ctxt, arg, ctxt->node, NULL);
3073 #endif
3074  } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
3075  int dir = (!strcmp(command, "dir"));
3076 
3077  if (arg[0] == 0) {
3078  if (dir)
3079  xmlShellDir(ctxt, NULL, ctxt->node, NULL);
3080  else
3081  xmlShellList(ctxt, NULL, ctxt->node, NULL);
3082  } else {
3083  ctxt->pctxt->node = ctxt->node;
3084 #ifdef LIBXML_XPATH_ENABLED
3085  ctxt->pctxt->node = ctxt->node;
3086  list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3087 #else
3088  list = NULL;
3089 #endif /* LIBXML_XPATH_ENABLED */
3090  if (list != NULL) {
3091  switch (list->type) {
3092  case XPATH_UNDEFINED:
3094  "%s: no such node\n", arg);
3095  break;
3096  case XPATH_NODESET:{
3097  int indx;
3098 
3099  if (list->nodesetval == NULL)
3100  break;
3101 
3102  for (indx = 0;
3103  indx < list->nodesetval->nodeNr;
3104  indx++) {
3105  if (dir)
3106  xmlShellDir(ctxt, NULL,
3107  list->nodesetval->
3108  nodeTab[indx], NULL);
3109  else
3110  xmlShellList(ctxt, NULL,
3111  list->nodesetval->
3112  nodeTab[indx], NULL);
3113  }
3114  break;
3115  }
3116  case XPATH_BOOLEAN:
3118  "%s is a Boolean\n", arg);
3119  break;
3120  case XPATH_NUMBER:
3122  "%s is a number\n", arg);
3123  break;
3124  case XPATH_STRING:
3126  "%s is a string\n", arg);
3127  break;
3128  case XPATH_POINT:
3130  "%s is a point\n", arg);
3131  break;
3132  case XPATH_RANGE:
3134  "%s is a range\n", arg);
3135  break;
3136  case XPATH_LOCATIONSET:
3138  "%s is a range\n", arg);
3139  break;
3140  case XPATH_USERS:
3142  "%s is user-defined\n", arg);
3143  break;
3144  case XPATH_XSLT_TREE:
3146  "%s is an XSLT value tree\n",
3147  arg);
3148  break;
3149  }
3150 #ifdef LIBXML_XPATH_ENABLED
3151  xmlXPathFreeObject(list);
3152 #endif
3153  } else {
3155  "%s: no such node\n", arg);
3156  }
3157  ctxt->pctxt->node = NULL;
3158  }
3159  } else if (!strcmp(command, "whereis")) {
3160  char dir[500];
3161 
3162  if (arg[0] == 0) {
3163  if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
3164  fprintf(ctxt->output, "%s\n", dir);
3165  } else {
3166  ctxt->pctxt->node = ctxt->node;
3167 #ifdef LIBXML_XPATH_ENABLED
3168  list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3169 #else
3170  list = NULL;
3171 #endif /* LIBXML_XPATH_ENABLED */
3172  if (list != NULL) {
3173  switch (list->type) {
3174  case XPATH_UNDEFINED:
3176  "%s: no such node\n", arg);
3177  break;
3178  case XPATH_NODESET:{
3179  int indx;
3180 
3181  if (list->nodesetval == NULL)
3182  break;
3183 
3184  for (indx = 0;
3185  indx < list->nodesetval->nodeNr;
3186  indx++) {
3187  if (!xmlShellPwd(ctxt, dir, list->nodesetval->
3188  nodeTab[indx], NULL))
3189  fprintf(ctxt->output, "%s\n", dir);
3190  }
3191  break;
3192  }
3193  case XPATH_BOOLEAN:
3195  "%s is a Boolean\n", arg);
3196  break;
3197  case XPATH_NUMBER:
3199  "%s is a number\n", arg);
3200  break;
3201  case XPATH_STRING:
3203  "%s is a string\n", arg);
3204  break;
3205  case XPATH_POINT:
3207  "%s is a point\n", arg);
3208  break;
3209  case XPATH_RANGE:
3211  "%s is a range\n", arg);
3212  break;
3213  case XPATH_LOCATIONSET:
3215  "%s is a range\n", arg);
3216  break;
3217  case XPATH_USERS:
3219  "%s is user-defined\n", arg);
3220  break;
3221  case XPATH_XSLT_TREE:
3223  "%s is an XSLT value tree\n",
3224  arg);
3225  break;
3226  }
3227 #ifdef LIBXML_XPATH_ENABLED
3228  xmlXPathFreeObject(list);
3229 #endif
3230  } else {
3232  "%s: no such node\n", arg);
3233  }
3234  ctxt->pctxt->node = NULL;
3235  }
3236  } else if (!strcmp(command, "cd")) {
3237  if (arg[0] == 0) {
3238  ctxt->node = (xmlNodePtr) ctxt->doc;
3239  } else {
3240 #ifdef LIBXML_XPATH_ENABLED
3241  int l;
3242 
3243  ctxt->pctxt->node = ctxt->node;
3244  l = strlen(arg);
3245  if ((l >= 2) && (arg[l - 1] == '/'))
3246  arg[l - 1] = 0;
3247  list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
3248 #else
3249  list = NULL;
3250 #endif /* LIBXML_XPATH_ENABLED */
3251  if (list != NULL) {
3252  switch (list->type) {
3253  case XPATH_UNDEFINED:
3255  "%s: no such node\n", arg);
3256  break;
3257  case XPATH_NODESET:
3258  if (list->nodesetval != NULL) {
3259  if (list->nodesetval->nodeNr == 1) {
3260  ctxt->node = list->nodesetval->nodeTab[0];
3261  if ((ctxt->node != NULL) &&
3262  (ctxt->node->type ==
3263  XML_NAMESPACE_DECL)) {
3265  "cannot cd to namespace\n");
3266  ctxt->node = NULL;
3267  }
3268  } else
3270  "%s is a %d Node Set\n",
3271  arg,
3272  list->nodesetval->nodeNr);
3273  } else
3275  "%s is an empty Node Set\n",
3276  arg);
3277  break;
3278  case XPATH_BOOLEAN:
3280  "%s is a Boolean\n", arg);
3281  break;
3282  case XPATH_NUMBER:
3284  "%s is a number\n", arg);
3285  break;
3286  case XPATH_STRING:
3288  "%s is a string\n", arg);
3289  break;
3290  case XPATH_POINT:
3292  "%s is a point\n", arg);
3293  break;
3294  case XPATH_RANGE:
3296  "%s is a range\n", arg);
3297  break;
3298  case XPATH_LOCATIONSET:
3300  "%s is a range\n", arg);
3301  break;
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  case XPATH_POINT:
3370  "%s is a point\n", arg);
3371  break;
3372  case XPATH_RANGE:
3374  "%s is a range\n", arg);
3375  break;
3376  case XPATH_LOCATIONSET:
3378  "%s is a range\n", arg);
3379  break;
3380  case XPATH_USERS:
3382  "%s is user-defined\n", arg);
3383  break;
3384  case XPATH_XSLT_TREE:
3386  "%s is an XSLT value tree\n",
3387  arg);
3388  break;
3389  }
3390 #ifdef LIBXML_XPATH_ENABLED
3391  xmlXPathFreeObject(list);
3392 #endif
3393  } else {
3395  "%s: no such node\n", arg);
3396  }
3397  ctxt->pctxt->node = NULL;
3398  }
3399 #endif /* LIBXML_OUTPUT_ENABLED */
3400  } else {
3402  "Unknown command %s\n", command);
3403  }
3404  free(cmdline); /* not xmlFree here ! */
3405  cmdline = NULL;
3406  }
3407 #ifdef LIBXML_XPATH_ENABLED
3408  xmlXPathFreeContext(ctxt->pctxt);
3409 #endif /* LIBXML_XPATH_ENABLED */
3410  if (ctxt->loaded) {
3411  xmlFreeDoc(ctxt->doc);
3412  }
3413  if (ctxt->filename != NULL)
3414  xmlFree(ctxt->filename);
3415  xmlFree(ctxt);
3416  if (cmdline != NULL)
3417  free(cmdline); /* not xmlFree here ! */
3418 }
3419 
3420 #endif /* LIBXML_XPATH_ENABLED */
3421 #define bottom_debugXML
3422 #include "elfgcchack.h"
3423 #endif /* LIBXML_DEBUG_ENABLED */
xmlEntityType etype
Definition: entities.h:52
xmlElementType type
Definition: tree.h:553
Definition: pdh_main.c:93
struct _xmlNs * oldNs
Definition: tree.h:572
_Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE *_File)
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
XMLPUBFUN const xmlChar *XMLCALL xmlStrstr(const xmlChar *str, const xmlChar *val)
Definition: xmlstring.c:344
#define shift
Definition: input.c:1756
char * name
Definition: tree.h:554
XMLPUBFUN void XMLCALL xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data)
Definition: hash.c:864
static const WCHAR indent[]
Definition: object.c:1156
const xmlChar * URL
Definition: tree.h:577
const xmlChar * SystemID
Definition: entities.h:54
#define error(str)
Definition: mkdosfs.c:1605
const xmlChar * version
Definition: tree.h:573
struct _xmlDtd * intSubset
Definition: tree.h:570
xmlElementType type
Definition: tree.h:408
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLsizei const GLchar ** path
Definition: glext.h:7234
Definition: tree.h:389
XMLPUBFUN void XMLCALL xmlFreeNodeList(xmlNodePtr cur)
struct _tree tree
XMLPUBFUN int XMLCALL xmlStrlen(const xmlChar *str)
Definition: xmlstring.c:425
#define free
Definition: debug_ros.c:5
struct _root root
xmlNs * xmlNsPtr
Definition: tree.h:388
#define LIBXML_XPATH_ENABLED
Definition: xmlversion.h:247
XMLPUBFUN void XMLCALL xmlMemShow(FILE *fp, int nr)
Definition: xmlmemory.c:886
void * next
Definition: dlist.c:360
#define snprintf
Definition: wintirpc.h:48
xmlValidityErrorFunc error
Definition: valid.h:84
GLuint buffer
Definition: glext.h:5915
TCHAR * cmdline
Definition: stretchblt.cpp:32
XMLPUBFUN xmlChar *XMLCALL xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur)
if(dx==0 &&dy==0)
Definition: linetemp.h:174
const char * filename
Definition: ioapi.h:135
XMLPUBFUN const xmlChar *XMLCALL xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:324
const xmlChar * URI
Definition: entities.h:57
FILE * stdout
Definition: tree.h:406
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct node node
XMLPUBFUN xmlDocPtr XMLCALL xmlReadFile(const char *URL, const char *encoding, int options)
Definition: parser.c:15221
XMLPUBFUN void XMLCALL xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int englob)
Definition: valid.c:1297
int standalone
Definition: tree.h:564
GLuint base
Definition: 3dtext.c:35
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
const xmlChar * name
Definition: tree.h:409
#define IS_BLANK_CH(c)
static size_t elem
Definition: string.c:68
XMLPUBVAR const xmlChar xmlStringText[]
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:346
const WCHAR * str
XMLPUBFUN xmlChar *XMLCALL xmlCanonicPath(const xmlChar *path)
Definition: uri.c:2379
XMLPUBFUN void XMLCALL xmlFreeDtd(xmlDtdPtr cur)
xmlNode * xmlNodePtr
Definition: tree.h:488
#define BAD_CAST
Definition: xmlstring.h:35
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
unsigned int dir
Definition: maze.c:112
Definition: dict.c:116
int options
Definition: main.c:106
const xmlChar * ExternalID
Definition: tree.h:422
r l[0]
Definition: byte_order.h:167
#define LIBXML_ATTR_FORMAT(fmt, args)
Definition: xmlversion.h:477
GLfloat f
Definition: glext.h:7540
Definition: id3.c:95
xmlParserErrors
Definition: xmlerror.h:99
struct list * next
Definition: list.h:38
XMLPUBFUN void XMLCALL xmlFreeDoc(xmlDocPtr cur)
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:865
Definition: cookie.c:201
const xmlChar * name
Definition: entities.h:41
void check(CONTEXT *pContext)
Definition: NtContinue.c:68
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _test_info results[8]
Definition: SetCursorPos.c:29
const xmlChar * SystemID
Definition: tree.h:423
XMLPUBFUN xmlParserErrors XMLCALL xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen, int options, xmlNodePtr *lst)
Definition: parser.c:13490
Definition: tree.h:489
XMLPUBFUN xmlEntityPtr XMLCALL xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name)
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
const xmlChar * ExternalID
Definition: entities.h:53
int ret
xmlAttr * xmlAttrPtr
Definition: tree.h:433
xmlElementType type
Definition: entities.h:40
Definition: mxnamespace.c:44
unsigned char xmlChar
Definition: xmlstring.h:28
GLenum GLsizei len
Definition: glext.h:6722
Definition: _list.h:228
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
BSTR prefix
Definition: mxnamespace.c:46
const xmlChar * encoding
Definition: tree.h:574
xmlEntitiesTable * xmlEntitiesTablePtr
Definition: entities.h:71
FxCollectionEntry * cur
struct _xmlNode * children
Definition: tree.h:410
xmlDoc * xmlDocPtr
Definition: tree.h:550
static unsigned __int64 next
Definition: rand_nt.c:6
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
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
#define f
Definition: ke_i.h:83
XMLPUBFUN int XMLCALL xmlDictOwns(xmlDictPtr dict, const xmlChar *str)
Definition: dict.c:1218
#define list
Definition: rosglue.h:35
#define ATTRIBUTE_UNUSED
Definition: win32config.h:132
XMLPUBVAR const xmlChar xmlStringTextNoenc[]
XMLPUBFUN int XMLCALL xmlCheckUTF8(const unsigned char *utf)
Definition: xmlstring.c:784
#define NULL
Definition: types.h:112
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
Definition: tree.h:551
xmlChar * content
Definition: entities.h:50
#define W_OK
Definition: io.h:170
#define msg(x)
Definition: auth_time.c:54
struct _xmlDtd * extSubset
Definition: tree.h:571
Definition: tree.h:434
Definition: name.c:38
GLuint res
Definition: glext.h:9613
WCHAR * name
Definition: cookie.c:203
XMLPUBFUN xmlNodePtr XMLCALL xmlDocGetRootElement(const xmlDoc *doc)
void * userData
Definition: valid.h:83
FILE * stderr
XMLPUBFUN xmlNodePtr XMLCALL xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur)
#define const
Definition: zconf.h:230
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
struct _xmlNode * children
Definition: tree.h:555
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:159
XMLPUBVAR const xmlChar xmlStringComment[]
xmlEntity * xmlEntityPtr
Definition: tree.h:49
struct _xmlDict * dict
Definition: tree.h:580
xmlValidityWarningFunc warning
Definition: valid.h:85
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
Definition: dlist.c:348
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:362