@helm2/poc_jenki_rce 0.0.1

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

Potentially problematic release.


This version of @helm2/poc_jenki_rce 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 +118 -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 */