Annotation of XML/debugXML.c, revision 1.47
1.1 daniel 1: /*
2: * debugXML.c : This is a set of routines used for debugging the tree
3: * produced by the XML parser.
4: *
1.2 daniel 5: * See Copyright for the status of this software.
6: *
1.1 daniel 7: * Daniel Veillard <Daniel.Veillard@w3.org>
8: */
9:
1.11 daniel 10: #ifdef WIN32
11: #include "win32config.h"
12: #else
13: #include "config.h"
14: #endif
1.23 daniel 15:
1.41 veillard 16: #include <libxml/xmlversion.h>
1.23 daniel 17: #ifdef LIBXML_DEBUG_ENABLED
18:
1.1 daniel 19: #include <stdio.h>
1.26 veillard 20: #include <string.h>
1.12 daniel 21: #ifdef HAVE_STDLIB_H
22: #include <stdlib.h>
23: #endif
1.14 daniel 24: #ifdef HAVE_STRING_H
25: #include <string.h>
26: #endif
1.23 daniel 27: #include <libxml/xmlmemory.h>
28: #include <libxml/tree.h>
29: #include <libxml/parser.h>
30: #include <libxml/valid.h>
31: #include <libxml/debugXML.h>
32: #include <libxml/HTMLtree.h>
33: #include <libxml/HTMLparser.h>
1.44 veillard 34: #include <libxml/xmlerror.h>
1.1 daniel 35:
36: #define IS_BLANK(c) \
37: (((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
38:
1.6 daniel 39: void xmlDebugDumpString(FILE *output, const xmlChar *str) {
1.1 daniel 40: int i;
1.29 veillard 41: if (str == NULL) {
42: fprintf(output, "(NULL)");
43: return;
44: }
1.1 daniel 45: for (i = 0;i < 40;i++)
46: if (str[i] == 0) return;
47: else if (IS_BLANK(str[i])) fputc(' ', output);
1.27 veillard 48: else if (str[i] >= 0x80)
49: fprintf(output, "#%X", str[i]);
1.1 daniel 50: else fputc(str[i], output);
51: fprintf(output, "...");
52: }
53:
1.18 daniel 54: void xmlDebugDumpDtd(FILE *output, xmlDtdPtr dtd, int depth) {
55: int i;
56: char shift[100];
57:
58: for (i = 0;((i < depth) && (i < 25));i++)
59: shift[2 * i] = shift[2 * i + 1] = ' ';
60: shift[2 * i] = shift[2 * i + 1] = 0;
61:
62: fprintf(output, shift);
63:
64: if (dtd->type != XML_DTD_NODE) {
65: fprintf(output, "PBM: not a DTD\n");
66: return;
67: }
68: if (dtd->name != NULL)
69: fprintf(output, "DTD(%s)", dtd->name);
70: else
71: fprintf(output, "DTD");
72: if (dtd->ExternalID != NULL)
73: fprintf(output, ", PUBLIC %s", dtd->ExternalID);
74: if (dtd->SystemID != NULL)
75: fprintf(output, ", SYSTEM %s", dtd->SystemID);
76: fprintf(output, "\n");
77: /*
78: * Do a bit of checking
79: */
80: if (dtd->parent == NULL)
81: fprintf(output, "PBM: Dtd has no parent\n");
82: if (dtd->doc == NULL)
83: fprintf(output, "PBM: Dtd has no doc\n");
84: if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
85: fprintf(output, "PBM: Dtd doc differs from parent's one\n");
86: if (dtd->prev == NULL) {
87: if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
88: fprintf(output, "PBM: Dtd has no prev and not first of list\n");
89: } else {
90: if (dtd->prev->next != (xmlNodePtr) dtd)
91: fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
92: }
93: if (dtd->next == NULL) {
94: if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
95: fprintf(output, "PBM: Dtd has no next and not last of list\n");
96: } else {
97: if (dtd->next->prev != (xmlNodePtr) dtd)
98: fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
99: }
100: }
101:
102: void xmlDebugDumpAttrDecl(FILE *output, xmlAttributePtr attr, int depth) {
103: int i;
104: char shift[100];
105:
106: for (i = 0;((i < depth) && (i < 25));i++)
107: shift[2 * i] = shift[2 * i + 1] = ' ';
108: shift[2 * i] = shift[2 * i + 1] = 0;
109:
110: fprintf(output, shift);
111:
112: if (attr->type != XML_ATTRIBUTE_DECL) {
113: fprintf(output, "PBM: not a Attr\n");
114: return;
115: }
116: if (attr->name != NULL)
117: fprintf(output, "ATTRDECL(%s)", attr->name);
118: else
119: fprintf(output, "PBM ATTRDECL noname!!!");
120: if (attr->elem != NULL)
121: fprintf(output, " for %s", attr->elem);
122: else
123: fprintf(output, " PBM noelem!!!");
124: switch (attr->atype) {
125: case XML_ATTRIBUTE_CDATA:
126: fprintf(output, " CDATA");
127: break;
128: case XML_ATTRIBUTE_ID:
129: fprintf(output, " ID");
130: break;
131: case XML_ATTRIBUTE_IDREF:
132: fprintf(output, " IDREF");
133: break;
134: case XML_ATTRIBUTE_IDREFS:
135: fprintf(output, " IDREFS");
136: break;
137: case XML_ATTRIBUTE_ENTITY:
138: fprintf(output, " ENTITY");
139: break;
140: case XML_ATTRIBUTE_ENTITIES:
141: fprintf(output, " ENTITIES");
142: break;
143: case XML_ATTRIBUTE_NMTOKEN:
144: fprintf(output, " NMTOKEN");
145: break;
146: case XML_ATTRIBUTE_NMTOKENS:
147: fprintf(output, " NMTOKENS");
148: break;
149: case XML_ATTRIBUTE_ENUMERATION:
150: fprintf(output, " ENUMERATION");
151: break;
152: case XML_ATTRIBUTE_NOTATION:
153: fprintf(output, " NOTATION ");
154: break;
155: }
156: if (attr->tree != NULL) {
157: int i;
158: xmlEnumerationPtr cur = attr->tree;
159:
160: for (i = 0;i < 5; i++) {
161: if (i != 0)
162: fprintf(output, "|%s", cur->name);
163: else
164: fprintf(output, " (%s", cur->name);
165: cur = cur->next;
166: if (cur == NULL) break;
167: }
168: if (cur == NULL)
169: fprintf(output, ")");
170: else
171: fprintf(output, "...)");
172: }
173: switch (attr->def) {
174: case XML_ATTRIBUTE_NONE:
175: break;
176: case XML_ATTRIBUTE_REQUIRED:
177: fprintf(output, " REQUIRED");
178: break;
179: case XML_ATTRIBUTE_IMPLIED:
180: fprintf(output, " IMPLIED");
181: break;
182: case XML_ATTRIBUTE_FIXED:
183: fprintf(output, " FIXED");
184: break;
185: }
186: if (attr->defaultValue != NULL) {
187: fprintf(output, "\"");
188: xmlDebugDumpString(output, attr->defaultValue);
189: fprintf(output, "\"");
190: }
191: printf("\n");
192:
193: /*
194: * Do a bit of checking
195: */
196: if (attr->parent == NULL)
197: fprintf(output, "PBM: Attr has no parent\n");
198: if (attr->doc == NULL)
199: fprintf(output, "PBM: Attr has no doc\n");
200: if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
201: fprintf(output, "PBM: Attr doc differs from parent's one\n");
202: if (attr->prev == NULL) {
203: if ((attr->parent != NULL) && (attr->parent->children != (xmlNodePtr)attr))
204: fprintf(output, "PBM: Attr has no prev and not first of list\n");
205: } else {
206: if (attr->prev->next != (xmlNodePtr) attr)
207: fprintf(output, "PBM: Attr prev->next : back link wrong\n");
208: }
209: if (attr->next == NULL) {
210: if ((attr->parent != NULL) && (attr->parent->last != (xmlNodePtr) attr))
211: fprintf(output, "PBM: Attr has no next and not last of list\n");
212: } else {
213: if (attr->next->prev != (xmlNodePtr) attr)
214: fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
215: }
216: }
217:
218: void xmlDebugDumpElemDecl(FILE *output, xmlElementPtr elem, int depth) {
219: int i;
220: char shift[100];
221:
222: for (i = 0;((i < depth) && (i < 25));i++)
223: shift[2 * i] = shift[2 * i + 1] = ' ';
224: shift[2 * i] = shift[2 * i + 1] = 0;
225:
226: fprintf(output, shift);
227:
228: if (elem->type != XML_ELEMENT_DECL) {
229: fprintf(output, "PBM: not a Elem\n");
230: return;
231: }
1.27 veillard 232: if (elem->name != NULL) {
233: fprintf(output, "ELEMDECL(");
234: xmlDebugDumpString(output, elem->name);
235: fprintf(output, ")");
236: } else
1.18 daniel 237: fprintf(output, "PBM ELEMDECL noname!!!");
238: switch (elem->etype) {
239: case XML_ELEMENT_TYPE_EMPTY:
240: fprintf(output, ", EMPTY");
241: break;
242: case XML_ELEMENT_TYPE_ANY:
243: fprintf(output, ", ANY");
244: break;
245: case XML_ELEMENT_TYPE_MIXED:
246: fprintf(output, ", MIXED ");
247: break;
248: case XML_ELEMENT_TYPE_ELEMENT:
249: fprintf(output, ", MIXED ");
250: break;
251: }
252: if (elem->content != NULL) {
1.30 veillard 253: char buf[5001];
1.18 daniel 254:
255: buf[0] = 0;
256: xmlSprintfElementContent(buf, elem->content, 1);
1.30 veillard 257: buf[5000] = 0;
1.18 daniel 258: fprintf(output, "%s", buf);
259: }
260: printf("\n");
261:
262: /*
263: * Do a bit of checking
264: */
265: if (elem->parent == NULL)
266: fprintf(output, "PBM: Elem has no parent\n");
267: if (elem->doc == NULL)
268: fprintf(output, "PBM: Elem has no doc\n");
269: if ((elem->parent != NULL) && (elem->doc != elem->parent->doc))
270: fprintf(output, "PBM: Elem doc differs from parent's one\n");
271: if (elem->prev == NULL) {
272: if ((elem->parent != NULL) && (elem->parent->children != (xmlNodePtr)elem))
273: fprintf(output, "PBM: Elem has no prev and not first of list\n");
274: } else {
275: if (elem->prev->next != (xmlNodePtr) elem)
276: fprintf(output, "PBM: Elem prev->next : back link wrong\n");
277: }
278: if (elem->next == NULL) {
279: if ((elem->parent != NULL) && (elem->parent->last != (xmlNodePtr) elem))
280: fprintf(output, "PBM: Elem has no next and not last of list\n");
281: } else {
282: if (elem->next->prev != (xmlNodePtr) elem)
283: fprintf(output, "PBM: Elem next->prev : forward link wrong\n");
284: }
285: }
286:
1.20 daniel 287: void xmlDebugDumpEntityDecl(FILE *output, xmlEntityPtr ent, int depth) {
288: int i;
289: char shift[100];
290:
291: for (i = 0;((i < depth) && (i < 25));i++)
292: shift[2 * i] = shift[2 * i + 1] = ' ';
293: shift[2 * i] = shift[2 * i + 1] = 0;
294:
295: fprintf(output, shift);
296:
297: if (ent->type != XML_ENTITY_DECL) {
298: fprintf(output, "PBM: not a Entity decl\n");
299: return;
300: }
1.27 veillard 301: if (ent->name != NULL) {
302: fprintf(output, "ENTITYDECL(");
303: xmlDebugDumpString(output, ent->name);
304: fprintf(output, ")");
305: } else
1.20 daniel 306: fprintf(output, "PBM ENTITYDECL noname!!!");
307: switch (ent->etype) {
308: case XML_INTERNAL_GENERAL_ENTITY:
309: fprintf(output, ", internal\n");
310: break;
311: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
312: fprintf(output, ", external parsed\n");
313: break;
314: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
315: fprintf(output, ", unparsed\n");
316: break;
317: case XML_INTERNAL_PARAMETER_ENTITY:
318: fprintf(output, ", parameter\n");
319: break;
320: case XML_EXTERNAL_PARAMETER_ENTITY:
321: fprintf(output, ", external parameter\n");
322: break;
323: case XML_INTERNAL_PREDEFINED_ENTITY:
324: fprintf(output, ", predefined\n");
325: break;
326: }
327: if (ent->ExternalID) {
328: fprintf(output, shift);
1.32 veillard 329: fprintf(output, " ExternalID=%s\n", ent->ExternalID);
1.20 daniel 330: }
331: if (ent->SystemID) {
332: fprintf(output, shift);
1.32 veillard 333: fprintf(output, " SystemID=%s\n", ent->SystemID);
334: }
335: if (ent->URI != NULL) {
336: fprintf(output, shift);
337: fprintf(output, " URI=%s\n", ent->URI);
1.20 daniel 338: }
339: if (ent->content) {
340: fprintf(output, shift);
1.32 veillard 341: fprintf(output, " content=");
1.20 daniel 342: xmlDebugDumpString(output, ent->content);
343: fprintf(output, "\n");
344: }
345:
346: /*
347: * Do a bit of checking
348: */
349: if (ent->parent == NULL)
350: fprintf(output, "PBM: Ent has no parent\n");
351: if (ent->doc == NULL)
352: fprintf(output, "PBM: Ent has no doc\n");
353: if ((ent->parent != NULL) && (ent->doc != ent->parent->doc))
354: fprintf(output, "PBM: Ent doc differs from parent's one\n");
355: if (ent->prev == NULL) {
356: if ((ent->parent != NULL) && (ent->parent->children != (xmlNodePtr)ent))
357: fprintf(output, "PBM: Ent has no prev and not first of list\n");
358: } else {
359: if (ent->prev->next != (xmlNodePtr) ent)
360: fprintf(output, "PBM: Ent prev->next : back link wrong\n");
361: }
362: if (ent->next == NULL) {
363: if ((ent->parent != NULL) && (ent->parent->last != (xmlNodePtr) ent))
364: fprintf(output, "PBM: Ent has no next and not last of list\n");
365: } else {
366: if (ent->next->prev != (xmlNodePtr) ent)
367: fprintf(output, "PBM: Ent next->prev : forward link wrong\n");
368: }
369: }
370:
1.1 daniel 371: void xmlDebugDumpNamespace(FILE *output, xmlNsPtr ns, int depth) {
372: int i;
373: char shift[100];
374:
375: for (i = 0;((i < depth) && (i < 25));i++)
376: shift[2 * i] = shift[2 * i + 1] = ' ';
377: shift[2 * i] = shift[2 * i + 1] = 0;
378:
379: fprintf(output, shift);
1.45 veillard 380: if (ns->type != XML_NAMESPACE_DECL) {
381: fprintf(output, "invalid namespace node %d\n", ns->type);
382: return;
383: }
1.29 veillard 384: if (ns->href == NULL) {
385: if (ns->prefix != NULL)
386: fprintf(output, "incomplete namespace %s href=NULL\n", ns->prefix);
387: else
388: fprintf(output, "incomplete default namespace href=NULL\n");
389: } else {
390: if (ns->prefix != NULL)
391: fprintf(output, "namespace %s href=", ns->prefix);
392: else
393: fprintf(output, "default namespace href=");
1.10 daniel 394:
1.29 veillard 395: xmlDebugDumpString(output, ns->href);
396: fprintf(output, "\n");
397: }
1.1 daniel 398: }
399:
400: void xmlDebugDumpNamespaceList(FILE *output, xmlNsPtr ns, int depth) {
401: while (ns != NULL) {
402: xmlDebugDumpNamespace(output, ns, depth);
403: ns = ns->next;
404: }
405: }
406:
407: void xmlDebugDumpEntity(FILE *output, xmlEntityPtr ent, int depth) {
408: int i;
409: char shift[100];
410:
411: for (i = 0;((i < depth) && (i < 25));i++)
412: shift[2 * i] = shift[2 * i + 1] = ' ';
413: shift[2 * i] = shift[2 * i + 1] = 0;
414:
415: fprintf(output, shift);
1.19 daniel 416: switch (ent->etype) {
1.1 daniel 417: case XML_INTERNAL_GENERAL_ENTITY:
418: fprintf(output, "INTERNAL_GENERAL_ENTITY ");
419: break;
420: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
421: fprintf(output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
422: break;
423: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
424: fprintf(output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
425: break;
426: case XML_INTERNAL_PARAMETER_ENTITY:
427: fprintf(output, "INTERNAL_PARAMETER_ENTITY ");
428: break;
429: case XML_EXTERNAL_PARAMETER_ENTITY:
430: fprintf(output, "EXTERNAL_PARAMETER_ENTITY ");
431: break;
432: default:
1.19 daniel 433: fprintf(output, "ENTITY_%d ! ", ent->etype);
1.1 daniel 434: }
435: fprintf(output, "%s\n", ent->name);
436: if (ent->ExternalID) {
437: fprintf(output, shift);
438: fprintf(output, "ExternalID=%s\n", ent->ExternalID);
439: }
440: if (ent->SystemID) {
441: fprintf(output, shift);
442: fprintf(output, "SystemID=%s\n", ent->SystemID);
443: }
1.32 veillard 444: if (ent->URI) {
445: fprintf(output, shift);
446: fprintf(output, "URI=%s\n", ent->URI);
447: }
1.1 daniel 448: if (ent->content) {
449: fprintf(output, shift);
450: fprintf(output, "content=");
451: xmlDebugDumpString(output, ent->content);
452: fprintf(output, "\n");
453: }
454: }
455:
456: void xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
457: int i;
458: char shift[100];
459:
460: for (i = 0;((i < depth) && (i < 25));i++)
461: shift[2 * i] = shift[2 * i + 1] = ' ';
462: shift[2 * i] = shift[2 * i + 1] = 0;
463:
464: fprintf(output, shift);
1.18 daniel 465:
1.27 veillard 466: fprintf(output, "ATTRIBUTE ");
467: xmlDebugDumpString(output, attr->name);
468: fprintf(output, "\n");
1.16 daniel 469: if (attr->children != NULL)
470: xmlDebugDumpNodeList(output, attr->children, depth + 1);
1.18 daniel 471:
472: /*
473: * Do a bit of checking
474: */
475: if (attr->parent == NULL)
476: fprintf(output, "PBM: Attr has no parent\n");
477: if (attr->doc == NULL)
478: fprintf(output, "PBM: Attr has no doc\n");
479: if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
480: fprintf(output, "PBM: Attr doc differs from parent's one\n");
481: if (attr->prev == NULL) {
482: if ((attr->parent != NULL) && (attr->parent->properties != attr))
483: fprintf(output, "PBM: Attr has no prev and not first of list\n");
484: } else {
485: if (attr->prev->next != attr)
486: fprintf(output, "PBM: Attr prev->next : back link wrong\n");
487: }
488: if (attr->next != NULL) {
489: if (attr->next->prev != attr)
490: fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
491: }
1.1 daniel 492: }
493:
494: void xmlDebugDumpAttrList(FILE *output, xmlAttrPtr attr, int depth) {
495: while (attr != NULL) {
496: xmlDebugDumpAttr(output, attr, depth);
497: attr = attr->next;
498: }
499: }
500:
1.3 daniel 501: void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
1.1 daniel 502: int i;
503: char shift[100];
504:
505: for (i = 0;((i < depth) && (i < 25));i++)
506: shift[2 * i] = shift[2 * i + 1] = ' ';
507: shift[2 * i] = shift[2 * i + 1] = 0;
508:
509: switch (node->type) {
510: case XML_ELEMENT_NODE:
1.21 daniel 511: fprintf(output, shift);
1.1 daniel 512: fprintf(output, "ELEMENT ");
1.27 veillard 513: if (node->ns != NULL) {
514: xmlDebugDumpString(output, node->ns->prefix);
515: fprintf(output, ":");
516: }
517: xmlDebugDumpString(output, node->name);
518: fprintf(output, "\n");
1.1 daniel 519: break;
520: case XML_ATTRIBUTE_NODE:
1.21 daniel 521: fprintf(output, shift);
1.1 daniel 522: fprintf(output, "Error, ATTRIBUTE found here\n");
523: break;
524: case XML_TEXT_NODE:
1.21 daniel 525: fprintf(output, shift);
1.1 daniel 526: fprintf(output, "TEXT\n");
527: break;
528: case XML_CDATA_SECTION_NODE:
1.21 daniel 529: fprintf(output, shift);
1.1 daniel 530: fprintf(output, "CDATA_SECTION\n");
531: break;
532: case XML_ENTITY_REF_NODE:
1.21 daniel 533: fprintf(output, shift);
1.15 daniel 534: fprintf(output, "ENTITY_REF(%s)\n", node->name);
1.1 daniel 535: break;
536: case XML_ENTITY_NODE:
1.21 daniel 537: fprintf(output, shift);
1.1 daniel 538: fprintf(output, "ENTITY\n");
539: break;
540: case XML_PI_NODE:
1.21 daniel 541: fprintf(output, shift);
1.4 daniel 542: fprintf(output, "PI %s\n", node->name);
1.1 daniel 543: break;
544: case XML_COMMENT_NODE:
1.21 daniel 545: fprintf(output, shift);
1.1 daniel 546: fprintf(output, "COMMENT\n");
547: break;
548: case XML_DOCUMENT_NODE:
1.7 daniel 549: case XML_HTML_DOCUMENT_NODE:
1.21 daniel 550: fprintf(output, shift);
1.1 daniel 551: fprintf(output, "Error, DOCUMENT found here\n");
552: break;
553: case XML_DOCUMENT_TYPE_NODE:
1.21 daniel 554: fprintf(output, shift);
1.1 daniel 555: fprintf(output, "DOCUMENT_TYPE\n");
556: break;
557: case XML_DOCUMENT_FRAG_NODE:
1.21 daniel 558: fprintf(output, shift);
1.1 daniel 559: fprintf(output, "DOCUMENT_FRAG\n");
560: break;
561: case XML_NOTATION_NODE:
1.47 ! veillard 562: fprintf(output, shift);
1.1 daniel 563: fprintf(output, "NOTATION\n");
564: break;
1.18 daniel 565: case XML_DTD_NODE:
1.21 daniel 566: xmlDebugDumpDtd(output, (xmlDtdPtr) node, depth);
1.18 daniel 567: return;
568: case XML_ELEMENT_DECL:
1.21 daniel 569: xmlDebugDumpElemDecl(output, (xmlElementPtr) node, depth);
1.18 daniel 570: return;
571: case XML_ATTRIBUTE_DECL:
1.21 daniel 572: xmlDebugDumpAttrDecl(output, (xmlAttributePtr) node, depth);
1.18 daniel 573: return;
1.20 daniel 574: case XML_ENTITY_DECL:
1.21 daniel 575: xmlDebugDumpEntityDecl(output, (xmlEntityPtr) node, depth);
1.20 daniel 576: return;
1.45 veillard 577: case XML_NAMESPACE_DECL:
578: xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
1.47 ! veillard 579: return;
! 580: case XML_XINCLUDE_START:
! 581: fprintf(output, shift);
! 582: fprintf(output, "INCLUDE START\n");
! 583: return;
! 584: case XML_XINCLUDE_END:
! 585: fprintf(output, shift);
! 586: fprintf(output, "INCLUDE END\n");
1.45 veillard 587: return;
1.1 daniel 588: default:
1.21 daniel 589: fprintf(output, shift);
1.40 veillard 590: fprintf(output, "NODE_%d !!!\n", node->type);
591: return;
1.1 daniel 592: }
593: if (node->doc == NULL) {
594: fprintf(output, shift);
595: fprintf(output, "doc == NULL !!!\n");
596: }
597: if (node->nsDef != NULL)
598: xmlDebugDumpNamespaceList(output, node->nsDef, depth + 1);
599: if (node->properties != NULL)
600: xmlDebugDumpAttrList(output, node->properties, depth + 1);
601: if (node->type != XML_ENTITY_REF_NODE) {
602: if (node->content != NULL) {
1.38 veillard 603: shift[2 * i] = shift[2 * i + 1] = ' ' ;
604: shift[2 * i + 2] = shift[2 * i + 3] = 0 ;
1.1 daniel 605: fprintf(output, shift);
606: fprintf(output, "content=");
1.8 daniel 607: #ifndef XML_USE_BUFFER_CONTENT
1.1 daniel 608: xmlDebugDumpString(output, node->content);
1.8 daniel 609: #else
610: xmlDebugDumpString(output, xmlBufferContent(node->content));
611: #endif
1.1 daniel 612: fprintf(output, "\n");
613: }
614: } else {
615: xmlEntityPtr ent;
616: ent = xmlGetDocEntity(node->doc, node->name);
617: if (ent != NULL)
618: xmlDebugDumpEntity(output, ent, depth + 1);
1.18 daniel 619: }
620: /*
621: * Do a bit of checking
622: */
623: if (node->parent == NULL)
624: fprintf(output, "PBM: Node has no parent\n");
625: if (node->doc == NULL)
626: fprintf(output, "PBM: Node has no doc\n");
627: if ((node->parent != NULL) && (node->doc != node->parent->doc))
628: fprintf(output, "PBM: Node doc differs from parent's one\n");
629: if (node->prev == NULL) {
630: if ((node->parent != NULL) && (node->parent->children != node))
631: fprintf(output, "PBM: Node has no prev and not first of list\n");
632: } else {
633: if (node->prev->next != node)
634: fprintf(output, "PBM: Node prev->next : back link wrong\n");
635: }
636: if (node->next == NULL) {
637: if ((node->parent != NULL) && (node->parent->last != node))
638: fprintf(output, "PBM: Node has no next and not last of list\n");
639: } else {
640: if (node->next->prev != node)
641: fprintf(output, "PBM: Node next->prev : forward link wrong\n");
1.1 daniel 642: }
1.3 daniel 643: }
644:
645: void xmlDebugDumpNode(FILE *output, xmlNodePtr node, int depth) {
646: xmlDebugDumpOneNode(output, node, depth);
1.32 veillard 647: if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
1.16 daniel 648: xmlDebugDumpNodeList(output, node->children, depth + 1);
1.1 daniel 649: }
650:
651: void xmlDebugDumpNodeList(FILE *output, xmlNodePtr node, int depth) {
652: while (node != NULL) {
653: xmlDebugDumpNode(output, node, depth);
654: node = node->next;
655: }
656: }
657:
658:
1.12 daniel 659: void xmlDebugDumpDocumentHead(FILE *output, xmlDocPtr doc) {
1.1 daniel 660: if (output == NULL) output = stdout;
661: if (doc == NULL) {
662: fprintf(output, "DOCUMENT == NULL !\n");
663: return;
664: }
665:
666: switch (doc->type) {
667: case XML_ELEMENT_NODE:
668: fprintf(output, "Error, ELEMENT found here ");
669: break;
670: case XML_ATTRIBUTE_NODE:
671: fprintf(output, "Error, ATTRIBUTE found here\n");
672: break;
673: case XML_TEXT_NODE:
674: fprintf(output, "Error, TEXT\n");
675: break;
676: case XML_CDATA_SECTION_NODE:
677: fprintf(output, "Error, CDATA_SECTION\n");
678: break;
679: case XML_ENTITY_REF_NODE:
680: fprintf(output, "Error, ENTITY_REF\n");
681: break;
682: case XML_ENTITY_NODE:
683: fprintf(output, "Error, ENTITY\n");
684: break;
685: case XML_PI_NODE:
686: fprintf(output, "Error, PI\n");
687: break;
688: case XML_COMMENT_NODE:
689: fprintf(output, "Error, COMMENT\n");
690: break;
691: case XML_DOCUMENT_NODE:
692: fprintf(output, "DOCUMENT\n");
1.7 daniel 693: break;
694: case XML_HTML_DOCUMENT_NODE:
695: fprintf(output, "HTML DOCUMENT\n");
1.1 daniel 696: break;
697: case XML_DOCUMENT_TYPE_NODE:
698: fprintf(output, "Error, DOCUMENT_TYPE\n");
699: break;
700: case XML_DOCUMENT_FRAG_NODE:
701: fprintf(output, "Error, DOCUMENT_FRAG\n");
702: break;
703: case XML_NOTATION_NODE:
704: fprintf(output, "Error, NOTATION\n");
705: break;
706: default:
707: fprintf(output, "NODE_%d\n", doc->type);
708: }
709: if (doc->name != NULL) {
710: fprintf(output, "name=");
1.5 daniel 711: xmlDebugDumpString(output, BAD_CAST doc->name);
1.1 daniel 712: fprintf(output, "\n");
713: }
714: if (doc->version != NULL) {
715: fprintf(output, "version=");
716: xmlDebugDumpString(output, doc->version);
717: fprintf(output, "\n");
718: }
719: if (doc->encoding != NULL) {
720: fprintf(output, "encoding=");
721: xmlDebugDumpString(output, doc->encoding);
1.32 veillard 722: fprintf(output, "\n");
723: }
724: if (doc->URL != NULL) {
725: fprintf(output, "URL=");
726: xmlDebugDumpString(output, doc->URL);
1.1 daniel 727: fprintf(output, "\n");
728: }
729: if (doc->standalone)
730: fprintf(output, "standalone=true\n");
731: if (doc->oldNs != NULL)
732: xmlDebugDumpNamespaceList(output, doc->oldNs, 0);
1.12 daniel 733: }
734:
735: void xmlDebugDumpDocument(FILE *output, xmlDocPtr doc) {
736: if (output == NULL) output = stdout;
737: if (doc == NULL) {
738: fprintf(output, "DOCUMENT == NULL !\n");
739: return;
740: }
741: xmlDebugDumpDocumentHead(output, doc);
742: if (((doc->type == XML_DOCUMENT_NODE) ||
743: (doc->type == XML_HTML_DOCUMENT_NODE)) &&
1.16 daniel 744: (doc->children != NULL))
745: xmlDebugDumpNodeList(output, doc->children, 1);
1.12 daniel 746: }
1.30 veillard 747:
748: void xmlDebugDumpDTD(FILE *output, xmlDtdPtr dtd) {
749: if (dtd == NULL)
750: return;
751: if (dtd->type != XML_DTD_NODE) {
752: fprintf(output, "PBM: not a DTD\n");
753: return;
754: }
755: if (dtd->name != NULL)
756: fprintf(output, "DTD(%s)", dtd->name);
757: else
758: fprintf(output, "DTD");
759: if (dtd->ExternalID != NULL)
760: fprintf(output, ", PUBLIC %s", dtd->ExternalID);
761: if (dtd->SystemID != NULL)
762: fprintf(output, ", SYSTEM %s", dtd->SystemID);
763: fprintf(output, "\n");
764: /*
765: * Do a bit of checking
766: */
767: if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
768: fprintf(output, "PBM: Dtd doc differs from parent's one\n");
769: if (dtd->prev == NULL) {
770: if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
771: fprintf(output, "PBM: Dtd has no prev and not first of list\n");
772: } else {
773: if (dtd->prev->next != (xmlNodePtr) dtd)
774: fprintf(output, "PBM: Dtd prev->next : back link wrong\n");
775: }
776: if (dtd->next == NULL) {
777: if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
778: fprintf(output, "PBM: Dtd has no next and not last of list\n");
779: } else {
780: if (dtd->next->prev != (xmlNodePtr) dtd)
781: fprintf(output, "PBM: Dtd next->prev : forward link wrong\n");
782: }
783: if (dtd->children == NULL)
784: fprintf(output, " DTD is empty\n");
785: else
786: xmlDebugDumpNodeList(output, dtd->children, 1);
787: }
1.9 daniel 788:
1.43 veillard 789: void xmlDebugDumpEntityCallback(xmlEntityPtr cur, FILE *output,
790: const xmlChar *name) {
791: fprintf(output, "%s : ", cur->name);
792: switch (cur->etype) {
793: case XML_INTERNAL_GENERAL_ENTITY:
794: fprintf(output, "INTERNAL GENERAL, ");
795: break;
796: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
797: fprintf(output, "EXTERNAL PARSED, ");
798: break;
799: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
800: fprintf(output, "EXTERNAL UNPARSED, ");
801: break;
802: case XML_INTERNAL_PARAMETER_ENTITY:
803: fprintf(output, "INTERNAL PARAMETER, ");
804: break;
805: case XML_EXTERNAL_PARAMETER_ENTITY:
806: fprintf(output, "EXTERNAL PARAMETER, ");
807: break;
808: default:
809: fprintf(output, "UNKNOWN TYPE %d",
810: cur->etype);
811: }
812: if (cur->ExternalID != NULL)
813: fprintf(output, "ID \"%s\"", cur->ExternalID);
814: if (cur->SystemID != NULL)
815: fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
816: if (cur->orig != NULL)
817: fprintf(output, "\n orig \"%s\"", cur->orig);
818: if (cur->content != NULL)
819: fprintf(output, "\n content \"%s\"", cur->content);
820: fprintf(output, "\n");
821: }
822:
1.9 daniel 823: void xmlDebugDumpEntities(FILE *output, xmlDocPtr doc) {
824: if (output == NULL) output = stdout;
825: if (doc == NULL) {
826: fprintf(output, "DOCUMENT == NULL !\n");
827: return;
828: }
829:
830: switch (doc->type) {
831: case XML_ELEMENT_NODE:
832: fprintf(output, "Error, ELEMENT found here ");
833: break;
834: case XML_ATTRIBUTE_NODE:
835: fprintf(output, "Error, ATTRIBUTE found here\n");
836: break;
837: case XML_TEXT_NODE:
838: fprintf(output, "Error, TEXT\n");
839: break;
840: case XML_CDATA_SECTION_NODE:
841: fprintf(output, "Error, CDATA_SECTION\n");
842: break;
843: case XML_ENTITY_REF_NODE:
844: fprintf(output, "Error, ENTITY_REF\n");
845: break;
846: case XML_ENTITY_NODE:
847: fprintf(output, "Error, ENTITY\n");
848: break;
849: case XML_PI_NODE:
850: fprintf(output, "Error, PI\n");
851: break;
852: case XML_COMMENT_NODE:
853: fprintf(output, "Error, COMMENT\n");
854: break;
855: case XML_DOCUMENT_NODE:
856: fprintf(output, "DOCUMENT\n");
857: break;
858: case XML_HTML_DOCUMENT_NODE:
859: fprintf(output, "HTML DOCUMENT\n");
860: break;
861: case XML_DOCUMENT_TYPE_NODE:
862: fprintf(output, "Error, DOCUMENT_TYPE\n");
863: break;
864: case XML_DOCUMENT_FRAG_NODE:
865: fprintf(output, "Error, DOCUMENT_FRAG\n");
866: break;
867: case XML_NOTATION_NODE:
868: fprintf(output, "Error, NOTATION\n");
869: break;
870: default:
871: fprintf(output, "NODE_%d\n", doc->type);
872: }
873: if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
874: xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
875: doc->intSubset->entities;
876: fprintf(output, "Entities in internal subset\n");
1.43 veillard 877: xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
1.9 daniel 878: } else
879: fprintf(output, "No entities in internal subset\n");
880: if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
881: xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
882: doc->extSubset->entities;
883: fprintf(output, "Entities in external subset\n");
1.43 veillard 884: xmlHashScan(table, (xmlHashScanner)xmlDebugDumpEntityCallback, output);
1.9 daniel 885: } else
886: fprintf(output, "No entities in external subset\n");
887: }
1.12 daniel 888:
889: static int xmlLsCountNode(xmlNodePtr node) {
890: int ret = 0;
891: xmlNodePtr list = NULL;
892:
893: switch (node->type) {
894: case XML_ELEMENT_NODE:
1.16 daniel 895: list = node->children;
1.12 daniel 896: break;
897: case XML_DOCUMENT_NODE:
898: case XML_HTML_DOCUMENT_NODE:
1.33 veillard 899: #ifdef LIBXML_SGML_ENABLED
900: case XML_SGML_DOCUMENT_NODE:
901: #endif
1.16 daniel 902: list = ((xmlDocPtr) node)->children;
1.12 daniel 903: break;
904: case XML_ATTRIBUTE_NODE:
1.16 daniel 905: list = ((xmlAttrPtr) node)->children;
1.12 daniel 906: break;
907: case XML_TEXT_NODE:
908: case XML_CDATA_SECTION_NODE:
909: case XML_PI_NODE:
910: case XML_COMMENT_NODE:
911: if (node->content != NULL) {
912: #ifndef XML_USE_BUFFER_CONTENT
913: ret = xmlStrlen(node->content);
914: #else
915: ret = xmlBufferLength(node->content);
916: #endif
917: }
918: break;
919: case XML_ENTITY_REF_NODE:
920: case XML_DOCUMENT_TYPE_NODE:
921: case XML_ENTITY_NODE:
922: case XML_DOCUMENT_FRAG_NODE:
923: case XML_NOTATION_NODE:
1.16 daniel 924: case XML_DTD_NODE:
1.17 daniel 925: case XML_ELEMENT_DECL:
926: case XML_ATTRIBUTE_DECL:
1.20 daniel 927: case XML_ENTITY_DECL:
1.45 veillard 928: case XML_NAMESPACE_DECL:
1.46 veillard 929: case XML_XINCLUDE_START:
930: case XML_XINCLUDE_END:
1.12 daniel 931: ret = 1;
932: break;
933: }
934: for (;list != NULL;ret++)
935: list = list->next;
936: return(ret);
937: }
938:
939: void xmlLsOneNode(FILE *output, xmlNodePtr node) {
940: switch (node->type) {
941: case XML_ELEMENT_NODE:
942: fprintf(output, "-");
943: break;
944: case XML_ATTRIBUTE_NODE:
945: fprintf(output, "a");
946: break;
947: case XML_TEXT_NODE:
948: fprintf(output, "t");
949: break;
950: case XML_CDATA_SECTION_NODE:
951: fprintf(output, "c");
952: break;
953: case XML_ENTITY_REF_NODE:
954: fprintf(output, "e");
955: break;
956: case XML_ENTITY_NODE:
957: fprintf(output, "E");
958: break;
959: case XML_PI_NODE:
960: fprintf(output, "p");
961: break;
962: case XML_COMMENT_NODE:
963: fprintf(output, "c");
964: break;
965: case XML_DOCUMENT_NODE:
966: fprintf(output, "d");
967: break;
968: case XML_HTML_DOCUMENT_NODE:
969: fprintf(output, "h");
970: break;
971: case XML_DOCUMENT_TYPE_NODE:
972: fprintf(output, "T");
973: break;
974: case XML_DOCUMENT_FRAG_NODE:
975: fprintf(output, "F");
976: break;
977: case XML_NOTATION_NODE:
978: fprintf(output, "N");
979: break;
980: default:
981: fprintf(output, "?");
982: }
983: if (node->properties != NULL)
984: fprintf(output, "a");
985: else
986: fprintf(output, "-");
987: if (node->nsDef != NULL)
988: fprintf(output, "n");
989: else
990: fprintf(output, "-");
991:
992: fprintf(output, " %8d ", xmlLsCountNode(node));
993:
994: switch (node->type) {
995: case XML_ELEMENT_NODE:
996: if (node->name != NULL)
997: fprintf(output, "%s", node->name);
998: break;
999: case XML_ATTRIBUTE_NODE:
1000: if (node->name != NULL)
1001: fprintf(output, "%s", node->name);
1002: break;
1003: case XML_TEXT_NODE:
1004: if (node->content != NULL) {
1005: #ifndef XML_USE_BUFFER_CONTENT
1006: xmlDebugDumpString(output, node->content);
1007: #else
1008: xmlDebugDumpString(output, xmlBufferContent(node->content));
1009: #endif
1010: }
1011: break;
1012: case XML_CDATA_SECTION_NODE:
1013: break;
1014: case XML_ENTITY_REF_NODE:
1015: if (node->name != NULL)
1016: fprintf(output, "%s", node->name);
1017: break;
1018: case XML_ENTITY_NODE:
1019: if (node->name != NULL)
1020: fprintf(output, "%s", node->name);
1021: break;
1022: case XML_PI_NODE:
1023: if (node->name != NULL)
1024: fprintf(output, "%s", node->name);
1025: break;
1026: case XML_COMMENT_NODE:
1027: break;
1028: case XML_DOCUMENT_NODE:
1029: break;
1030: case XML_HTML_DOCUMENT_NODE:
1031: break;
1032: case XML_DOCUMENT_TYPE_NODE:
1033: break;
1034: case XML_DOCUMENT_FRAG_NODE:
1035: break;
1036: case XML_NOTATION_NODE:
1037: break;
1038: default:
1039: if (node->name != NULL)
1040: fprintf(output, "%s", node->name);
1041: }
1042: fprintf(output, "\n");
1043: }
1044:
1045: /****************************************************************
1046: * *
1047: * The XML shell related functions *
1048: * *
1049: ****************************************************************/
1050:
1051: /*
1052: * TODO: Improvement/cleanups for the XML shell
1053: * - allow to shell out an editor on a subpart
1054: * - cleanup function registrations (with help) and calling
1055: * - provide registration routines
1056: */
1057:
1058: /**
1059: * xmlShellList:
1060: * @ctxt: the shell context
1061: * @arg: unused
1062: * @node: a node
1063: * @node2: unused
1064: *
1065: * Implements the XML shell function "ls"
1066: * Does an Unix like listing of the given node (like a directory)
1067: *
1068: * Returns 0
1069: */
1070: int
1071: xmlShellList(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
1072: xmlNodePtr node2) {
1073: xmlNodePtr cur;
1074:
1075: if ((node->type == XML_DOCUMENT_NODE) ||
1076: (node->type == XML_HTML_DOCUMENT_NODE)) {
1.16 daniel 1077: cur = ((xmlDocPtr) node)->children;
1078: } else if (node->children != NULL) {
1079: cur = node->children;
1.12 daniel 1080: } else {
1081: xmlLsOneNode(stdout, node);
1082: return(0);
1083: }
1084: while (cur != NULL) {
1085: xmlLsOneNode(stdout, cur);
1086: cur = cur->next;
1087: }
1088: return(0);
1089: }
1090:
1091: /**
1092: * xmlShellDir:
1093: * @ctxt: the shell context
1094: * @arg: unused
1095: * @node: a node
1096: * @node2: unused
1097: *
1098: * Implements the XML shell function "dir"
1099: * dumps informations about the node (namespace, attributes, content).
1100: *
1101: * Returns 0
1102: */
1103: int
1104: xmlShellDir(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
1105: xmlNodePtr node2) {
1106: if ((node->type == XML_DOCUMENT_NODE) ||
1107: (node->type == XML_HTML_DOCUMENT_NODE)) {
1108: xmlDebugDumpDocumentHead(stdout, (xmlDocPtr) node);
1109: } else if (node->type == XML_ATTRIBUTE_NODE) {
1110: xmlDebugDumpAttr(stdout, (xmlAttrPtr) node, 0);
1111: } else {
1112: xmlDebugDumpOneNode(stdout, node, 0);
1113: }
1114: return(0);
1115: }
1116:
1117: /**
1118: * xmlShellCat:
1119: * @ctxt: the shell context
1120: * @arg: unused
1121: * @node: a node
1122: * @node2: unused
1123: *
1124: * Implements the XML shell function "cat"
1125: * dumps the serialization node content (XML or HTML).
1126: *
1127: * Returns 0
1128: */
1129: int
1130: xmlShellCat(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr node,
1131: xmlNodePtr node2) {
1.13 daniel 1132: if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
1.23 daniel 1133: #ifdef LIBXML_HTML_ENABLED
1.13 daniel 1134: if (node->type == XML_HTML_DOCUMENT_NODE)
1135: htmlDocDump(stdout, (htmlDocPtr) node);
1136: else
1.14 daniel 1137: htmlNodeDumpFile(stdout, ctxt->doc, node);
1.23 daniel 1138: #else
1139: if (node->type == XML_DOCUMENT_NODE)
1140: xmlDocDump(stdout, (xmlDocPtr) node);
1141: else
1142: xmlElemDump(stdout, ctxt->doc, node);
1143: #endif /* LIBXML_HTML_ENABLED */
1.13 daniel 1144: } else {
1145: if (node->type == XML_DOCUMENT_NODE)
1146: xmlDocDump(stdout, (xmlDocPtr) node);
1147: else
1148: xmlElemDump(stdout, ctxt->doc, node);
1149: }
1.12 daniel 1150: printf("\n");
1151: return(0);
1152: }
1153:
1154: /**
1155: * xmlShellLoad:
1156: * @ctxt: the shell context
1157: * @filename: the file name
1158: * @node: unused
1159: * @node2: unused
1160: *
1161: * Implements the XML shell function "load"
1162: * loads a new document specified by the filename
1163: *
1164: * Returns 0 or -1 if loading failed
1165: */
1166: int
1167: xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
1168: xmlNodePtr node2) {
1169: xmlDocPtr doc;
1170: int html = 0;
1171:
1172: if (ctxt->doc != NULL)
1173: html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
1174:
1175: if (html) {
1.23 daniel 1176: #ifdef LIBXML_HTML_ENABLED
1.12 daniel 1177: doc = htmlParseFile(filename, NULL);
1.23 daniel 1178: #else
1179: printf("HTML support not compiled in\n");
1180: doc = NULL;
1181: #endif /* LIBXML_HTML_ENABLED */
1.12 daniel 1182: } else {
1183: doc = xmlParseFile(filename);
1184: }
1185: if (doc != NULL) {
1186: if (ctxt->loaded == 1) {
1187: xmlFreeDoc(ctxt->doc);
1188: }
1189: ctxt->loaded = 1;
1.23 daniel 1190: #ifdef LIBXML_XPATH_ENABLED
1.12 daniel 1191: xmlXPathFreeContext(ctxt->pctxt);
1.23 daniel 1192: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1193: xmlFree(ctxt->filename);
1194: ctxt->doc = doc;
1195: ctxt->node = (xmlNodePtr) doc;
1.23 daniel 1196: #ifdef LIBXML_XPATH_ENABLED
1.12 daniel 1197: ctxt->pctxt = xmlXPathNewContext(doc);
1.23 daniel 1198: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1199: ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
1200: } else
1201: return(-1);
1202: return(0);
1203: }
1204:
1205: /**
1206: * xmlShellWrite:
1207: * @ctxt: the shell context
1208: * @filename: the file name
1209: * @node: a node in the tree
1210: * @node2: unused
1211: *
1212: * Implements the XML shell function "write"
1213: * Write the current node to the filename, it saves the serailization
1214: * of the subtree under the @node specified
1215: *
1216: * Returns 0 or -1 in case of error
1217: */
1218: int
1219: xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
1220: xmlNodePtr node2) {
1221: if (node == NULL)
1222: return(-1);
1223: if ((filename == NULL) || (filename[0] == 0)) {
1.44 veillard 1224: xmlGenericError(xmlGenericErrorContext,
1225: "Write command requires a filename argument\n");
1.12 daniel 1226: return(-1);
1227: }
1228: #ifdef W_OK
1229: if (access((char *) filename, W_OK)) {
1.44 veillard 1230: xmlGenericError(xmlGenericErrorContext,
1231: "Cannot write to %s\n", filename);
1.12 daniel 1232: return(-1);
1233: }
1234: #endif
1235: switch(node->type) {
1236: case XML_DOCUMENT_NODE:
1237: if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
1.44 veillard 1238: xmlGenericError(xmlGenericErrorContext,
1239: "Failed to write to %s\n", filename);
1.12 daniel 1240: return(-1);
1241: }
1242: break;
1243: case XML_HTML_DOCUMENT_NODE:
1.23 daniel 1244: #ifdef LIBXML_HTML_ENABLED
1.12 daniel 1245: if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
1.44 veillard 1246: xmlGenericError(xmlGenericErrorContext,
1247: "Failed to write to %s\n", filename);
1.12 daniel 1248: return(-1);
1249: }
1.23 daniel 1250: #else
1251: if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
1.44 veillard 1252: xmlGenericError(xmlGenericErrorContext,
1253: "Failed to write to %s\n", filename);
1.23 daniel 1254: return(-1);
1255: }
1256: #endif /* LIBXML_HTML_ENABLED */
1.12 daniel 1257: break;
1258: default: {
1259: FILE *f;
1260:
1261: f = fopen((char *) filename, "w");
1262: if (f == NULL) {
1.44 veillard 1263: xmlGenericError(xmlGenericErrorContext,
1264: "Failed to write to %s\n", filename);
1.12 daniel 1265: return(-1);
1266: }
1267: xmlElemDump(f, ctxt->doc, node);
1268: fclose(f);
1269: }
1270: }
1271: return(0);
1272: }
1273:
1274: /**
1275: * xmlShellSave:
1276: * @ctxt: the shell context
1277: * @filename: the file name (optionnal)
1278: * @node: unused
1279: * @node2: unused
1280: *
1281: * Implements the XML shell function "save"
1282: * Write the current document to the filename, or it's original name
1283: *
1284: * Returns 0 or -1 in case of error
1285: */
1286: int
1287: xmlShellSave(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
1288: xmlNodePtr node2) {
1289: if (ctxt->doc == NULL)
1290: return(-1);
1291: if ((filename == NULL) || (filename[0] == 0))
1292: filename = ctxt->filename;
1293: #ifdef W_OK
1294: if (access((char *) filename, W_OK)) {
1.44 veillard 1295: xmlGenericError(xmlGenericErrorContext,
1296: "Cannot save to %s\n", filename);
1.12 daniel 1297: return(-1);
1298: }
1299: #endif
1300: switch(ctxt->doc->type) {
1301: case XML_DOCUMENT_NODE:
1302: if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
1.44 veillard 1303: xmlGenericError(xmlGenericErrorContext,
1304: "Failed to save to %s\n", filename);
1.12 daniel 1305: }
1306: break;
1307: case XML_HTML_DOCUMENT_NODE:
1.23 daniel 1308: #ifdef LIBXML_HTML_ENABLED
1.12 daniel 1309: if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
1.44 veillard 1310: xmlGenericError(xmlGenericErrorContext,
1311: "Failed to save to %s\n", filename);
1.12 daniel 1312: }
1.23 daniel 1313: #else
1314: if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
1.44 veillard 1315: xmlGenericError(xmlGenericErrorContext,
1316: "Failed to save to %s\n", filename);
1.23 daniel 1317: }
1318: #endif /* LIBXML_HTML_ENABLED */
1.12 daniel 1319: break;
1320: default:
1.44 veillard 1321: xmlGenericError(xmlGenericErrorContext,
1.12 daniel 1322: "To save to subparts of a document use the 'write' command\n");
1323: return(-1);
1324:
1325: }
1326: return(0);
1327: }
1328:
1329: /**
1330: * xmlShellValidate:
1331: * @ctxt: the shell context
1332: * @dtd: the DTD URI (optionnal)
1333: * @node: unused
1334: * @node2: unused
1335: *
1336: * Implements the XML shell function "validate"
1337: * Validate the document, if a DTD path is provided, then the validation
1338: * is done against the given DTD.
1339: *
1340: * Returns 0 or -1 in case of error
1341: */
1342: int
1343: xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd, xmlNodePtr node,
1344: xmlNodePtr node2) {
1345: xmlValidCtxt vctxt;
1346: int res = -1;
1347:
1348: vctxt.userData = stderr;
1349: vctxt.error = (xmlValidityErrorFunc) fprintf;
1350: vctxt.warning = (xmlValidityWarningFunc) fprintf;
1351:
1352: if ((dtd == NULL) || (dtd[0] == 0)) {
1353: res = xmlValidateDocument(&vctxt, ctxt->doc);
1354: } else {
1355: xmlDtdPtr subset;
1356:
1357: subset = xmlParseDTD(NULL, (xmlChar *) dtd);
1358: if (subset != NULL) {
1359: res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
1360:
1361: xmlFreeDtd(subset);
1362: }
1363: }
1364: return(res);
1365: }
1366:
1367: /**
1368: * xmlShellDu:
1369: * @ctxt: the shell context
1370: * @arg: unused
1371: * @tree: a node defining a subtree
1372: * @node2: unused
1373: *
1374: * Implements the XML shell function "du"
1375: * show the structure of the subtree under node @tree
1376: * If @tree is null, the command works on the current node.
1377: *
1378: * Returns 0 or -1 in case of error
1379: */
1380: int
1381: xmlShellDu(xmlShellCtxtPtr ctxt, char *arg, xmlNodePtr tree,
1382: xmlNodePtr node2) {
1383: xmlNodePtr node;
1384: int indent = 0,i;
1385:
1386: if (tree == NULL) return(-1);
1387: node = tree;
1388: while (node != NULL) {
1389: if ((node->type == XML_DOCUMENT_NODE) ||
1390: (node->type == XML_HTML_DOCUMENT_NODE)) {
1391: printf("/\n");
1392: } else if (node->type == XML_ELEMENT_NODE) {
1393: for (i = 0;i < indent;i++)
1394: printf(" ");
1395: printf("%s\n", node->name);
1396: } else {
1397: }
1398:
1399: /*
1400: * Browse the full subtree, deep first
1401: */
1402:
1403: if ((node->type == XML_DOCUMENT_NODE) ||
1404: (node->type == XML_HTML_DOCUMENT_NODE)) {
1.16 daniel 1405: node = ((xmlDocPtr) node)->children;
1.25 daniel 1406: } else if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
1.12 daniel 1407: /* deep first */
1.16 daniel 1408: node = node->children;
1.12 daniel 1409: indent++;
1410: } else if ((node != tree) && (node->next != NULL)) {
1411: /* then siblings */
1412: node = node->next;
1413: } else if (node != tree) {
1414: /* go up to parents->next if needed */
1415: while (node != tree) {
1416: if (node->parent != NULL) {
1417: node = node->parent;
1418: indent--;
1419: }
1420: if ((node != tree) && (node->next != NULL)) {
1421: node = node->next;
1422: break;
1423: }
1424: if (node->parent == NULL) {
1425: node = NULL;
1426: break;
1427: }
1428: if (node == tree) {
1429: node = NULL;
1430: break;
1431: }
1432: }
1433: /* exit condition */
1434: if (node == tree)
1435: node = NULL;
1436: } else
1437: node = NULL;
1438: }
1439: return(0);
1440: }
1441:
1442: /**
1443: * xmlShellPwd:
1444: * @ctxt: the shell context
1445: * @buffer: the output buffer
1446: * @tree: a node
1447: * @node2: unused
1448: *
1449: * Implements the XML shell function "pwd"
1450: * Show the full path from the root to the node, if needed building
1451: * thumblers when similar elements exists at a given ancestor level.
1452: * The output is compatible with XPath commands.
1453: *
1454: * Returns 0 or -1 in case of error
1455: */
1456: int
1457: xmlShellPwd(xmlShellCtxtPtr ctxt, char *buffer, xmlNodePtr node,
1458: xmlNodePtr node2) {
1459: xmlNodePtr cur, tmp, next;
1460: char buf[500];
1461: char sep;
1462: const char *name;
1463: int occur = 0;
1464:
1465: buffer[0] = 0;
1466: if (node == NULL) return(-1);
1467: cur = node;
1468: do {
1469: name = "";
1470: sep= '?';
1471: occur = 0;
1472: if ((cur->type == XML_DOCUMENT_NODE) ||
1473: (cur->type == XML_HTML_DOCUMENT_NODE)) {
1474: sep = '/';
1475: next = NULL;
1476: } else if (cur->type == XML_ELEMENT_NODE) {
1477: sep = '/';
1478: name = (const char *)cur->name;
1479: next = cur->parent;
1480:
1481: /*
1482: * Thumbler index computation
1483: */
1484: tmp = cur->prev;
1485: while (tmp != NULL) {
1.35 veillard 1486: if (xmlStrEqual(cur->name, tmp->name))
1.12 daniel 1487: occur++;
1488: tmp = tmp->prev;
1489: }
1490: if (occur == 0) {
1491: tmp = cur->next;
1492: while (tmp != NULL) {
1.35 veillard 1493: if (xmlStrEqual(cur->name, tmp->name))
1.12 daniel 1494: occur++;
1495: tmp = tmp->next;
1496: }
1497: if (occur != 0) occur = 1;
1498: } else
1499: occur++;
1500: } else if (cur->type == XML_ATTRIBUTE_NODE) {
1501: sep = '@';
1502: name = (const char *) (((xmlAttrPtr) cur)->name);
1.16 daniel 1503: next = ((xmlAttrPtr) cur)->parent;
1.12 daniel 1504: } else {
1505: next = cur->parent;
1506: }
1507: if (occur == 0)
1.31 veillard 1508: #ifdef HAVE_SNPRINTF
1509: snprintf(buf, sizeof(buf), "%c%s%s", sep, name, buffer);
1510: #else
1.12 daniel 1511: sprintf(buf, "%c%s%s", sep, name, buffer);
1.31 veillard 1512: #endif
1513: else
1514: #ifdef HAVE_SNPRINTF
1515: snprintf(buf, sizeof(buf), "%c%s[%d]%s",
1516: sep, name, occur, buffer);
1517: #else
1.12 daniel 1518: sprintf(buf, "%c%s[%d]%s", sep, name, occur, buffer);
1.31 veillard 1519: #endif
1520: buf[sizeof(buf) - 1] = 0;
1521: /*
1522: * This test prevents buffer overflow, because this routine
1523: * is only called by xmlShell, in which the second argument is
1524: * 500 chars long.
1525: * It is a dirty hack before a cleaner solution is found.
1526: * Documentation should mention that the second argument must
1527: * be at least 500 chars long, and could be stripped if too long.
1528: */
1529: if (strlen(buffer) + strlen(buf) > 499)
1530: break;
1.12 daniel 1531: strcpy(buffer, buf);
1532: cur = next;
1533: } while (cur != NULL);
1534: return(0);
1535: }
1536:
1537: /**
1538: * xmlShell
1539: * @doc: the initial document
1540: * @filename: the output buffer
1541: * @input: the line reading function
1542: * @output: the output FILE*
1543: *
1544: * Implements the XML shell
1545: * This allow to load, validate, view, modify and save a document
1546: * using a environment similar to a UNIX commandline.
1547: */
1548: void
1549: xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
1550: FILE *output) {
1551: char prompt[500] = "/ > ";
1.39 veillard 1552: char *cmdline = NULL, *cur;
1.12 daniel 1553: int nbargs;
1554: char command[100];
1555: char arg[400];
1.39 veillard 1556: int i;
1.12 daniel 1557: xmlShellCtxtPtr ctxt;
1558: xmlXPathObjectPtr list;
1559:
1560: if (doc == NULL)
1561: return;
1562: if (filename == NULL)
1563: return;
1564: if (input == NULL)
1565: return;
1566: if (output == NULL)
1567: return;
1568: ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
1569: if (ctxt == NULL)
1570: return;
1571: ctxt->loaded = 0;
1572: ctxt->doc = doc;
1573: ctxt->input = input;
1574: ctxt->output = output;
1575: ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
1576: ctxt->node = (xmlNodePtr) ctxt->doc;
1577:
1.23 daniel 1578: #ifdef LIBXML_XPATH_ENABLED
1.12 daniel 1579: ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
1580: if (ctxt->pctxt == NULL) {
1581: xmlFree(ctxt);
1582: return;
1583: }
1.23 daniel 1584: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1585: while (1) {
1586: if (ctxt->node == (xmlNodePtr) ctxt->doc)
1587: sprintf(prompt, "%s > ", "/");
1588: else if (ctxt->node->name)
1.31 veillard 1589: #ifdef HAVE_SNPRINTF
1590: snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
1591: #else
1.34 veillard 1592: sprintf(prompt, "%s > ", ctxt->node->name);
1.31 veillard 1593: #endif
1594: else
1.12 daniel 1595: sprintf(prompt, "? > ");
1.31 veillard 1596: prompt[sizeof(prompt) - 1] = 0;
1.12 daniel 1597:
1.39 veillard 1598: /*
1599: * Get a new command line
1600: */
1.12 daniel 1601: cmdline = ctxt->input(prompt);
1602: if (cmdline == NULL) break;
1603:
1.39 veillard 1604: /*
1605: * Parse the command itself
1606: */
1607: cur = cmdline;
1608: while ((*cur == ' ') || (*cur == '\t')) cur++;
1609: i = 0;
1610: while ((*cur != ' ') && (*cur != '\t') &&
1611: (*cur != '\n') && (*cur != '\r')) {
1612: if (*cur == 0)
1613: break;
1614: command[i++] = *cur++;
1615: }
1616: command[i] = 0;
1617: if (i == 0) continue;
1618: nbargs++;
1.12 daniel 1619:
1.39 veillard 1620: /*
1621: * Parse the argument
1622: */
1623: while ((*cur == ' ') || (*cur == '\t')) cur++;
1624: i = 0;
1625: while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
1626: if (*cur == 0)
1627: break;
1628: arg[i++] = *cur++;
1629: }
1630: arg[i] = 0;
1631: if (i != 0)
1632: nbargs++;
1633:
1634: /*
1635: * start interpreting the command
1636: */
1.12 daniel 1637: if (!strcmp(command, "exit"))
1638: break;
1639: if (!strcmp(command, "quit"))
1640: break;
1641: if (!strcmp(command, "bye"))
1642: break;
1643: if (!strcmp(command, "validate")) {
1644: xmlShellValidate(ctxt, arg, NULL, NULL);
1645: } else if (!strcmp(command, "load")) {
1646: xmlShellLoad(ctxt, arg, NULL, NULL);
1647: } else if (!strcmp(command, "save")) {
1648: xmlShellSave(ctxt, arg, NULL, NULL);
1649: } else if (!strcmp(command, "write")) {
1650: xmlShellWrite(ctxt, arg, NULL, NULL);
1651: } else if (!strcmp(command, "free")) {
1652: if (arg[0] == 0) {
1653: xmlMemShow(stdout, 0);
1654: } else {
1655: int len = 0;
1656: sscanf(arg, "%d", &len);
1657: xmlMemShow(stdout, len);
1658: }
1659: } else if (!strcmp(command, "pwd")) {
1660: char dir[500];
1661: if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
1662: printf("%s\n", dir);
1663: } else if (!strcmp(command, "du")) {
1664: xmlShellDu(ctxt, NULL, ctxt->node, NULL);
1665: } else if ((!strcmp(command, "ls")) ||
1666: (!strcmp(command, "dir"))) {
1667: int dir = (!strcmp(command, "dir"));
1668: if (arg[0] == 0) {
1669: if (dir)
1670: xmlShellDir(ctxt, NULL, ctxt->node, NULL);
1671: else
1672: xmlShellList(ctxt, NULL, ctxt->node, NULL);
1673: } else {
1674: ctxt->pctxt->node = ctxt->node;
1.23 daniel 1675: #ifdef LIBXML_XPATH_ENABLED
1.36 veillard 1676: ctxt->pctxt->node = ctxt->node;
1.12 daniel 1677: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
1.23 daniel 1678: #else
1679: list = NULL;
1680: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1681: if (list != NULL) {
1682: switch (list->type) {
1683: case XPATH_UNDEFINED:
1.44 veillard 1684: xmlGenericError(xmlGenericErrorContext,
1685: "%s: no such node\n", arg);
1.12 daniel 1686: break;
1687: case XPATH_NODESET: {
1688: int i;
1689:
1690: for (i = 0;i < list->nodesetval->nodeNr;i++) {
1691: if (dir)
1692: xmlShellDir(ctxt, NULL,
1693: list->nodesetval->nodeTab[i], NULL);
1694: else
1695: xmlShellList(ctxt, NULL,
1696: list->nodesetval->nodeTab[i], NULL);
1697: }
1698: break;
1699: }
1700: case XPATH_BOOLEAN:
1.44 veillard 1701: xmlGenericError(xmlGenericErrorContext,
1702: "%s is a Boolean\n", arg);
1.12 daniel 1703: break;
1704: case XPATH_NUMBER:
1.44 veillard 1705: xmlGenericError(xmlGenericErrorContext,
1706: "%s is a number\n", arg);
1.12 daniel 1707: break;
1708: case XPATH_STRING:
1.44 veillard 1709: xmlGenericError(xmlGenericErrorContext,
1710: "%s is a string\n", arg);
1.12 daniel 1711: break;
1.37 veillard 1712: case XPATH_POINT:
1.44 veillard 1713: xmlGenericError(xmlGenericErrorContext,
1714: "%s is a point\n", arg);
1.37 veillard 1715: break;
1716: case XPATH_RANGE:
1.44 veillard 1717: xmlGenericError(xmlGenericErrorContext,
1718: "%s is a range\n", arg);
1.37 veillard 1719: break;
1.38 veillard 1720: case XPATH_LOCATIONSET:
1.44 veillard 1721: xmlGenericError(xmlGenericErrorContext,
1722: "%s is a range\n", arg);
1.37 veillard 1723: break;
1724: case XPATH_USERS:
1.44 veillard 1725: xmlGenericError(xmlGenericErrorContext,
1726: "%s is user-defined\n", arg);
1.37 veillard 1727: break;
1.12 daniel 1728: }
1729: xmlXPathFreeNodeSetList(list);
1730: } else {
1.44 veillard 1731: xmlGenericError(xmlGenericErrorContext,
1732: "%s: no such node\n", arg);
1.12 daniel 1733: }
1.36 veillard 1734: ctxt->pctxt->node = NULL;
1.12 daniel 1735: }
1736: } else if (!strcmp(command, "cd")) {
1737: if (arg[0] == 0) {
1738: ctxt->node = (xmlNodePtr) ctxt->doc;
1739: } else {
1.36 veillard 1740: #ifdef LIBXML_XPATH_ENABLED
1.12 daniel 1741: ctxt->pctxt->node = ctxt->node;
1742: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
1.23 daniel 1743: #else
1744: list = NULL;
1745: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1746: if (list != NULL) {
1747: switch (list->type) {
1748: case XPATH_UNDEFINED:
1.44 veillard 1749: xmlGenericError(xmlGenericErrorContext,
1750: "%s: no such node\n", arg);
1.12 daniel 1751: break;
1752: case XPATH_NODESET:
1753: if (list->nodesetval->nodeNr == 1) {
1754: ctxt->node = list->nodesetval->nodeTab[0];
1755: } else
1.44 veillard 1756: xmlGenericError(xmlGenericErrorContext,
1757: "%s is a %d Node Set\n",
1.12 daniel 1758: arg, list->nodesetval->nodeNr);
1759: break;
1760: case XPATH_BOOLEAN:
1.44 veillard 1761: xmlGenericError(xmlGenericErrorContext,
1762: "%s is a Boolean\n", arg);
1.12 daniel 1763: break;
1764: case XPATH_NUMBER:
1.44 veillard 1765: xmlGenericError(xmlGenericErrorContext,
1766: "%s is a number\n", arg);
1.12 daniel 1767: break;
1768: case XPATH_STRING:
1.44 veillard 1769: xmlGenericError(xmlGenericErrorContext,
1770: "%s is a string\n", arg);
1.12 daniel 1771: break;
1.37 veillard 1772: case XPATH_POINT:
1.44 veillard 1773: xmlGenericError(xmlGenericErrorContext,
1774: "%s is a point\n", arg);
1.37 veillard 1775: break;
1776: case XPATH_RANGE:
1.44 veillard 1777: xmlGenericError(xmlGenericErrorContext,
1778: "%s is a range\n", arg);
1.37 veillard 1779: break;
1.38 veillard 1780: case XPATH_LOCATIONSET:
1.44 veillard 1781: xmlGenericError(xmlGenericErrorContext,
1782: "%s is a range\n", arg);
1.37 veillard 1783: break;
1784: case XPATH_USERS:
1.44 veillard 1785: xmlGenericError(xmlGenericErrorContext,
1786: "%s is user-defined\n", arg);
1.37 veillard 1787: break;
1.12 daniel 1788: }
1789: xmlXPathFreeNodeSetList(list);
1790: } else {
1.44 veillard 1791: xmlGenericError(xmlGenericErrorContext,
1792: "%s: no such node\n", arg);
1.12 daniel 1793: }
1.36 veillard 1794: ctxt->pctxt->node = NULL;
1.12 daniel 1795: }
1796: } else if (!strcmp(command, "cat")) {
1797: if (arg[0] == 0) {
1798: xmlShellCat(ctxt, NULL, ctxt->node, NULL);
1799: } else {
1800: ctxt->pctxt->node = ctxt->node;
1.23 daniel 1801: #ifdef LIBXML_XPATH_ENABLED
1.36 veillard 1802: ctxt->pctxt->node = ctxt->node;
1.12 daniel 1803: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
1.23 daniel 1804: #else
1805: list = NULL;
1806: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1807: if (list != NULL) {
1808: switch (list->type) {
1809: case XPATH_UNDEFINED:
1.44 veillard 1810: xmlGenericError(xmlGenericErrorContext,
1811: "%s: no such node\n", arg);
1.12 daniel 1812: break;
1813: case XPATH_NODESET: {
1814: int i;
1815:
1816: for (i = 0;i < list->nodesetval->nodeNr;i++) {
1817: if (i > 0) printf(" -------\n");
1818: xmlShellCat(ctxt, NULL,
1819: list->nodesetval->nodeTab[i], NULL);
1820: }
1821: break;
1822: }
1823: case XPATH_BOOLEAN:
1.44 veillard 1824: xmlGenericError(xmlGenericErrorContext,
1825: "%s is a Boolean\n", arg);
1.12 daniel 1826: break;
1827: case XPATH_NUMBER:
1.44 veillard 1828: xmlGenericError(xmlGenericErrorContext,
1829: "%s is a number\n", arg);
1.12 daniel 1830: break;
1831: case XPATH_STRING:
1.44 veillard 1832: xmlGenericError(xmlGenericErrorContext,
1833: "%s is a string\n", arg);
1.37 veillard 1834: break;
1835: case XPATH_POINT:
1.44 veillard 1836: xmlGenericError(xmlGenericErrorContext,
1837: "%s is a point\n", arg);
1.37 veillard 1838: break;
1839: case XPATH_RANGE:
1.44 veillard 1840: xmlGenericError(xmlGenericErrorContext,
1841: "%s is a range\n", arg);
1.37 veillard 1842: break;
1.38 veillard 1843: case XPATH_LOCATIONSET:
1.44 veillard 1844: xmlGenericError(xmlGenericErrorContext,
1845: "%s is a range\n", arg);
1.37 veillard 1846: break;
1847: case XPATH_USERS:
1.44 veillard 1848: xmlGenericError(xmlGenericErrorContext,
1849: "%s is user-defined\n", arg);
1.12 daniel 1850: break;
1851: }
1852: xmlXPathFreeNodeSetList(list);
1853: } else {
1.44 veillard 1854: xmlGenericError(xmlGenericErrorContext,
1855: "%s: no such node\n", arg);
1.12 daniel 1856: }
1.36 veillard 1857: ctxt->pctxt->node = NULL;
1.12 daniel 1858: }
1859: } else {
1.44 veillard 1860: xmlGenericError(xmlGenericErrorContext,
1861: "Unknown command %s\n", command);
1.12 daniel 1862: }
1863: free(cmdline); /* not xmlFree here ! */
1864: }
1.23 daniel 1865: #ifdef LIBXML_XPATH_ENABLED
1.12 daniel 1866: xmlXPathFreeContext(ctxt->pctxt);
1.23 daniel 1867: #endif /* LIBXML_XPATH_ENABLED */
1.12 daniel 1868: if (ctxt->loaded) {
1869: xmlFreeDoc(ctxt->doc);
1870: }
1871: xmlFree(ctxt);
1872: if (cmdline != NULL)
1873: free(cmdline); /* not xmlFree here ! */
1874: }
1875:
1.23 daniel 1876: #endif /* LIBXML_DEBUG_ENABLED */
Webmaster