pocxxeci 0.30.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pocxxeci might be problematic. Click here for more details.

Files changed (160) hide show
  1. package/LICENSE +19 -0
  2. package/Makefile +18 -0
  3. package/README.md +52 -0
  4. package/binding.gyp +81 -0
  5. package/index.d.ts +273 -0
  6. package/index.js +45 -0
  7. package/lib/bindings.js +1 -0
  8. package/lib/document.js +122 -0
  9. package/lib/element.js +82 -0
  10. package/lib/sax_parser.js +38 -0
  11. package/package.json +70 -0
  12. package/src/html_document.cc +7 -0
  13. package/src/html_document.h +18 -0
  14. package/src/libxmljs.cc +252 -0
  15. package/src/libxmljs.h +53 -0
  16. package/src/xml_attribute.cc +173 -0
  17. package/src/xml_attribute.h +40 -0
  18. package/src/xml_comment.cc +117 -0
  19. package/src/xml_comment.h +30 -0
  20. package/src/xml_document.cc +810 -0
  21. package/src/xml_document.h +67 -0
  22. package/src/xml_element.cc +565 -0
  23. package/src/xml_element.h +61 -0
  24. package/src/xml_namespace.cc +158 -0
  25. package/src/xml_namespace.h +39 -0
  26. package/src/xml_node.cc +761 -0
  27. package/src/xml_node.h +73 -0
  28. package/src/xml_pi.cc +161 -0
  29. package/src/xml_pi.h +34 -0
  30. package/src/xml_sax_parser.cc +424 -0
  31. package/src/xml_sax_parser.h +73 -0
  32. package/src/xml_syntax_error.cc +66 -0
  33. package/src/xml_syntax_error.h +25 -0
  34. package/src/xml_text.cc +320 -0
  35. package/src/xml_text.h +48 -0
  36. package/src/xml_textwriter.cc +315 -0
  37. package/src/xml_textwriter.h +62 -0
  38. package/src/xml_xpath_context.cc +70 -0
  39. package/src/xml_xpath_context.h +23 -0
  40. package/vendor/libxml/Copyright +23 -0
  41. package/vendor/libxml/DOCBparser.c +305 -0
  42. package/vendor/libxml/HTMLparser.c +7287 -0
  43. package/vendor/libxml/HTMLtree.c +1200 -0
  44. package/vendor/libxml/Makefile +2983 -0
  45. package/vendor/libxml/SAX.c +180 -0
  46. package/vendor/libxml/SAX2.c +3036 -0
  47. package/vendor/libxml/buf.c +1351 -0
  48. package/vendor/libxml/buf.h +72 -0
  49. package/vendor/libxml/c14n.c +2234 -0
  50. package/vendor/libxml/catalog.c +3828 -0
  51. package/vendor/libxml/chvalid.c +336 -0
  52. package/vendor/libxml/config.h +294 -0
  53. package/vendor/libxml/config.h.gch +0 -0
  54. package/vendor/libxml/debugXML.c +3423 -0
  55. package/vendor/libxml/dict.c +1298 -0
  56. package/vendor/libxml/elfgcchack.h +17818 -0
  57. package/vendor/libxml/enc.h +32 -0
  58. package/vendor/libxml/encoding.c +3975 -0
  59. package/vendor/libxml/entities.c +1163 -0
  60. package/vendor/libxml/error.c +998 -0
  61. package/vendor/libxml/globals.c +1126 -0
  62. package/vendor/libxml/hash.c +1146 -0
  63. package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
  64. package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
  65. package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
  66. package/vendor/libxml/include/libxml/Makefile +725 -0
  67. package/vendor/libxml/include/libxml/Makefile.am +54 -0
  68. package/vendor/libxml/include/libxml/Makefile.in +725 -0
  69. package/vendor/libxml/include/libxml/SAX.h +173 -0
  70. package/vendor/libxml/include/libxml/SAX2.h +178 -0
  71. package/vendor/libxml/include/libxml/c14n.h +128 -0
  72. package/vendor/libxml/include/libxml/catalog.h +182 -0
  73. package/vendor/libxml/include/libxml/chvalid.h +230 -0
  74. package/vendor/libxml/include/libxml/debugXML.h +217 -0
  75. package/vendor/libxml/include/libxml/dict.h +79 -0
  76. package/vendor/libxml/include/libxml/encoding.h +245 -0
  77. package/vendor/libxml/include/libxml/entities.h +151 -0
  78. package/vendor/libxml/include/libxml/globals.h +508 -0
  79. package/vendor/libxml/include/libxml/hash.h +236 -0
  80. package/vendor/libxml/include/libxml/list.h +137 -0
  81. package/vendor/libxml/include/libxml/nanoftp.h +163 -0
  82. package/vendor/libxml/include/libxml/nanohttp.h +81 -0
  83. package/vendor/libxml/include/libxml/parser.h +1243 -0
  84. package/vendor/libxml/include/libxml/parserInternals.h +644 -0
  85. package/vendor/libxml/include/libxml/pattern.h +100 -0
  86. package/vendor/libxml/include/libxml/relaxng.h +217 -0
  87. package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
  88. package/vendor/libxml/include/libxml/schematron.h +142 -0
  89. package/vendor/libxml/include/libxml/threads.h +89 -0
  90. package/vendor/libxml/include/libxml/tree.h +1311 -0
  91. package/vendor/libxml/include/libxml/uri.h +94 -0
  92. package/vendor/libxml/include/libxml/valid.h +458 -0
  93. package/vendor/libxml/include/libxml/xinclude.h +129 -0
  94. package/vendor/libxml/include/libxml/xlink.h +189 -0
  95. package/vendor/libxml/include/libxml/xmlIO.h +368 -0
  96. package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
  97. package/vendor/libxml/include/libxml/xmlerror.h +945 -0
  98. package/vendor/libxml/include/libxml/xmlexports.h +77 -0
  99. package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
  100. package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
  101. package/vendor/libxml/include/libxml/xmlreader.h +428 -0
  102. package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
  103. package/vendor/libxml/include/libxml/xmlsave.h +88 -0
  104. package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
  105. package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
  106. package/vendor/libxml/include/libxml/xmlstring.h +140 -0
  107. package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
  108. package/vendor/libxml/include/libxml/xmlversion.h +484 -0
  109. package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
  110. package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
  111. package/vendor/libxml/include/libxml/xpath.h +564 -0
  112. package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
  113. package/vendor/libxml/include/libxml/xpointer.h +114 -0
  114. package/vendor/libxml/include/win32config.h +122 -0
  115. package/vendor/libxml/include/wsockcompat.h +54 -0
  116. package/vendor/libxml/legacy.c +1343 -0
  117. package/vendor/libxml/libxml.h +134 -0
  118. package/vendor/libxml/list.c +779 -0
  119. package/vendor/libxml/nanoftp.c +2118 -0
  120. package/vendor/libxml/nanohttp.c +1899 -0
  121. package/vendor/libxml/parser.c +15553 -0
  122. package/vendor/libxml/parserInternals.c +2164 -0
  123. package/vendor/libxml/pattern.c +2621 -0
  124. package/vendor/libxml/relaxng.c +11101 -0
  125. package/vendor/libxml/rngparser.c +1595 -0
  126. package/vendor/libxml/runsuite.c +1157 -0
  127. package/vendor/libxml/save.h +36 -0
  128. package/vendor/libxml/schematron.c +1787 -0
  129. package/vendor/libxml/threads.c +1049 -0
  130. package/vendor/libxml/timsort.h +601 -0
  131. package/vendor/libxml/tree.c +10183 -0
  132. package/vendor/libxml/trio.c +6895 -0
  133. package/vendor/libxml/trio.h +230 -0
  134. package/vendor/libxml/triodef.h +228 -0
  135. package/vendor/libxml/trionan.c +914 -0
  136. package/vendor/libxml/trionan.h +84 -0
  137. package/vendor/libxml/triop.h +150 -0
  138. package/vendor/libxml/triostr.c +2112 -0
  139. package/vendor/libxml/triostr.h +144 -0
  140. package/vendor/libxml/uri.c +2561 -0
  141. package/vendor/libxml/valid.c +7138 -0
  142. package/vendor/libxml/xinclude.c +2657 -0
  143. package/vendor/libxml/xlink.c +183 -0
  144. package/vendor/libxml/xmlIO.c +4135 -0
  145. package/vendor/libxml/xmlcatalog.c +624 -0
  146. package/vendor/libxml/xmllint.c +3796 -0
  147. package/vendor/libxml/xmlmemory.c +1163 -0
  148. package/vendor/libxml/xmlmodule.c +468 -0
  149. package/vendor/libxml/xmlreader.c +6033 -0
  150. package/vendor/libxml/xmlregexp.c +8271 -0
  151. package/vendor/libxml/xmlsave.c +2735 -0
  152. package/vendor/libxml/xmlschemas.c +29173 -0
  153. package/vendor/libxml/xmlschemastypes.c +6276 -0
  154. package/vendor/libxml/xmlstring.c +1050 -0
  155. package/vendor/libxml/xmlunicode.c +3179 -0
  156. package/vendor/libxml/xmlwriter.c +4738 -0
  157. package/vendor/libxml/xpath.c +14734 -0
  158. package/vendor/libxml/xpointer.c +2969 -0
  159. package/vendor/libxml/xzlib.c +815 -0
  160. package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,3423 @@
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
+
81
+ /**
82
+ * xmlNsCheckScope:
83
+ * @node: the node
84
+ * @ns: the namespace node
85
+ *
86
+ * Check that a given namespace is in scope on a node.
87
+ *
88
+ * Returns 1 if in scope, -1 in case of argument error,
89
+ * -2 if the namespace is not in scope, and -3 if not on
90
+ * an ancestor node.
91
+ */
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
+
150
+ /**
151
+ * xmlDebugErr:
152
+ * @ctxt: a debug context
153
+ * @error: the error code
154
+ *
155
+ * Handle a debug error.
156
+ */
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
+
188
+ /**
189
+ * xmlCtxtNsCheckScope:
190
+ * @ctxt: the debugging context
191
+ * @node: the node
192
+ * @ns: the namespace node
193
+ *
194
+ * Report if a given namespace is is not in scope.
195
+ */
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
+
222
+ /**
223
+ * xmlCtxtCheckString:
224
+ * @ctxt: the debug context
225
+ * @str: the string
226
+ *
227
+ * Do debugging on the string, currently it just checks the UTF-8 content
228
+ */
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
+
241
+ /**
242
+ * xmlCtxtCheckName:
243
+ * @ctxt: the debug context
244
+ * @name: the name
245
+ *
246
+ * Do debugging on the name, for example the dictionary status and
247
+ * conformance to the Name production.
248
+ */
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;
393
+ case XML_CDATA_SECTION_NODE:
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:
402
+ case XML_DOCUMENT_TYPE_NODE:
403
+ case XML_DOCUMENT_FRAG_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:
416
+ case XML_HTML_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;
517
+ case XML_ATTRIBUTE_IDREFS:
518
+ fprintf(ctxt->output, " IDREFS");
519
+ break;
520
+ case XML_ATTRIBUTE_ENTITY:
521
+ fprintf(ctxt->output, " ENTITY");
522
+ break;
523
+ case XML_ATTRIBUTE_ENTITIES:
524
+ fprintf(ctxt->output, " ENTITIES");
525
+ break;
526
+ case XML_ATTRIBUTE_NMTOKEN:
527
+ fprintf(ctxt->output, " NMTOKEN");
528
+ break;
529
+ case XML_ATTRIBUTE_NMTOKENS:
530
+ fprintf(ctxt->output, " NMTOKENS");
531
+ break;
532
+ case XML_ATTRIBUTE_ENUMERATION:
533
+ fprintf(ctxt->output, " ENUMERATION");
534
+ break;
535
+ case XML_ATTRIBUTE_NOTATION:
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;
560
+ case XML_ATTRIBUTE_REQUIRED:
561
+ fprintf(ctxt->output, " REQUIRED");
562
+ break;
563
+ case XML_ATTRIBUTE_IMPLIED:
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) {
610
+ case XML_ELEMENT_TYPE_UNDEFINED:
611
+ fprintf(ctxt->output, ", UNDEFINED");
612
+ break;
613
+ case XML_ELEMENT_TYPE_EMPTY:
614
+ fprintf(ctxt->output, ", EMPTY");
615
+ break;
616
+ case XML_ELEMENT_TYPE_ANY:
617
+ fprintf(ctxt->output, ", ANY");
618
+ break;
619
+ case XML_ELEMENT_TYPE_MIXED:
620
+ fprintf(ctxt->output, ", MIXED ");
621
+ break;
622
+ case XML_ELEMENT_TYPE_ELEMENT:
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) {
669
+ case XML_INTERNAL_GENERAL_ENTITY:
670
+ fprintf(ctxt->output, ", internal\n");
671
+ break;
672
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
673
+ fprintf(ctxt->output, ", external parsed\n");
674
+ break;
675
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
676
+ fprintf(ctxt->output, ", unparsed\n");
677
+ break;
678
+ case XML_INTERNAL_PARAMETER_ENTITY:
679
+ fprintf(ctxt->output, ", parameter\n");
680
+ break;
681
+ case XML_EXTERNAL_PARAMETER_ENTITY:
682
+ fprintf(ctxt->output, ", external parameter\n");
683
+ break;
684
+ case XML_INTERNAL_PREDEFINED_ENTITY:
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) {
774
+ case XML_INTERNAL_GENERAL_ENTITY:
775
+ fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY ");
776
+ break;
777
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
778
+ fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
779
+ break;
780
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
781
+ fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
782
+ break;
783
+ case XML_INTERNAL_PARAMETER_ENTITY:
784
+ fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY ");
785
+ break;
786
+ case XML_EXTERNAL_PARAMETER_ENTITY:
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
+
815
+ /**
816
+ * xmlCtxtDumpAttr:
817
+ * @output: the FILE * for the output
818
+ * @attr: the attribute
819
+ * @depth: the indentation level.
820
+ *
821
+ * Dumps debug information for the attribute
822
+ */
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
+
853
+ /**
854
+ * xmlCtxtDumpAttrList:
855
+ * @output: the FILE * for the output
856
+ * @attr: the attribute list
857
+ * @depth: the indentation level.
858
+ *
859
+ * Dumps debug information for the attribute list
860
+ */
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
+
870
+ /**
871
+ * xmlCtxtDumpOneNode:
872
+ * @output: the FILE * for the output
873
+ * @node: the node
874
+ * @depth: the indentation level.
875
+ *
876
+ * Dumps debug information for the element node, it is not recursive
877
+ */
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;
927
+ case XML_CDATA_SECTION_NODE:
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:
959
+ case XML_HTML_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;
966
+ case XML_DOCUMENT_TYPE_NODE:
967
+ if (!ctxt->check) {
968
+ xmlCtxtDumpSpaces(ctxt);
969
+ fprintf(ctxt->output, "DOCUMENT_TYPE\n");
970
+ }
971
+ break;
972
+ case XML_DOCUMENT_FRAG_NODE:
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
+
1053
+ /**
1054
+ * xmlCtxtDumpNode:
1055
+ * @output: the FILE * for the output
1056
+ * @node: the node
1057
+ * @depth: the indentation level.
1058
+ *
1059
+ * Dumps debug information for the element node, it is recursive
1060
+ */
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
+
1080
+ /**
1081
+ * xmlCtxtDumpNodeList:
1082
+ * @output: the FILE * for the output
1083
+ * @node: the node list
1084
+ * @depth: the indentation level.
1085
+ *
1086
+ * Dumps debug information for the list of element node, it is recursive
1087
+ */
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;
1120
+ case XML_CDATA_SECTION_NODE:
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;
1144
+ case XML_HTML_DOCUMENT_NODE:
1145
+ if (!ctxt->check)
1146
+ fprintf(ctxt->output, "HTML DOCUMENT\n");
1147
+ break;
1148
+ case XML_DOCUMENT_TYPE_NODE:
1149
+ xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE,
1150
+ "Misplaced DOCTYPE node\n");
1151
+ break;
1152
+ case XML_DOCUMENT_FRAG_NODE:
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
+
1166
+ /**
1167
+ * xmlCtxtDumpDocumentHead:
1168
+ * @output: the FILE * for the output
1169
+ * @doc: the document
1170
+ *
1171
+ * Dumps debug information concerning the document, not recursive
1172
+ */
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
+
1206
+ /**
1207
+ * xmlCtxtDumpDocument:
1208
+ * @output: the FILE * for the output
1209
+ * @doc: the document
1210
+ *
1211
+ * Dumps debug information for the document, it's recursive
1212
+ */
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) {
1245
+ case XML_INTERNAL_GENERAL_ENTITY:
1246
+ fprintf(ctxt->output, "INTERNAL GENERAL, ");
1247
+ break;
1248
+ case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1249
+ fprintf(ctxt->output, "EXTERNAL PARSED, ");
1250
+ break;
1251
+ case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1252
+ fprintf(ctxt->output, "EXTERNAL UNPARSED, ");
1253
+ break;
1254
+ case XML_INTERNAL_PARAMETER_ENTITY:
1255
+ fprintf(ctxt->output, "INTERNAL PARAMETER, ");
1256
+ break;
1257
+ case XML_EXTERNAL_PARAMETER_ENTITY:
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
+
1277
+ /**
1278
+ * xmlCtxtDumpEntities:
1279
+ * @output: the FILE * for the output
1280
+ * @doc: the document
1281
+ *
1282
+ * Dumps debug information for all the entities in use by the document
1283
+ */
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)) {
1290
+ xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
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)) {
1299
+ xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
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
+
1309
+ /**
1310
+ * xmlCtxtDumpDTD:
1311
+ * @output: the FILE * for the output
1312
+ * @dtd: the DTD
1313
+ *
1314
+ * Dumps debug information for the DTD
1315
+ */
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
+
1340
+ /**
1341
+ * xmlDebugDumpString:
1342
+ * @output: the FILE * for the output
1343
+ * @str: the string
1344
+ *
1345
+ * Dumps information about the string, shorten it if necessary
1346
+ */
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
+
1370
+ /**
1371
+ * xmlDebugDumpAttr:
1372
+ * @output: the FILE * for the output
1373
+ * @attr: the attribute
1374
+ * @depth: the indentation level.
1375
+ *
1376
+ * Dumps debug information for the attribute
1377
+ */
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
+
1391
+ /**
1392
+ * xmlDebugDumpEntities:
1393
+ * @output: the FILE * for the output
1394
+ * @doc: the document
1395
+ *
1396
+ * Dumps debug information for all the entities in use by the document
1397
+ */
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
+
1410
+ /**
1411
+ * xmlDebugDumpAttrList:
1412
+ * @output: the FILE * for the output
1413
+ * @attr: the attribute list
1414
+ * @depth: the indentation level.
1415
+ *
1416
+ * Dumps debug information for the attribute list
1417
+ */
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
+
1431
+ /**
1432
+ * xmlDebugDumpOneNode:
1433
+ * @output: the FILE * for the output
1434
+ * @node: the node
1435
+ * @depth: the indentation level.
1436
+ *
1437
+ * Dumps debug information for the element node, it is not recursive
1438
+ */
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
+
1452
+ /**
1453
+ * xmlDebugDumpNode:
1454
+ * @output: the FILE * for the output
1455
+ * @node: the node
1456
+ * @depth: the indentation level.
1457
+ *
1458
+ * Dumps debug information for the element node, it is recursive
1459
+ */
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
+
1474
+ /**
1475
+ * xmlDebugDumpNodeList:
1476
+ * @output: the FILE * for the output
1477
+ * @node: the node list
1478
+ * @depth: the indentation level.
1479
+ *
1480
+ * Dumps debug information for the list of element node, it is recursive
1481
+ */
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
+
1496
+ /**
1497
+ * xmlDebugDumpDocumentHead:
1498
+ * @output: the FILE * for the output
1499
+ * @doc: the document
1500
+ *
1501
+ * Dumps debug information concerning the document, not recursive
1502
+ */
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
+
1517
+ /**
1518
+ * xmlDebugDumpDocument:
1519
+ * @output: the FILE * for the output
1520
+ * @doc: the document
1521
+ *
1522
+ * Dumps debug information for the document, it's recursive
1523
+ */
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
+
1538
+ /**
1539
+ * xmlDebugDumpDTD:
1540
+ * @output: the FILE * for the output
1541
+ * @dtd: the DTD
1542
+ *
1543
+ * Dumps debug information for the DTD
1544
+ */
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
+
1565
+ /**
1566
+ * xmlDebugCheckDocument:
1567
+ * @output: the FILE * for the output
1568
+ * @doc: the document
1569
+ *
1570
+ * Check the document for potential content problems, and output
1571
+ * the errors to @output
1572
+ *
1573
+ * Returns the number of errors found
1574
+ */
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
+
1596
+ /**
1597
+ * xmlLsCountNode:
1598
+ * @node: the node to count
1599
+ *
1600
+ * Count the children of @node.
1601
+ *
1602
+ * Returns the number of children of @node.
1603
+ */
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:
1617
+ case XML_HTML_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:
1627
+ case XML_CDATA_SECTION_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:
1635
+ case XML_DOCUMENT_TYPE_NODE:
1636
+ case XML_ENTITY_NODE:
1637
+ case XML_DOCUMENT_FRAG_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
+
1654
+ /**
1655
+ * xmlLsOneNode:
1656
+ * @output: the FILE * for the output
1657
+ * @node: the node to dump
1658
+ *
1659
+ * Dump to @output the type and name of @node.
1660
+ */
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;
1678
+ case XML_CDATA_SECTION_NODE:
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;
1696
+ case XML_HTML_DOCUMENT_NODE:
1697
+ fprintf(output, "h");
1698
+ break;
1699
+ case XML_DOCUMENT_TYPE_NODE:
1700
+ fprintf(output, "T");
1701
+ break;
1702
+ case XML_DOCUMENT_FRAG_NODE:
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;
1744
+ case XML_CDATA_SECTION_NODE:
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;
1762
+ case XML_HTML_DOCUMENT_NODE:
1763
+ break;
1764
+ case XML_DOCUMENT_TYPE_NODE:
1765
+ break;
1766
+ case XML_DOCUMENT_FRAG_NODE:
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
+
1787
+ /**
1788
+ * xmlBoolToText:
1789
+ * @boolval: a bool to turn into text
1790
+ *
1791
+ * Convenient way to turn bool into text
1792
+ *
1793
+ * Returns a pointer to either "True" or "False"
1794
+ */
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
+
1820
+ /**
1821
+ * xmlShellPrintXPathError:
1822
+ * @errorType: valid xpath error id
1823
+ * @arg: the argument that cause xpath to fail
1824
+ *
1825
+ * Print the xpath error to libxml default error channel
1826
+ */
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:
1837
+ xmlGenericError(xmlGenericErrorContext,
1838
+ "%s: no such node\n", arg);
1839
+ break;
1840
+
1841
+ case XPATH_BOOLEAN:
1842
+ xmlGenericError(xmlGenericErrorContext,
1843
+ "%s is a Boolean\n", arg);
1844
+ break;
1845
+ case XPATH_NUMBER:
1846
+ xmlGenericError(xmlGenericErrorContext,
1847
+ "%s is a number\n", arg);
1848
+ break;
1849
+ case XPATH_STRING:
1850
+ xmlGenericError(xmlGenericErrorContext,
1851
+ "%s is a string\n", arg);
1852
+ break;
1853
+ case XPATH_POINT:
1854
+ xmlGenericError(xmlGenericErrorContext,
1855
+ "%s is a point\n", arg);
1856
+ break;
1857
+ case XPATH_RANGE:
1858
+ xmlGenericError(xmlGenericErrorContext,
1859
+ "%s is a range\n", arg);
1860
+ break;
1861
+ case XPATH_LOCATIONSET:
1862
+ xmlGenericError(xmlGenericErrorContext,
1863
+ "%s is a range\n", arg);
1864
+ break;
1865
+ case XPATH_USERS:
1866
+ xmlGenericError(xmlGenericErrorContext,
1867
+ "%s is user-defined\n", arg);
1868
+ break;
1869
+ case XPATH_XSLT_TREE:
1870
+ xmlGenericError(xmlGenericErrorContext,
1871
+ "%s is an XSLT value tree\n", arg);
1872
+ break;
1873
+ }
1874
+ #if 0
1875
+ xmlGenericError(xmlGenericErrorContext,
1876
+ "Try casting the result string function (xpath builtin)\n",
1877
+ arg);
1878
+ #endif
1879
+ }
1880
+
1881
+
1882
+ #ifdef LIBXML_OUTPUT_ENABLED
1883
+ /**
1884
+ * xmlShellPrintNodeCtxt:
1885
+ * @ctxt : a non-null shell context
1886
+ * @node : a non-null node to print to the output FILE
1887
+ *
1888
+ * Print node to the output FILE
1889
+ */
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
+
1912
+ /**
1913
+ * xmlShellPrintNode:
1914
+ * @node : a non-null node to print to the output FILE
1915
+ *
1916
+ * Print node to the output FILE
1917
+ */
1918
+ void
1919
+ xmlShellPrintNode(xmlNodePtr node)
1920
+ {
1921
+ xmlShellPrintNodeCtxt(NULL, node);
1922
+ }
1923
+ #endif /* LIBXML_OUTPUT_ENABLED */
1924
+
1925
+ /**
1926
+ * xmlShellPrintXPathResultCtxt:
1927
+ * @ctxt: a valid shell context
1928
+ * @list: a valid result generated by an xpath evaluation
1929
+ *
1930
+ * Prints result to the output FILE
1931
+ */
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 {
1951
+ xmlGenericError(xmlGenericErrorContext,
1952
+ "Empty node set\n");
1953
+ }
1954
+ break;
1955
+ #else
1956
+ xmlGenericError(xmlGenericErrorContext,
1957
+ "Node set\n");
1958
+ #endif /* LIBXML_OUTPUT_ENABLED */
1959
+ }
1960
+ case XPATH_BOOLEAN:
1961
+ xmlGenericError(xmlGenericErrorContext,
1962
+ "Is a Boolean:%s\n",
1963
+ xmlBoolToText(list->boolval));
1964
+ break;
1965
+ case XPATH_NUMBER:
1966
+ xmlGenericError(xmlGenericErrorContext,
1967
+ "Is a number:%0g\n", list->floatval);
1968
+ break;
1969
+ case XPATH_STRING:
1970
+ xmlGenericError(xmlGenericErrorContext,
1971
+ "Is a string:%s\n", list->stringval);
1972
+ break;
1973
+
1974
+ default:
1975
+ xmlShellPrintXPathError(list->type, NULL);
1976
+ }
1977
+ }
1978
+ }
1979
+
1980
+ /**
1981
+ * xmlShellPrintXPathResult:
1982
+ * @list: a valid result generated by an xpath evaluation
1983
+ *
1984
+ * Prints result to the output FILE
1985
+ */
1986
+ void
1987
+ xmlShellPrintXPathResult(xmlXPathObjectPtr list)
1988
+ {
1989
+ xmlShellPrintXPathResultCtxt(NULL, list);
1990
+ }
1991
+
1992
+ /**
1993
+ * xmlShellList:
1994
+ * @ctxt: the shell context
1995
+ * @arg: unused
1996
+ * @node: a node
1997
+ * @node2: unused
1998
+ *
1999
+ * Implements the XML shell function "ls"
2000
+ * Does an Unix like listing of the given node (like a directory)
2001
+ *
2002
+ * Returns 0
2003
+ */
2004
+ int
2005
+ xmlShellList(xmlShellCtxtPtr ctxt,
2006
+ char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
2007
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+
2035
+ /**
2036
+ * xmlShellBase:
2037
+ * @ctxt: the shell context
2038
+ * @arg: unused
2039
+ * @node: a node
2040
+ * @node2: unused
2041
+ *
2042
+ * Implements the XML shell function "base"
2043
+ * dumps the current XML base of the node
2044
+ *
2045
+ * Returns 0
2046
+ */
2047
+ int
2048
+ xmlShellBase(xmlShellCtxtPtr ctxt,
2049
+ char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
2050
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+ /**
2073
+ * xmlShellSetBase:
2074
+ * @ctxt: the shell context
2075
+ * @arg: the new base
2076
+ * @node: a node
2077
+ * @node2: unused
2078
+ *
2079
+ * Implements the XML shell function "setbase"
2080
+ * change the current XML base of the node
2081
+ *
2082
+ * Returns 0
2083
+ */
2084
+ static int
2085
+ xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2086
+ char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
2087
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
2088
+ {
2089
+ xmlNodeSetBase(node, (xmlChar*) arg);
2090
+ return (0);
2091
+ }
2092
+ #endif
2093
+
2094
+ #ifdef LIBXML_XPATH_ENABLED
2095
+ /**
2096
+ * xmlShellRegisterNamespace:
2097
+ * @ctxt: the shell context
2098
+ * @arg: a string in prefix=nsuri format
2099
+ * @node: unused
2100
+ * @node2: unused
2101
+ *
2102
+ * Implements the XML shell function "setns"
2103
+ * register/unregister a prefix=namespace pair
2104
+ * on the XPath context
2105
+ *
2106
+ * Returns 0 on success and a negative value otherwise.
2107
+ */
2108
+ static int
2109
+ xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg,
2110
+ xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+ }
2152
+ /**
2153
+ * xmlShellRegisterRootNamespaces:
2154
+ * @ctxt: the shell context
2155
+ * @arg: unused
2156
+ * @node: the root element
2157
+ * @node2: unused
2158
+ *
2159
+ * Implements the XML shell function "setrootns"
2160
+ * which registers all namespaces declarations found on the root element.
2161
+ *
2162
+ * Returns 0 on success and a negative value otherwise.
2163
+ */
2164
+ static int
2165
+ xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
2166
+ xmlNodePtr root, xmlNodePtr node2 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
+
2185
+ /**
2186
+ * xmlShellGrep:
2187
+ * @ctxt: the shell context
2188
+ * @arg: the string or regular expression to find
2189
+ * @node: a node
2190
+ * @node2: unused
2191
+ *
2192
+ * Implements the XML shell function "grep"
2193
+ * dumps information about the node (namespace, attributes, content).
2194
+ *
2195
+ * Returns 0
2196
+ */
2197
+ static int
2198
+ xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2199
+ char *arg, xmlNodePtr node, xmlNodePtr node2 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
+
2263
+ /**
2264
+ * xmlShellDir:
2265
+ * @ctxt: the shell context
2266
+ * @arg: unused
2267
+ * @node: a node
2268
+ * @node2: unused
2269
+ *
2270
+ * Implements the XML shell function "dir"
2271
+ * dumps information about the node (namespace, attributes, content).
2272
+ *
2273
+ * Returns 0
2274
+ */
2275
+ int
2276
+ xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2277
+ char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
2278
+ xmlNodePtr node2 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
+
2297
+ /**
2298
+ * xmlShellSetContent:
2299
+ * @ctxt: the shell context
2300
+ * @value: the content as a string
2301
+ * @node: a node
2302
+ * @node2: unused
2303
+ *
2304
+ * Implements the XML shell function "dir"
2305
+ * dumps information about the node (namespace, attributes, content).
2306
+ *
2307
+ * Returns 0
2308
+ */
2309
+ static int
2310
+ xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
2311
+ char *value, xmlNodePtr node,
2312
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
2313
+ {
2314
+ xmlNodePtr results;
2315
+ xmlParserErrors ret;
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
+
2328
+ ret = xmlParseInNodeContext(node, value, strlen(value), 0, &results);
2329
+ if (ret == XML_ERR_OK) {
2330
+ if (node->children != NULL) {
2331
+ xmlFreeNodeList(node->children);
2332
+ node->children = NULL;
2333
+ node->last = NULL;
2334
+ }
2335
+ xmlAddChildList(node, results);
2336
+ } else {
2337
+ fprintf(ctxt->output, "failed to parse content\n");
2338
+ }
2339
+ return (0);
2340
+ }
2341
+
2342
+ #ifdef LIBXML_SCHEMAS_ENABLED
2343
+ /**
2344
+ * xmlShellRNGValidate:
2345
+ * @ctxt: the shell context
2346
+ * @schemas: the path to the Relax-NG schemas
2347
+ * @node: a node
2348
+ * @node2: unused
2349
+ *
2350
+ * Implements the XML shell function "relaxng"
2351
+ * validating the instance against a Relax-NG schemas
2352
+ *
2353
+ * Returns 0
2354
+ */
2355
+ static int
2356
+ xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
2357
+ xmlNodePtr node ATTRIBUTE_UNUSED,
2358
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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) {
2370
+ xmlGenericError(xmlGenericErrorContext,
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
+ /**
2394
+ * xmlShellCat:
2395
+ * @ctxt: the shell context
2396
+ * @arg: unused
2397
+ * @node: a node
2398
+ * @node2: unused
2399
+ *
2400
+ * Implements the XML shell function "cat"
2401
+ * dumps the serialization node content (XML or HTML).
2402
+ *
2403
+ * Returns 0
2404
+ */
2405
+ int
2406
+ xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
2407
+ xmlNodePtr node, xmlNodePtr node2 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
+
2438
+ /**
2439
+ * xmlShellLoad:
2440
+ * @ctxt: the shell context
2441
+ * @filename: the file name
2442
+ * @node: unused
2443
+ * @node2: unused
2444
+ *
2445
+ * Implements the XML shell function "load"
2446
+ * loads a new document specified by the filename
2447
+ *
2448
+ * Returns 0 or -1 if loading failed
2449
+ */
2450
+ int
2451
+ xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
2452
+ xmlNodePtr node ATTRIBUTE_UNUSED,
2453
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+ /**
2494
+ * xmlShellWrite:
2495
+ * @ctxt: the shell context
2496
+ * @filename: the file name
2497
+ * @node: a node in the tree
2498
+ * @node2: unused
2499
+ *
2500
+ * Implements the XML shell function "write"
2501
+ * Write the current node to the filename, it saves the serialization
2502
+ * of the subtree under the @node specified
2503
+ *
2504
+ * Returns 0 or -1 in case of error
2505
+ */
2506
+ int
2507
+ xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
2508
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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)) {
2517
+ xmlGenericError(xmlGenericErrorContext,
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) {
2525
+ xmlGenericError(xmlGenericErrorContext,
2526
+ "Failed to write to %s\n", filename);
2527
+ return (-1);
2528
+ }
2529
+ break;
2530
+ case XML_HTML_DOCUMENT_NODE:
2531
+ #ifdef LIBXML_HTML_ENABLED
2532
+ if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
2533
+ xmlGenericError(xmlGenericErrorContext,
2534
+ "Failed to write to %s\n", filename);
2535
+ return (-1);
2536
+ }
2537
+ #else
2538
+ if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
2539
+ xmlGenericError(xmlGenericErrorContext,
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) {
2550
+ xmlGenericError(xmlGenericErrorContext,
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
+
2561
+ /**
2562
+ * xmlShellSave:
2563
+ * @ctxt: the shell context
2564
+ * @filename: the file name (optional)
2565
+ * @node: unused
2566
+ * @node2: unused
2567
+ *
2568
+ * Implements the XML shell function "save"
2569
+ * Write the current document to the filename, or it's original name
2570
+ *
2571
+ * Returns 0 or -1 in case of error
2572
+ */
2573
+ int
2574
+ xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
2575
+ xmlNodePtr node ATTRIBUTE_UNUSED,
2576
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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)) {
2586
+ xmlGenericError(xmlGenericErrorContext,
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) {
2594
+ xmlGenericError(xmlGenericErrorContext,
2595
+ "Failed to save to %s\n", filename);
2596
+ }
2597
+ break;
2598
+ case XML_HTML_DOCUMENT_NODE:
2599
+ #ifdef LIBXML_HTML_ENABLED
2600
+ if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
2601
+ xmlGenericError(xmlGenericErrorContext,
2602
+ "Failed to save to %s\n", filename);
2603
+ }
2604
+ #else
2605
+ if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
2606
+ xmlGenericError(xmlGenericErrorContext,
2607
+ "Failed to save to %s\n", filename);
2608
+ }
2609
+ #endif /* LIBXML_HTML_ENABLED */
2610
+ break;
2611
+ default:
2612
+ xmlGenericError(xmlGenericErrorContext,
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
+ /**
2623
+ * xmlShellValidate:
2624
+ * @ctxt: the shell context
2625
+ * @dtd: the DTD URI (optional)
2626
+ * @node: unused
2627
+ * @node2: unused
2628
+ *
2629
+ * Implements the XML shell function "validate"
2630
+ * Validate the document, if a DTD path is provided, then the validation
2631
+ * is done against the given DTD.
2632
+ *
2633
+ * Returns 0 or -1 in case of error
2634
+ */
2635
+ int
2636
+ xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
2637
+ xmlNodePtr node ATTRIBUTE_UNUSED,
2638
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+
2664
+ /**
2665
+ * xmlShellDu:
2666
+ * @ctxt: the shell context
2667
+ * @arg: unused
2668
+ * @tree: a node defining a subtree
2669
+ * @node2: unused
2670
+ *
2671
+ * Implements the XML shell function "du"
2672
+ * show the structure of the subtree under node @tree
2673
+ * If @tree is null, the command works on the current node.
2674
+ *
2675
+ * Returns 0 or -1 in case of error
2676
+ */
2677
+ int
2678
+ xmlShellDu(xmlShellCtxtPtr ctxt,
2679
+ char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
2680
+ xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+
2748
+ /**
2749
+ * xmlShellPwd:
2750
+ * @ctxt: the shell context
2751
+ * @buffer: the output buffer
2752
+ * @node: a node
2753
+ * @node2: unused
2754
+ *
2755
+ * Implements the XML shell function "pwd"
2756
+ * Show the full path from the root to the node, if needed building
2757
+ * thumblers when similar elements exists at a given ancestor level.
2758
+ * The output is compatible with XPath commands.
2759
+ *
2760
+ * Returns 0 or -1 in case of error
2761
+ */
2762
+ int
2763
+ xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
2764
+ xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
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
+
2790
+ /**
2791
+ * xmlShell:
2792
+ * @doc: the initial document
2793
+ * @filename: the output buffer
2794
+ * @input: the line reading function
2795
+ * @output: the output FILE*, defaults to stdout if NULL
2796
+ *
2797
+ * Implements the XML shell
2798
+ * This allow to load, validate, view, modify and save a document
2799
+ * using a environment similar to a UNIX commandline.
2800
+ */
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)
2947
+ xmlGenericError(xmlGenericErrorContext,
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:
2982
+ xmlGenericError(xmlGenericErrorContext,
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:
3000
+ xmlGenericError(xmlGenericErrorContext,
3001
+ "%s is a Boolean\n", arg);
3002
+ break;
3003
+ case XPATH_NUMBER:
3004
+ xmlGenericError(xmlGenericErrorContext,
3005
+ "%s is a number\n", arg);
3006
+ break;
3007
+ case XPATH_STRING:
3008
+ xmlGenericError(xmlGenericErrorContext,
3009
+ "%s is a string\n", arg);
3010
+ break;
3011
+ case XPATH_POINT:
3012
+ xmlGenericError(xmlGenericErrorContext,
3013
+ "%s is a point\n", arg);
3014
+ break;
3015
+ case XPATH_RANGE:
3016
+ xmlGenericError(xmlGenericErrorContext,
3017
+ "%s is a range\n", arg);
3018
+ break;
3019
+ case XPATH_LOCATIONSET:
3020
+ xmlGenericError(xmlGenericErrorContext,
3021
+ "%s is a range\n", arg);
3022
+ break;
3023
+ case XPATH_USERS:
3024
+ xmlGenericError(xmlGenericErrorContext,
3025
+ "%s is user-defined\n", arg);
3026
+ break;
3027
+ case XPATH_XSLT_TREE:
3028
+ xmlGenericError(xmlGenericErrorContext,
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 {
3037
+ xmlGenericError(xmlGenericErrorContext,
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) {
3049
+ xmlGenericError(xmlGenericErrorContext,
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) {
3061
+ xmlGenericError(xmlGenericErrorContext,
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:
3093
+ xmlGenericError(xmlGenericErrorContext,
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:
3117
+ xmlGenericError(xmlGenericErrorContext,
3118
+ "%s is a Boolean\n", arg);
3119
+ break;
3120
+ case XPATH_NUMBER:
3121
+ xmlGenericError(xmlGenericErrorContext,
3122
+ "%s is a number\n", arg);
3123
+ break;
3124
+ case XPATH_STRING:
3125
+ xmlGenericError(xmlGenericErrorContext,
3126
+ "%s is a string\n", arg);
3127
+ break;
3128
+ case XPATH_POINT:
3129
+ xmlGenericError(xmlGenericErrorContext,
3130
+ "%s is a point\n", arg);
3131
+ break;
3132
+ case XPATH_RANGE:
3133
+ xmlGenericError(xmlGenericErrorContext,
3134
+ "%s is a range\n", arg);
3135
+ break;
3136
+ case XPATH_LOCATIONSET:
3137
+ xmlGenericError(xmlGenericErrorContext,
3138
+ "%s is a range\n", arg);
3139
+ break;
3140
+ case XPATH_USERS:
3141
+ xmlGenericError(xmlGenericErrorContext,
3142
+ "%s is user-defined\n", arg);
3143
+ break;
3144
+ case XPATH_XSLT_TREE:
3145
+ xmlGenericError(xmlGenericErrorContext,
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 {
3154
+ xmlGenericError(xmlGenericErrorContext,
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:
3175
+ xmlGenericError(xmlGenericErrorContext,
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:
3194
+ xmlGenericError(xmlGenericErrorContext,
3195
+ "%s is a Boolean\n", arg);
3196
+ break;
3197
+ case XPATH_NUMBER:
3198
+ xmlGenericError(xmlGenericErrorContext,
3199
+ "%s is a number\n", arg);
3200
+ break;
3201
+ case XPATH_STRING:
3202
+ xmlGenericError(xmlGenericErrorContext,
3203
+ "%s is a string\n", arg);
3204
+ break;
3205
+ case XPATH_POINT:
3206
+ xmlGenericError(xmlGenericErrorContext,
3207
+ "%s is a point\n", arg);
3208
+ break;
3209
+ case XPATH_RANGE:
3210
+ xmlGenericError(xmlGenericErrorContext,
3211
+ "%s is a range\n", arg);
3212
+ break;
3213
+ case XPATH_LOCATIONSET:
3214
+ xmlGenericError(xmlGenericErrorContext,
3215
+ "%s is a range\n", arg);
3216
+ break;
3217
+ case XPATH_USERS:
3218
+ xmlGenericError(xmlGenericErrorContext,
3219
+ "%s is user-defined\n", arg);
3220
+ break;
3221
+ case XPATH_XSLT_TREE:
3222
+ xmlGenericError(xmlGenericErrorContext,
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 {
3231
+ xmlGenericError(xmlGenericErrorContext,
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:
3254
+ xmlGenericError(xmlGenericErrorContext,
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)) {
3264
+ xmlGenericError(xmlGenericErrorContext,
3265
+ "cannot cd to namespace\n");
3266
+ ctxt->node = NULL;
3267
+ }
3268
+ } else
3269
+ xmlGenericError(xmlGenericErrorContext,
3270
+ "%s is a %d Node Set\n",
3271
+ arg,
3272
+ list->nodesetval->nodeNr);
3273
+ } else
3274
+ xmlGenericError(xmlGenericErrorContext,
3275
+ "%s is an empty Node Set\n",
3276
+ arg);
3277
+ break;
3278
+ case XPATH_BOOLEAN:
3279
+ xmlGenericError(xmlGenericErrorContext,
3280
+ "%s is a Boolean\n", arg);
3281
+ break;
3282
+ case XPATH_NUMBER:
3283
+ xmlGenericError(xmlGenericErrorContext,
3284
+ "%s is a number\n", arg);
3285
+ break;
3286
+ case XPATH_STRING:
3287
+ xmlGenericError(xmlGenericErrorContext,
3288
+ "%s is a string\n", arg);
3289
+ break;
3290
+ case XPATH_POINT:
3291
+ xmlGenericError(xmlGenericErrorContext,
3292
+ "%s is a point\n", arg);
3293
+ break;
3294
+ case XPATH_RANGE:
3295
+ xmlGenericError(xmlGenericErrorContext,
3296
+ "%s is a range\n", arg);
3297
+ break;
3298
+ case XPATH_LOCATIONSET:
3299
+ xmlGenericError(xmlGenericErrorContext,
3300
+ "%s is a range\n", arg);
3301
+ break;
3302
+ case XPATH_USERS:
3303
+ xmlGenericError(xmlGenericErrorContext,
3304
+ "%s is user-defined\n", arg);
3305
+ break;
3306
+ case XPATH_XSLT_TREE:
3307
+ xmlGenericError(xmlGenericErrorContext,
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 {
3316
+ xmlGenericError(xmlGenericErrorContext,
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:
3336
+ xmlGenericError(xmlGenericErrorContext,
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:
3357
+ xmlGenericError(xmlGenericErrorContext,
3358
+ "%s is a Boolean\n", arg);
3359
+ break;
3360
+ case XPATH_NUMBER:
3361
+ xmlGenericError(xmlGenericErrorContext,
3362
+ "%s is a number\n", arg);
3363
+ break;
3364
+ case XPATH_STRING:
3365
+ xmlGenericError(xmlGenericErrorContext,
3366
+ "%s is a string\n", arg);
3367
+ break;
3368
+ case XPATH_POINT:
3369
+ xmlGenericError(xmlGenericErrorContext,
3370
+ "%s is a point\n", arg);
3371
+ break;
3372
+ case XPATH_RANGE:
3373
+ xmlGenericError(xmlGenericErrorContext,
3374
+ "%s is a range\n", arg);
3375
+ break;
3376
+ case XPATH_LOCATIONSET:
3377
+ xmlGenericError(xmlGenericErrorContext,
3378
+ "%s is a range\n", arg);
3379
+ break;
3380
+ case XPATH_USERS:
3381
+ xmlGenericError(xmlGenericErrorContext,
3382
+ "%s is user-defined\n", arg);
3383
+ break;
3384
+ case XPATH_XSLT_TREE:
3385
+ xmlGenericError(xmlGenericErrorContext,
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 {
3394
+ xmlGenericError(xmlGenericErrorContext,
3395
+ "%s: no such node\n", arg);
3396
+ }
3397
+ ctxt->pctxt->node = NULL;
3398
+ }
3399
+ #endif /* LIBXML_OUTPUT_ENABLED */
3400
+ } else {
3401
+ xmlGenericError(xmlGenericErrorContext,
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 */