Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygendebugXML.c
Go to the documentation of this file.
00001 /* 00002 * debugXML.c : This is a set of routines used for debugging the tree 00003 * produced by the XML parser. 00004 * 00005 * See Copyright for the status of this software. 00006 * 00007 * Daniel Veillard <daniel@veillard.com> 00008 */ 00009 00010 #define IN_LIBXML 00011 #include "libxml.h" 00012 #ifdef LIBXML_DEBUG_ENABLED 00013 00014 #include <string.h> 00015 #ifdef HAVE_STDLIB_H 00016 #include <stdlib.h> 00017 #endif 00018 #ifdef HAVE_STRING_H 00019 #include <string.h> 00020 #endif 00021 #include <libxml/xmlmemory.h> 00022 #include <libxml/tree.h> 00023 #include <libxml/parser.h> 00024 #include <libxml/parserInternals.h> 00025 #include <libxml/valid.h> 00026 #include <libxml/debugXML.h> 00027 #include <libxml/HTMLtree.h> 00028 #include <libxml/HTMLparser.h> 00029 #include <libxml/xmlerror.h> 00030 #include <libxml/globals.h> 00031 #include <libxml/xpathInternals.h> 00032 #include <libxml/uri.h> 00033 #ifdef LIBXML_SCHEMAS_ENABLED 00034 #include <libxml/relaxng.h> 00035 #endif 00036 00037 #define DUMP_TEXT_TYPE 1 00038 00039 typedef struct _xmlDebugCtxt xmlDebugCtxt; 00040 typedef xmlDebugCtxt *xmlDebugCtxtPtr; 00041 struct _xmlDebugCtxt { 00042 FILE *output; /* the output file */ 00043 char shift[101]; /* used for indenting */ 00044 int depth; /* current depth */ 00045 xmlDocPtr doc; /* current document */ 00046 xmlNodePtr node; /* current node */ 00047 xmlDictPtr dict; /* the doc dictionnary */ 00048 int check; /* do just checkings */ 00049 int errors; /* number of errors found */ 00050 int nodict; /* if the document has no dictionnary */ 00051 int options; /* options */ 00052 }; 00053 00054 static void xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node); 00055 00056 static void 00057 xmlCtxtDumpInitCtxt(xmlDebugCtxtPtr ctxt) 00058 { 00059 int i; 00060 00061 ctxt->depth = 0; 00062 ctxt->check = 0; 00063 ctxt->errors = 0; 00064 ctxt->output = stdout; 00065 ctxt->doc = NULL; 00066 ctxt->node = NULL; 00067 ctxt->dict = NULL; 00068 ctxt->nodict = 0; 00069 ctxt->options = 0; 00070 for (i = 0; i < 100; i++) 00071 ctxt->shift[i] = ' '; 00072 ctxt->shift[100] = 0; 00073 } 00074 00075 static void 00076 xmlCtxtDumpCleanCtxt(xmlDebugCtxtPtr ctxt ATTRIBUTE_UNUSED) 00077 { 00078 /* remove the ATTRIBUTE_UNUSED when this is added */ 00079 } 00080 00092 static int 00093 xmlNsCheckScope(xmlNodePtr node, xmlNsPtr ns) 00094 { 00095 xmlNsPtr cur; 00096 00097 if ((node == NULL) || (ns == NULL)) 00098 return(-1); 00099 00100 if ((node->type != XML_ELEMENT_NODE) && 00101 (node->type != XML_ATTRIBUTE_NODE) && 00102 (node->type != XML_DOCUMENT_NODE) && 00103 (node->type != XML_TEXT_NODE) && 00104 (node->type != XML_HTML_DOCUMENT_NODE) && 00105 (node->type != XML_XINCLUDE_START)) 00106 return(-2); 00107 00108 while ((node != NULL) && 00109 ((node->type == XML_ELEMENT_NODE) || 00110 (node->type == XML_ATTRIBUTE_NODE) || 00111 (node->type == XML_TEXT_NODE) || 00112 (node->type == XML_XINCLUDE_START))) { 00113 if ((node->type == XML_ELEMENT_NODE) || 00114 (node->type == XML_XINCLUDE_START)) { 00115 cur = node->nsDef; 00116 while (cur != NULL) { 00117 if (cur == ns) 00118 return(1); 00119 if (xmlStrEqual(cur->prefix, ns->prefix)) 00120 return(-2); 00121 cur = cur->next; 00122 } 00123 } 00124 node = node->parent; 00125 } 00126 /* the xml namespace may be declared on the document node */ 00127 if ((node != NULL) && 00128 ((node->type == XML_DOCUMENT_NODE) || 00129 (node->type == XML_HTML_DOCUMENT_NODE))) { 00130 xmlNsPtr oldNs = ((xmlDocPtr) node)->oldNs; 00131 if (oldNs == ns) 00132 return(1); 00133 } 00134 return(-3); 00135 } 00136 00137 static void 00138 xmlCtxtDumpSpaces(xmlDebugCtxtPtr ctxt) 00139 { 00140 if (ctxt->check) 00141 return; 00142 if ((ctxt->output != NULL) && (ctxt->depth > 0)) { 00143 if (ctxt->depth < 50) 00144 fprintf(ctxt->output, "%s", &ctxt->shift[100 - 2 * ctxt->depth]); 00145 else 00146 fprintf(ctxt->output, "%s", ctxt->shift); 00147 } 00148 } 00149 00157 static void 00158 xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg) 00159 { 00160 ctxt->errors++; 00161 __xmlRaiseError(NULL, NULL, NULL, 00162 NULL, ctxt->node, XML_FROM_CHECK, 00163 error, XML_ERR_ERROR, NULL, 0, 00164 NULL, NULL, NULL, 0, 0, 00165 "%s", msg); 00166 } 00167 static void 00168 xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra) 00169 { 00170 ctxt->errors++; 00171 __xmlRaiseError(NULL, NULL, NULL, 00172 NULL, ctxt->node, XML_FROM_CHECK, 00173 error, XML_ERR_ERROR, NULL, 0, 00174 NULL, NULL, NULL, 0, 0, 00175 msg, extra); 00176 } 00177 static void 00178 xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra) 00179 { 00180 ctxt->errors++; 00181 __xmlRaiseError(NULL, NULL, NULL, 00182 NULL, ctxt->node, XML_FROM_CHECK, 00183 error, XML_ERR_ERROR, NULL, 0, 00184 NULL, NULL, NULL, 0, 0, 00185 msg, extra); 00186 } 00187 00196 static void 00197 xmlCtxtNsCheckScope(xmlDebugCtxtPtr ctxt, xmlNodePtr node, xmlNsPtr ns) 00198 { 00199 int ret; 00200 00201 ret = xmlNsCheckScope(node, ns); 00202 if (ret == -2) { 00203 if (ns->prefix == NULL) 00204 xmlDebugErr(ctxt, XML_CHECK_NS_SCOPE, 00205 "Reference to default namespace not in scope\n"); 00206 else 00207 xmlDebugErr3(ctxt, XML_CHECK_NS_SCOPE, 00208 "Reference to namespace '%s' not in scope\n", 00209 (char *) ns->prefix); 00210 } 00211 if (ret == -3) { 00212 if (ns->prefix == NULL) 00213 xmlDebugErr(ctxt, XML_CHECK_NS_ANCESTOR, 00214 "Reference to default namespace not on ancestor\n"); 00215 else 00216 xmlDebugErr3(ctxt, XML_CHECK_NS_ANCESTOR, 00217 "Reference to namespace '%s' not on ancestor\n", 00218 (char *) ns->prefix); 00219 } 00220 } 00221 00229 static void 00230 xmlCtxtCheckString(xmlDebugCtxtPtr ctxt, const xmlChar * str) 00231 { 00232 if (str == NULL) return; 00233 if (ctxt->check) { 00234 if (!xmlCheckUTF8(str)) { 00235 xmlDebugErr3(ctxt, XML_CHECK_NOT_UTF8, 00236 "String is not UTF-8 %s", (const char *) str); 00237 } 00238 } 00239 } 00240 00249 static void 00250 xmlCtxtCheckName(xmlDebugCtxtPtr ctxt, const xmlChar * name) 00251 { 00252 if (ctxt->check) { 00253 if (name == NULL) { 00254 xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL"); 00255 return; 00256 } 00257 if (xmlValidateName(name, 0)) { 00258 xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME, 00259 "Name is not an NCName '%s'", (const char *) name); 00260 } 00261 if ((ctxt->dict != NULL) && 00262 (!xmlDictOwns(ctxt->dict, name)) && 00263 ((ctxt->doc == NULL) || 00264 ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) { 00265 xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT, 00266 "Name is not from the document dictionnary '%s'", 00267 (const char *) name); 00268 } 00269 } 00270 } 00271 00272 static void 00273 xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) { 00274 xmlDocPtr doc; 00275 xmlDictPtr dict; 00276 00277 doc = node->doc; 00278 00279 if (node->parent == NULL) 00280 xmlDebugErr(ctxt, XML_CHECK_NO_PARENT, 00281 "Node has no parent\n"); 00282 if (node->doc == NULL) { 00283 xmlDebugErr(ctxt, XML_CHECK_NO_DOC, 00284 "Node has no doc\n"); 00285 dict = NULL; 00286 } else { 00287 dict = doc->dict; 00288 if ((dict == NULL) && (ctxt->nodict == 0)) { 00289 #if 0 00290 /* desactivated right now as it raises too many errors */ 00291 if (doc->type == XML_DOCUMENT_NODE) 00292 xmlDebugErr(ctxt, XML_CHECK_NO_DICT, 00293 "Document has no dictionnary\n"); 00294 #endif 00295 ctxt->nodict = 1; 00296 } 00297 if (ctxt->doc == NULL) 00298 ctxt->doc = doc; 00299 00300 if (ctxt->dict == NULL) { 00301 ctxt->dict = dict; 00302 } 00303 } 00304 if ((node->parent != NULL) && (node->doc != node->parent->doc) && 00305 (!xmlStrEqual(node->name, BAD_CAST "pseudoroot"))) 00306 xmlDebugErr(ctxt, XML_CHECK_WRONG_DOC, 00307 "Node doc differs from parent's one\n"); 00308 if (node->prev == NULL) { 00309 if (node->type == XML_ATTRIBUTE_NODE) { 00310 if ((node->parent != NULL) && 00311 (node != (xmlNodePtr) node->parent->properties)) 00312 xmlDebugErr(ctxt, XML_CHECK_NO_PREV, 00313 "Attr has no prev and not first of attr list\n"); 00314 00315 } else if ((node->parent != NULL) && (node->parent->children != node)) 00316 xmlDebugErr(ctxt, XML_CHECK_NO_PREV, 00317 "Node has no prev and not first of parent list\n"); 00318 } else { 00319 if (node->prev->next != node) 00320 xmlDebugErr(ctxt, XML_CHECK_WRONG_PREV, 00321 "Node prev->next : back link wrong\n"); 00322 } 00323 if (node->next == NULL) { 00324 if ((node->parent != NULL) && (node->type != XML_ATTRIBUTE_NODE) && 00325 (node->parent->last != node) && 00326 (node->parent->type == XML_ELEMENT_NODE)) 00327 xmlDebugErr(ctxt, XML_CHECK_NO_NEXT, 00328 "Node has no next and not last of parent list\n"); 00329 } else { 00330 if (node->next->prev != node) 00331 xmlDebugErr(ctxt, XML_CHECK_WRONG_NEXT, 00332 "Node next->prev : forward link wrong\n"); 00333 if (node->next->parent != node->parent) 00334 xmlDebugErr(ctxt, XML_CHECK_WRONG_PARENT, 00335 "Node next->prev : forward link wrong\n"); 00336 } 00337 if (node->type == XML_ELEMENT_NODE) { 00338 xmlNsPtr ns; 00339 00340 ns = node->nsDef; 00341 while (ns != NULL) { 00342 xmlCtxtNsCheckScope(ctxt, node, ns); 00343 ns = ns->next; 00344 } 00345 if (node->ns != NULL) 00346 xmlCtxtNsCheckScope(ctxt, node, node->ns); 00347 } else if (node->type == XML_ATTRIBUTE_NODE) { 00348 if (node->ns != NULL) 00349 xmlCtxtNsCheckScope(ctxt, node, node->ns); 00350 } 00351 00352 if ((node->type != XML_ELEMENT_NODE) && 00353 (node->type != XML_ATTRIBUTE_NODE) && 00354 (node->type != XML_ELEMENT_DECL) && 00355 (node->type != XML_ATTRIBUTE_DECL) && 00356 (node->type != XML_DTD_NODE) && 00357 (node->type != XML_ELEMENT_DECL) && 00358 (node->type != XML_HTML_DOCUMENT_NODE) && 00359 (node->type != XML_DOCUMENT_NODE)) { 00360 if (node->content != NULL) 00361 xmlCtxtCheckString(ctxt, (const xmlChar *) node->content); 00362 } 00363 switch (node->type) { 00364 case XML_ELEMENT_NODE: 00365 case XML_ATTRIBUTE_NODE: 00366 xmlCtxtCheckName(ctxt, node->name); 00367 break; 00368 case XML_TEXT_NODE: 00369 if ((node->name == xmlStringText) || 00370 (node->name == xmlStringTextNoenc)) 00371 break; 00372 /* some case of entity substitution can lead to this */ 00373 if ((ctxt->dict != NULL) && 00374 (node->name == xmlDictLookup(ctxt->dict, BAD_CAST "nbktext", 00375 7))) 00376 break; 00377 00378 xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME, 00379 "Text node has wrong name '%s'", 00380 (const char *) node->name); 00381 break; 00382 case XML_COMMENT_NODE: 00383 if (node->name == xmlStringComment) 00384 break; 00385 xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME, 00386 "Comment node has wrong name '%s'", 00387 (const char *) node->name); 00388 break; 00389 case XML_PI_NODE: 00390 xmlCtxtCheckName(ctxt, node->name); 00391 break; 00392 case XML_CDATA_SECTION_NODE: 00393 if (node->name == NULL) 00394 break; 00395 xmlDebugErr3(ctxt, XML_CHECK_NAME_NOT_NULL, 00396 "CData section has non NULL name '%s'", 00397 (const char *) node->name); 00398 break; 00399 case XML_ENTITY_REF_NODE: 00400 case XML_ENTITY_NODE: 00401 case XML_DOCUMENT_TYPE_NODE: 00402 case XML_DOCUMENT_FRAG_NODE: 00403 case XML_NOTATION_NODE: 00404 case XML_DTD_NODE: 00405 case XML_ELEMENT_DECL: 00406 case XML_ATTRIBUTE_DECL: 00407 case XML_ENTITY_DECL: 00408 case XML_NAMESPACE_DECL: 00409 case XML_XINCLUDE_START: 00410 case XML_XINCLUDE_END: 00411 #ifdef LIBXML_DOCB_ENABLED 00412 case XML_DOCB_DOCUMENT_NODE: 00413 #endif 00414 case XML_DOCUMENT_NODE: 00415 case XML_HTML_DOCUMENT_NODE: 00416 break; 00417 } 00418 } 00419 00420 static void 00421 xmlCtxtDumpString(xmlDebugCtxtPtr ctxt, const xmlChar * str) 00422 { 00423 int i; 00424 00425 if (ctxt->check) { 00426 return; 00427 } 00428 /* TODO: check UTF8 content of the string */ 00429 if (str == NULL) { 00430 fprintf(ctxt->output, "(NULL)"); 00431 return; 00432 } 00433 for (i = 0; i < 40; i++) 00434 if (str[i] == 0) 00435 return; 00436 else if (IS_BLANK_CH(str[i])) 00437 fputc(' ', ctxt->output); 00438 else if (str[i] >= 0x80) 00439 fprintf(ctxt->output, "#%X", str[i]); 00440 else 00441 fputc(str[i], ctxt->output); 00442 fprintf(ctxt->output, "..."); 00443 } 00444 00445 static void 00446 xmlCtxtDumpDtdNode(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd) 00447 { 00448 xmlCtxtDumpSpaces(ctxt); 00449 00450 if (dtd == NULL) { 00451 if (!ctxt->check) 00452 fprintf(ctxt->output, "DTD node is NULL\n"); 00453 return; 00454 } 00455 00456 if (dtd->type != XML_DTD_NODE) { 00457 xmlDebugErr(ctxt, XML_CHECK_NOT_DTD, 00458 "Node is not a DTD"); 00459 return; 00460 } 00461 if (!ctxt->check) { 00462 if (dtd->name != NULL) 00463 fprintf(ctxt->output, "DTD(%s)", (char *) dtd->name); 00464 else 00465 fprintf(ctxt->output, "DTD"); 00466 if (dtd->ExternalID != NULL) 00467 fprintf(ctxt->output, ", PUBLIC %s", (char *) dtd->ExternalID); 00468 if (dtd->SystemID != NULL) 00469 fprintf(ctxt->output, ", SYSTEM %s", (char *) dtd->SystemID); 00470 fprintf(ctxt->output, "\n"); 00471 } 00472 /* 00473 * Do a bit of checking 00474 */ 00475 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) dtd); 00476 } 00477 00478 static void 00479 xmlCtxtDumpAttrDecl(xmlDebugCtxtPtr ctxt, xmlAttributePtr attr) 00480 { 00481 xmlCtxtDumpSpaces(ctxt); 00482 00483 if (attr == NULL) { 00484 if (!ctxt->check) 00485 fprintf(ctxt->output, "Attribute declaration is NULL\n"); 00486 return; 00487 } 00488 if (attr->type != XML_ATTRIBUTE_DECL) { 00489 xmlDebugErr(ctxt, XML_CHECK_NOT_ATTR_DECL, 00490 "Node is not an attribute declaration"); 00491 return; 00492 } 00493 if (attr->name != NULL) { 00494 if (!ctxt->check) 00495 fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name); 00496 } else 00497 xmlDebugErr(ctxt, XML_CHECK_NO_NAME, 00498 "Node attribute declaration has no name"); 00499 if (attr->elem != NULL) { 00500 if (!ctxt->check) 00501 fprintf(ctxt->output, " for %s", (char *) attr->elem); 00502 } else 00503 xmlDebugErr(ctxt, XML_CHECK_NO_ELEM, 00504 "Node attribute declaration has no element name"); 00505 if (!ctxt->check) { 00506 switch (attr->atype) { 00507 case XML_ATTRIBUTE_CDATA: 00508 fprintf(ctxt->output, " CDATA"); 00509 break; 00510 case XML_ATTRIBUTE_ID: 00511 fprintf(ctxt->output, " ID"); 00512 break; 00513 case XML_ATTRIBUTE_IDREF: 00514 fprintf(ctxt->output, " IDREF"); 00515 break; 00516 case XML_ATTRIBUTE_IDREFS: 00517 fprintf(ctxt->output, " IDREFS"); 00518 break; 00519 case XML_ATTRIBUTE_ENTITY: 00520 fprintf(ctxt->output, " ENTITY"); 00521 break; 00522 case XML_ATTRIBUTE_ENTITIES: 00523 fprintf(ctxt->output, " ENTITIES"); 00524 break; 00525 case XML_ATTRIBUTE_NMTOKEN: 00526 fprintf(ctxt->output, " NMTOKEN"); 00527 break; 00528 case XML_ATTRIBUTE_NMTOKENS: 00529 fprintf(ctxt->output, " NMTOKENS"); 00530 break; 00531 case XML_ATTRIBUTE_ENUMERATION: 00532 fprintf(ctxt->output, " ENUMERATION"); 00533 break; 00534 case XML_ATTRIBUTE_NOTATION: 00535 fprintf(ctxt->output, " NOTATION "); 00536 break; 00537 } 00538 if (attr->tree != NULL) { 00539 int indx; 00540 xmlEnumerationPtr cur = attr->tree; 00541 00542 for (indx = 0; indx < 5; indx++) { 00543 if (indx != 0) 00544 fprintf(ctxt->output, "|%s", (char *) cur->name); 00545 else 00546 fprintf(ctxt->output, " (%s", (char *) cur->name); 00547 cur = cur->next; 00548 if (cur == NULL) 00549 break; 00550 } 00551 if (cur == NULL) 00552 fprintf(ctxt->output, ")"); 00553 else 00554 fprintf(ctxt->output, "...)"); 00555 } 00556 switch (attr->def) { 00557 case XML_ATTRIBUTE_NONE: 00558 break; 00559 case XML_ATTRIBUTE_REQUIRED: 00560 fprintf(ctxt->output, " REQUIRED"); 00561 break; 00562 case XML_ATTRIBUTE_IMPLIED: 00563 fprintf(ctxt->output, " IMPLIED"); 00564 break; 00565 case XML_ATTRIBUTE_FIXED: 00566 fprintf(ctxt->output, " FIXED"); 00567 break; 00568 } 00569 if (attr->defaultValue != NULL) { 00570 fprintf(ctxt->output, "\""); 00571 xmlCtxtDumpString(ctxt, attr->defaultValue); 00572 fprintf(ctxt->output, "\""); 00573 } 00574 fprintf(ctxt->output, "\n"); 00575 } 00576 00577 /* 00578 * Do a bit of checking 00579 */ 00580 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr); 00581 } 00582 00583 static void 00584 xmlCtxtDumpElemDecl(xmlDebugCtxtPtr ctxt, xmlElementPtr elem) 00585 { 00586 xmlCtxtDumpSpaces(ctxt); 00587 00588 if (elem == NULL) { 00589 if (!ctxt->check) 00590 fprintf(ctxt->output, "Element declaration is NULL\n"); 00591 return; 00592 } 00593 if (elem->type != XML_ELEMENT_DECL) { 00594 xmlDebugErr(ctxt, XML_CHECK_NOT_ELEM_DECL, 00595 "Node is not an element declaration"); 00596 return; 00597 } 00598 if (elem->name != NULL) { 00599 if (!ctxt->check) { 00600 fprintf(ctxt->output, "ELEMDECL("); 00601 xmlCtxtDumpString(ctxt, elem->name); 00602 fprintf(ctxt->output, ")"); 00603 } 00604 } else 00605 xmlDebugErr(ctxt, XML_CHECK_NO_NAME, 00606 "Element declaration has no name"); 00607 if (!ctxt->check) { 00608 switch (elem->etype) { 00609 case XML_ELEMENT_TYPE_UNDEFINED: 00610 fprintf(ctxt->output, ", UNDEFINED"); 00611 break; 00612 case XML_ELEMENT_TYPE_EMPTY: 00613 fprintf(ctxt->output, ", EMPTY"); 00614 break; 00615 case XML_ELEMENT_TYPE_ANY: 00616 fprintf(ctxt->output, ", ANY"); 00617 break; 00618 case XML_ELEMENT_TYPE_MIXED: 00619 fprintf(ctxt->output, ", MIXED "); 00620 break; 00621 case XML_ELEMENT_TYPE_ELEMENT: 00622 fprintf(ctxt->output, ", MIXED "); 00623 break; 00624 } 00625 if ((elem->type != XML_ELEMENT_NODE) && (elem->content != NULL)) { 00626 char buf[5001]; 00627 00628 buf[0] = 0; 00629 xmlSnprintfElementContent(buf, 5000, elem->content, 1); 00630 buf[5000] = 0; 00631 fprintf(ctxt->output, "%s", buf); 00632 } 00633 fprintf(ctxt->output, "\n"); 00634 } 00635 00636 /* 00637 * Do a bit of checking 00638 */ 00639 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) elem); 00640 } 00641 00642 static void 00643 xmlCtxtDumpEntityDecl(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent) 00644 { 00645 xmlCtxtDumpSpaces(ctxt); 00646 00647 if (ent == NULL) { 00648 if (!ctxt->check) 00649 fprintf(ctxt->output, "Entity declaration is NULL\n"); 00650 return; 00651 } 00652 if (ent->type != XML_ENTITY_DECL) { 00653 xmlDebugErr(ctxt, XML_CHECK_NOT_ENTITY_DECL, 00654 "Node is not an entity declaration"); 00655 return; 00656 } 00657 if (ent->name != NULL) { 00658 if (!ctxt->check) { 00659 fprintf(ctxt->output, "ENTITYDECL("); 00660 xmlCtxtDumpString(ctxt, ent->name); 00661 fprintf(ctxt->output, ")"); 00662 } 00663 } else 00664 xmlDebugErr(ctxt, XML_CHECK_NO_NAME, 00665 "Entity declaration has no name"); 00666 if (!ctxt->check) { 00667 switch (ent->etype) { 00668 case XML_INTERNAL_GENERAL_ENTITY: 00669 fprintf(ctxt->output, ", internal\n"); 00670 break; 00671 case XML_EXTERNAL_GENERAL_PARSED_ENTITY: 00672 fprintf(ctxt->output, ", external parsed\n"); 00673 break; 00674 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: 00675 fprintf(ctxt->output, ", unparsed\n"); 00676 break; 00677 case XML_INTERNAL_PARAMETER_ENTITY: 00678 fprintf(ctxt->output, ", parameter\n"); 00679 break; 00680 case XML_EXTERNAL_PARAMETER_ENTITY: 00681 fprintf(ctxt->output, ", external parameter\n"); 00682 break; 00683 case XML_INTERNAL_PREDEFINED_ENTITY: 00684 fprintf(ctxt->output, ", predefined\n"); 00685 break; 00686 } 00687 if (ent->ExternalID) { 00688 xmlCtxtDumpSpaces(ctxt); 00689 fprintf(ctxt->output, " ExternalID=%s\n", 00690 (char *) ent->ExternalID); 00691 } 00692 if (ent->SystemID) { 00693 xmlCtxtDumpSpaces(ctxt); 00694 fprintf(ctxt->output, " SystemID=%s\n", 00695 (char *) ent->SystemID); 00696 } 00697 if (ent->URI != NULL) { 00698 xmlCtxtDumpSpaces(ctxt); 00699 fprintf(ctxt->output, " URI=%s\n", (char *) ent->URI); 00700 } 00701 if (ent->content) { 00702 xmlCtxtDumpSpaces(ctxt); 00703 fprintf(ctxt->output, " content="); 00704 xmlCtxtDumpString(ctxt, ent->content); 00705 fprintf(ctxt->output, "\n"); 00706 } 00707 } 00708 00709 /* 00710 * Do a bit of checking 00711 */ 00712 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) ent); 00713 } 00714 00715 static void 00716 xmlCtxtDumpNamespace(xmlDebugCtxtPtr ctxt, xmlNsPtr ns) 00717 { 00718 xmlCtxtDumpSpaces(ctxt); 00719 00720 if (ns == NULL) { 00721 if (!ctxt->check) 00722 fprintf(ctxt->output, "namespace node is NULL\n"); 00723 return; 00724 } 00725 if (ns->type != XML_NAMESPACE_DECL) { 00726 xmlDebugErr(ctxt, XML_CHECK_NOT_NS_DECL, 00727 "Node is not a namespace declaration"); 00728 return; 00729 } 00730 if (ns->href == NULL) { 00731 if (ns->prefix != NULL) 00732 xmlDebugErr3(ctxt, XML_CHECK_NO_HREF, 00733 "Incomplete namespace %s href=NULL\n", 00734 (char *) ns->prefix); 00735 else 00736 xmlDebugErr(ctxt, XML_CHECK_NO_HREF, 00737 "Incomplete default namespace href=NULL\n"); 00738 } else { 00739 if (!ctxt->check) { 00740 if (ns->prefix != NULL) 00741 fprintf(ctxt->output, "namespace %s href=", 00742 (char *) ns->prefix); 00743 else 00744 fprintf(ctxt->output, "default namespace href="); 00745 00746 xmlCtxtDumpString(ctxt, ns->href); 00747 fprintf(ctxt->output, "\n"); 00748 } 00749 } 00750 } 00751 00752 static void 00753 xmlCtxtDumpNamespaceList(xmlDebugCtxtPtr ctxt, xmlNsPtr ns) 00754 { 00755 while (ns != NULL) { 00756 xmlCtxtDumpNamespace(ctxt, ns); 00757 ns = ns->next; 00758 } 00759 } 00760 00761 static void 00762 xmlCtxtDumpEntity(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent) 00763 { 00764 xmlCtxtDumpSpaces(ctxt); 00765 00766 if (ent == NULL) { 00767 if (!ctxt->check) 00768 fprintf(ctxt->output, "Entity is NULL\n"); 00769 return; 00770 } 00771 if (!ctxt->check) { 00772 switch (ent->etype) { 00773 case XML_INTERNAL_GENERAL_ENTITY: 00774 fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY "); 00775 break; 00776 case XML_EXTERNAL_GENERAL_PARSED_ENTITY: 00777 fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY "); 00778 break; 00779 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: 00780 fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY "); 00781 break; 00782 case XML_INTERNAL_PARAMETER_ENTITY: 00783 fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY "); 00784 break; 00785 case XML_EXTERNAL_PARAMETER_ENTITY: 00786 fprintf(ctxt->output, "EXTERNAL_PARAMETER_ENTITY "); 00787 break; 00788 default: 00789 fprintf(ctxt->output, "ENTITY_%d ! ", (int) ent->etype); 00790 } 00791 fprintf(ctxt->output, "%s\n", ent->name); 00792 if (ent->ExternalID) { 00793 xmlCtxtDumpSpaces(ctxt); 00794 fprintf(ctxt->output, "ExternalID=%s\n", 00795 (char *) ent->ExternalID); 00796 } 00797 if (ent->SystemID) { 00798 xmlCtxtDumpSpaces(ctxt); 00799 fprintf(ctxt->output, "SystemID=%s\n", (char *) ent->SystemID); 00800 } 00801 if (ent->URI) { 00802 xmlCtxtDumpSpaces(ctxt); 00803 fprintf(ctxt->output, "URI=%s\n", (char *) ent->URI); 00804 } 00805 if (ent->content) { 00806 xmlCtxtDumpSpaces(ctxt); 00807 fprintf(ctxt->output, "content="); 00808 xmlCtxtDumpString(ctxt, ent->content); 00809 fprintf(ctxt->output, "\n"); 00810 } 00811 } 00812 } 00813 00822 static void 00823 xmlCtxtDumpAttr(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr) 00824 { 00825 xmlCtxtDumpSpaces(ctxt); 00826 00827 if (attr == NULL) { 00828 if (!ctxt->check) 00829 fprintf(ctxt->output, "Attr is NULL"); 00830 return; 00831 } 00832 if (!ctxt->check) { 00833 fprintf(ctxt->output, "ATTRIBUTE "); 00834 xmlCtxtDumpString(ctxt, attr->name); 00835 fprintf(ctxt->output, "\n"); 00836 if (attr->children != NULL) { 00837 ctxt->depth++; 00838 xmlCtxtDumpNodeList(ctxt, attr->children); 00839 ctxt->depth--; 00840 } 00841 } 00842 if (attr->name == NULL) 00843 xmlDebugErr(ctxt, XML_CHECK_NO_NAME, 00844 "Attribute has no name"); 00845 00846 /* 00847 * Do a bit of checking 00848 */ 00849 xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr); 00850 } 00851 00860 static void 00861 xmlCtxtDumpAttrList(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr) 00862 { 00863 while (attr != NULL) { 00864 xmlCtxtDumpAttr(ctxt, attr); 00865 attr = attr->next; 00866 } 00867 } 00868 00877 static void 00878 xmlCtxtDumpOneNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node) 00879 { 00880 if (node == NULL) { 00881 if (!ctxt->check) { 00882 xmlCtxtDumpSpaces(ctxt); 00883 fprintf(ctxt->output, "node is NULL\n"); 00884 } 00885 return; 00886 } 00887 ctxt->node = node; 00888 00889 switch (node->type) { 00890 case XML_ELEMENT_NODE: 00891 if (!ctxt->check) { 00892 xmlCtxtDumpSpaces(ctxt); 00893 fprintf(ctxt->output, "ELEMENT "); 00894 if ((node->ns != NULL) && (node->ns->prefix != NULL)) { 00895 xmlCtxtDumpString(ctxt, node->ns->prefix); 00896 fprintf(ctxt->output, ":"); 00897 } 00898 xmlCtxtDumpString(ctxt, node->name); 00899 fprintf(ctxt->output, "\n"); 00900 } 00901 break; 00902 case XML_ATTRIBUTE_NODE: 00903 if (!ctxt->check) 00904 xmlCtxtDumpSpaces(ctxt); 00905 fprintf(ctxt->output, "Error, ATTRIBUTE found here\n"); 00906 xmlCtxtGenericNodeCheck(ctxt, node); 00907 return; 00908 case XML_TEXT_NODE: 00909 if (!ctxt->check) { 00910 xmlCtxtDumpSpaces(ctxt); 00911 if (node->name == (const xmlChar *) xmlStringTextNoenc) 00912 fprintf(ctxt->output, "TEXT no enc"); 00913 else 00914 fprintf(ctxt->output, "TEXT"); 00915 if (ctxt->options & DUMP_TEXT_TYPE) { 00916 if (node->content == (xmlChar *) &(node->properties)) 00917 fprintf(ctxt->output, " compact\n"); 00918 else if (xmlDictOwns(ctxt->dict, node->content) == 1) 00919 fprintf(ctxt->output, " interned\n"); 00920 else 00921 fprintf(ctxt->output, "\n"); 00922 } else 00923 fprintf(ctxt->output, "\n"); 00924 } 00925 break; 00926 case XML_CDATA_SECTION_NODE: 00927 if (!ctxt->check) { 00928 xmlCtxtDumpSpaces(ctxt); 00929 fprintf(ctxt->output, "CDATA_SECTION\n"); 00930 } 00931 break; 00932 case XML_ENTITY_REF_NODE: 00933 if (!ctxt->check) { 00934 xmlCtxtDumpSpaces(ctxt); 00935 fprintf(ctxt->output, "ENTITY_REF(%s)\n", 00936 (char *) node->name); 00937 } 00938 break; 00939 case XML_ENTITY_NODE: 00940 if (!ctxt->check) { 00941 xmlCtxtDumpSpaces(ctxt); 00942 fprintf(ctxt->output, "ENTITY\n"); 00943 } 00944 break; 00945 case XML_PI_NODE: 00946 if (!ctxt->check) { 00947 xmlCtxtDumpSpaces(ctxt); 00948 fprintf(ctxt->output, "PI %s\n", (char *) node->name); 00949 } 00950 break; 00951 case XML_COMMENT_NODE: 00952 if (!ctxt->check) { 00953 xmlCtxtDumpSpaces(ctxt); 00954 fprintf(ctxt->output, "COMMENT\n"); 00955 } 00956 break; 00957 case XML_DOCUMENT_NODE: 00958 case XML_HTML_DOCUMENT_NODE: 00959 if (!ctxt->check) { 00960 xmlCtxtDumpSpaces(ctxt); 00961 } 00962 fprintf(ctxt->output, "Error, DOCUMENT found here\n"); 00963 xmlCtxtGenericNodeCheck(ctxt, node); 00964 return; 00965 case XML_DOCUMENT_TYPE_NODE: 00966 if (!ctxt->check) { 00967 xmlCtxtDumpSpaces(ctxt); 00968 fprintf(ctxt->output, "DOCUMENT_TYPE\n"); 00969 } 00970 break; 00971 case XML_DOCUMENT_FRAG_NODE: 00972 if (!ctxt->check) { 00973 xmlCtxtDumpSpaces(ctxt); 00974 fprintf(ctxt->output, "DOCUMENT_FRAG\n"); 00975 } 00976 break; 00977 case XML_NOTATION_NODE: 00978 if (!ctxt->check) { 00979 xmlCtxtDumpSpaces(ctxt); 00980 fprintf(ctxt->output, "NOTATION\n"); 00981 } 00982 break; 00983 case XML_DTD_NODE: 00984 xmlCtxtDumpDtdNode(ctxt, (xmlDtdPtr) node); 00985 return; 00986 case XML_ELEMENT_DECL: 00987 xmlCtxtDumpElemDecl(ctxt, (xmlElementPtr) node); 00988 return; 00989 case XML_ATTRIBUTE_DECL: 00990 xmlCtxtDumpAttrDecl(ctxt, (xmlAttributePtr) node); 00991 return; 00992 case XML_ENTITY_DECL: 00993 xmlCtxtDumpEntityDecl(ctxt, (xmlEntityPtr) node); 00994 return; 00995 case XML_NAMESPACE_DECL: 00996 xmlCtxtDumpNamespace(ctxt, (xmlNsPtr) node); 00997 return; 00998 case XML_XINCLUDE_START: 00999 if (!ctxt->check) { 01000 xmlCtxtDumpSpaces(ctxt); 01001 fprintf(ctxt->output, "INCLUDE START\n"); 01002 } 01003 return; 01004 case XML_XINCLUDE_END: 01005 if (!ctxt->check) { 01006 xmlCtxtDumpSpaces(ctxt); 01007 fprintf(ctxt->output, "INCLUDE END\n"); 01008 } 01009 return; 01010 default: 01011 if (!ctxt->check) 01012 xmlCtxtDumpSpaces(ctxt); 01013 xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE, 01014 "Unknown node type %d\n", node->type); 01015 return; 01016 } 01017 if (node->doc == NULL) { 01018 if (!ctxt->check) { 01019 xmlCtxtDumpSpaces(ctxt); 01020 } 01021 fprintf(ctxt->output, "PBM: doc == NULL !!!\n"); 01022 } 01023 ctxt->depth++; 01024 if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL)) 01025 xmlCtxtDumpNamespaceList(ctxt, node->nsDef); 01026 if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL)) 01027 xmlCtxtDumpAttrList(ctxt, node->properties); 01028 if (node->type != XML_ENTITY_REF_NODE) { 01029 if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) { 01030 if (!ctxt->check) { 01031 xmlCtxtDumpSpaces(ctxt); 01032 fprintf(ctxt->output, "content="); 01033 xmlCtxtDumpString(ctxt, node->content); 01034 fprintf(ctxt->output, "\n"); 01035 } 01036 } 01037 } else { 01038 xmlEntityPtr ent; 01039 01040 ent = xmlGetDocEntity(node->doc, node->name); 01041 if (ent != NULL) 01042 xmlCtxtDumpEntity(ctxt, ent); 01043 } 01044 ctxt->depth--; 01045 01046 /* 01047 * Do a bit of checking 01048 */ 01049 xmlCtxtGenericNodeCheck(ctxt, node); 01050 } 01051 01060 static void 01061 xmlCtxtDumpNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node) 01062 { 01063 if (node == NULL) { 01064 if (!ctxt->check) { 01065 xmlCtxtDumpSpaces(ctxt); 01066 fprintf(ctxt->output, "node is NULL\n"); 01067 } 01068 return; 01069 } 01070 xmlCtxtDumpOneNode(ctxt, node); 01071 if ((node->type != XML_NAMESPACE_DECL) && 01072 (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) { 01073 ctxt->depth++; 01074 xmlCtxtDumpNodeList(ctxt, node->children); 01075 ctxt->depth--; 01076 } 01077 } 01078 01087 static void 01088 xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node) 01089 { 01090 while (node != NULL) { 01091 xmlCtxtDumpNode(ctxt, node); 01092 node = node->next; 01093 } 01094 } 01095 01096 static void 01097 xmlCtxtDumpDocHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) 01098 { 01099 if (doc == NULL) { 01100 if (!ctxt->check) 01101 fprintf(ctxt->output, "DOCUMENT == NULL !\n"); 01102 return; 01103 } 01104 ctxt->node = (xmlNodePtr) doc; 01105 01106 switch (doc->type) { 01107 case XML_ELEMENT_NODE: 01108 xmlDebugErr(ctxt, XML_CHECK_FOUND_ELEMENT, 01109 "Misplaced ELEMENT node\n"); 01110 break; 01111 case XML_ATTRIBUTE_NODE: 01112 xmlDebugErr(ctxt, XML_CHECK_FOUND_ATTRIBUTE, 01113 "Misplaced ATTRIBUTE node\n"); 01114 break; 01115 case XML_TEXT_NODE: 01116 xmlDebugErr(ctxt, XML_CHECK_FOUND_TEXT, 01117 "Misplaced TEXT node\n"); 01118 break; 01119 case XML_CDATA_SECTION_NODE: 01120 xmlDebugErr(ctxt, XML_CHECK_FOUND_CDATA, 01121 "Misplaced CDATA node\n"); 01122 break; 01123 case XML_ENTITY_REF_NODE: 01124 xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITYREF, 01125 "Misplaced ENTITYREF node\n"); 01126 break; 01127 case XML_ENTITY_NODE: 01128 xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITY, 01129 "Misplaced ENTITY node\n"); 01130 break; 01131 case XML_PI_NODE: 01132 xmlDebugErr(ctxt, XML_CHECK_FOUND_PI, 01133 "Misplaced PI node\n"); 01134 break; 01135 case XML_COMMENT_NODE: 01136 xmlDebugErr(ctxt, XML_CHECK_FOUND_COMMENT, 01137 "Misplaced COMMENT node\n"); 01138 break; 01139 case XML_DOCUMENT_NODE: 01140 if (!ctxt->check) 01141 fprintf(ctxt->output, "DOCUMENT\n"); 01142 break; 01143 case XML_HTML_DOCUMENT_NODE: 01144 if (!ctxt->check) 01145 fprintf(ctxt->output, "HTML DOCUMENT\n"); 01146 break; 01147 case XML_DOCUMENT_TYPE_NODE: 01148 xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE, 01149 "Misplaced DOCTYPE node\n"); 01150 break; 01151 case XML_DOCUMENT_FRAG_NODE: 01152 xmlDebugErr(ctxt, XML_CHECK_FOUND_FRAGMENT, 01153 "Misplaced FRAGMENT node\n"); 01154 break; 01155 case XML_NOTATION_NODE: 01156 xmlDebugErr(ctxt, XML_CHECK_FOUND_NOTATION, 01157 "Misplaced NOTATION node\n"); 01158 break; 01159 default: 01160 xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE, 01161 "Unknown node type %d\n", doc->type); 01162 } 01163 } 01164 01172 static void 01173 xmlCtxtDumpDocumentHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) 01174 { 01175 if (doc == NULL) return; 01176 xmlCtxtDumpDocHead(ctxt, doc); 01177 if (!ctxt->check) { 01178 if (doc->name != NULL) { 01179 fprintf(ctxt->output, "name="); 01180 xmlCtxtDumpString(ctxt, BAD_CAST doc->name); 01181 fprintf(ctxt->output, "\n"); 01182 } 01183 if (doc->version != NULL) { 01184 fprintf(ctxt->output, "version="); 01185 xmlCtxtDumpString(ctxt, doc->version); 01186 fprintf(ctxt->output, "\n"); 01187 } 01188 if (doc->encoding != NULL) { 01189 fprintf(ctxt->output, "encoding="); 01190 xmlCtxtDumpString(ctxt, doc->encoding); 01191 fprintf(ctxt->output, "\n"); 01192 } 01193 if (doc->URL != NULL) { 01194 fprintf(ctxt->output, "URL="); 01195 xmlCtxtDumpString(ctxt, doc->URL); 01196 fprintf(ctxt->output, "\n"); 01197 } 01198 if (doc->standalone) 01199 fprintf(ctxt->output, "standalone=true\n"); 01200 } 01201 if (doc->oldNs != NULL) 01202 xmlCtxtDumpNamespaceList(ctxt, doc->oldNs); 01203 } 01204 01212 static void 01213 xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) 01214 { 01215 if (doc == NULL) { 01216 if (!ctxt->check) 01217 fprintf(ctxt->output, "DOCUMENT == NULL !\n"); 01218 return; 01219 } 01220 xmlCtxtDumpDocumentHead(ctxt, doc); 01221 if (((doc->type == XML_DOCUMENT_NODE) || 01222 (doc->type == XML_HTML_DOCUMENT_NODE)) 01223 && (doc->children != NULL)) { 01224 ctxt->depth++; 01225 xmlCtxtDumpNodeList(ctxt, doc->children); 01226 ctxt->depth--; 01227 } 01228 } 01229 01230 static void 01231 xmlCtxtDumpEntityCallback(xmlEntityPtr cur, xmlDebugCtxtPtr ctxt) 01232 { 01233 if (cur == NULL) { 01234 if (!ctxt->check) 01235 fprintf(ctxt->output, "Entity is NULL"); 01236 return; 01237 } 01238 if (!ctxt->check) { 01239 fprintf(ctxt->output, "%s : ", (char *) cur->name); 01240 switch (cur->etype) { 01241 case XML_INTERNAL_GENERAL_ENTITY: 01242 fprintf(ctxt->output, "INTERNAL GENERAL, "); 01243 break; 01244 case XML_EXTERNAL_GENERAL_PARSED_ENTITY: 01245 fprintf(ctxt->output, "EXTERNAL PARSED, "); 01246 break; 01247 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: 01248 fprintf(ctxt->output, "EXTERNAL UNPARSED, "); 01249 break; 01250 case XML_INTERNAL_PARAMETER_ENTITY: 01251 fprintf(ctxt->output, "INTERNAL PARAMETER, "); 01252 break; 01253 case XML_EXTERNAL_PARAMETER_ENTITY: 01254 fprintf(ctxt->output, "EXTERNAL PARAMETER, "); 01255 break; 01256 default: 01257 xmlDebugErr2(ctxt, XML_CHECK_ENTITY_TYPE, 01258 "Unknown entity type %d\n", cur->etype); 01259 } 01260 if (cur->ExternalID != NULL) 01261 fprintf(ctxt->output, "ID \"%s\"", (char *) cur->ExternalID); 01262 if (cur->SystemID != NULL) 01263 fprintf(ctxt->output, "SYSTEM \"%s\"", (char *) cur->SystemID); 01264 if (cur->orig != NULL) 01265 fprintf(ctxt->output, "\n orig \"%s\"", (char *) cur->orig); 01266 if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) 01267 fprintf(ctxt->output, "\n content \"%s\"", 01268 (char *) cur->content); 01269 fprintf(ctxt->output, "\n"); 01270 } 01271 } 01272 01280 static void 01281 xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) 01282 { 01283 if (doc == NULL) return; 01284 xmlCtxtDumpDocHead(ctxt, doc); 01285 if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) { 01286 xmlEntitiesTablePtr table = (xmlEntitiesTablePtr) 01287 doc->intSubset->entities; 01288 01289 if (!ctxt->check) 01290 fprintf(ctxt->output, "Entities in internal subset\n"); 01291 xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback, 01292 ctxt); 01293 } else 01294 fprintf(ctxt->output, "No entities in internal subset\n"); 01295 if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { 01296 xmlEntitiesTablePtr table = (xmlEntitiesTablePtr) 01297 doc->extSubset->entities; 01298 01299 if (!ctxt->check) 01300 fprintf(ctxt->output, "Entities in external subset\n"); 01301 xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback, 01302 ctxt); 01303 } else if (!ctxt->check) 01304 fprintf(ctxt->output, "No entities in external subset\n"); 01305 } 01306 01314 static void 01315 xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd) 01316 { 01317 if (dtd == NULL) { 01318 if (!ctxt->check) 01319 fprintf(ctxt->output, "DTD is NULL\n"); 01320 return; 01321 } 01322 xmlCtxtDumpDtdNode(ctxt, dtd); 01323 if (dtd->children == NULL) 01324 fprintf(ctxt->output, " DTD is empty\n"); 01325 else { 01326 ctxt->depth++; 01327 xmlCtxtDumpNodeList(ctxt, dtd->children); 01328 ctxt->depth--; 01329 } 01330 } 01331 01332 /************************************************************************ 01333 * * 01334 * Public entry points for dump * 01335 * * 01336 ************************************************************************/ 01337 01345 void 01346 xmlDebugDumpString(FILE * output, const xmlChar * str) 01347 { 01348 int i; 01349 01350 if (output == NULL) 01351 output = stdout; 01352 if (str == NULL) { 01353 fprintf(output, "(NULL)"); 01354 return; 01355 } 01356 for (i = 0; i < 40; i++) 01357 if (str[i] == 0) 01358 return; 01359 else if (IS_BLANK_CH(str[i])) 01360 fputc(' ', output); 01361 else if (str[i] >= 0x80) 01362 fprintf(output, "#%X", str[i]); 01363 else 01364 fputc(str[i], output); 01365 fprintf(output, "..."); 01366 } 01367 01376 void 01377 xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) { 01378 xmlDebugCtxt ctxt; 01379 01380 if (output == NULL) return; 01381 xmlCtxtDumpInitCtxt(&ctxt); 01382 ctxt.output = output; 01383 ctxt.depth = depth; 01384 xmlCtxtDumpAttr(&ctxt, attr); 01385 xmlCtxtDumpCleanCtxt(&ctxt); 01386 } 01387 01388 01396 void 01397 xmlDebugDumpEntities(FILE * output, xmlDocPtr doc) 01398 { 01399 xmlDebugCtxt ctxt; 01400 01401 if (output == NULL) return; 01402 xmlCtxtDumpInitCtxt(&ctxt); 01403 ctxt.output = output; 01404 xmlCtxtDumpEntities(&ctxt, doc); 01405 xmlCtxtDumpCleanCtxt(&ctxt); 01406 } 01407 01416 void 01417 xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth) 01418 { 01419 xmlDebugCtxt ctxt; 01420 01421 if (output == NULL) return; 01422 xmlCtxtDumpInitCtxt(&ctxt); 01423 ctxt.output = output; 01424 ctxt.depth = depth; 01425 xmlCtxtDumpAttrList(&ctxt, attr); 01426 xmlCtxtDumpCleanCtxt(&ctxt); 01427 } 01428 01437 void 01438 xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth) 01439 { 01440 xmlDebugCtxt ctxt; 01441 01442 if (output == NULL) return; 01443 xmlCtxtDumpInitCtxt(&ctxt); 01444 ctxt.output = output; 01445 ctxt.depth = depth; 01446 xmlCtxtDumpOneNode(&ctxt, node); 01447 xmlCtxtDumpCleanCtxt(&ctxt); 01448 } 01449 01458 void 01459 xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth) 01460 { 01461 xmlDebugCtxt ctxt; 01462 01463 if (output == NULL) 01464 output = stdout; 01465 xmlCtxtDumpInitCtxt(&ctxt); 01466 ctxt.output = output; 01467 ctxt.depth = depth; 01468 xmlCtxtDumpNode(&ctxt, node); 01469 xmlCtxtDumpCleanCtxt(&ctxt); 01470 } 01471 01480 void 01481 xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth) 01482 { 01483 xmlDebugCtxt ctxt; 01484 01485 if (output == NULL) 01486 output = stdout; 01487 xmlCtxtDumpInitCtxt(&ctxt); 01488 ctxt.output = output; 01489 ctxt.depth = depth; 01490 xmlCtxtDumpNodeList(&ctxt, node); 01491 xmlCtxtDumpCleanCtxt(&ctxt); 01492 } 01493 01501 void 01502 xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc) 01503 { 01504 xmlDebugCtxt ctxt; 01505 01506 if (output == NULL) 01507 output = stdout; 01508 xmlCtxtDumpInitCtxt(&ctxt); 01509 ctxt.options |= DUMP_TEXT_TYPE; 01510 ctxt.output = output; 01511 xmlCtxtDumpDocumentHead(&ctxt, doc); 01512 xmlCtxtDumpCleanCtxt(&ctxt); 01513 } 01514 01522 void 01523 xmlDebugDumpDocument(FILE * output, xmlDocPtr doc) 01524 { 01525 xmlDebugCtxt ctxt; 01526 01527 if (output == NULL) 01528 output = stdout; 01529 xmlCtxtDumpInitCtxt(&ctxt); 01530 ctxt.options |= DUMP_TEXT_TYPE; 01531 ctxt.output = output; 01532 xmlCtxtDumpDocument(&ctxt, doc); 01533 xmlCtxtDumpCleanCtxt(&ctxt); 01534 } 01535 01543 void 01544 xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd) 01545 { 01546 xmlDebugCtxt ctxt; 01547 01548 if (output == NULL) 01549 output = stdout; 01550 xmlCtxtDumpInitCtxt(&ctxt); 01551 ctxt.options |= DUMP_TEXT_TYPE; 01552 ctxt.output = output; 01553 xmlCtxtDumpDTD(&ctxt, dtd); 01554 xmlCtxtDumpCleanCtxt(&ctxt); 01555 } 01556 01557 /************************************************************************ 01558 * * 01559 * Public entry points for checkings * 01560 * * 01561 ************************************************************************/ 01562 01573 int 01574 xmlDebugCheckDocument(FILE * output, xmlDocPtr doc) 01575 { 01576 xmlDebugCtxt ctxt; 01577 01578 if (output == NULL) 01579 output = stdout; 01580 xmlCtxtDumpInitCtxt(&ctxt); 01581 ctxt.output = output; 01582 ctxt.check = 1; 01583 xmlCtxtDumpDocument(&ctxt, doc); 01584 xmlCtxtDumpCleanCtxt(&ctxt); 01585 return(ctxt.errors); 01586 } 01587 01588 /************************************************************************ 01589 * * 01590 * Helpers for Shell * 01591 * * 01592 ************************************************************************/ 01593 01602 int 01603 xmlLsCountNode(xmlNodePtr node) { 01604 int ret = 0; 01605 xmlNodePtr list = NULL; 01606 01607 if (node == NULL) 01608 return(0); 01609 01610 switch (node->type) { 01611 case XML_ELEMENT_NODE: 01612 list = node->children; 01613 break; 01614 case XML_DOCUMENT_NODE: 01615 case XML_HTML_DOCUMENT_NODE: 01616 #ifdef LIBXML_DOCB_ENABLED 01617 case XML_DOCB_DOCUMENT_NODE: 01618 #endif 01619 list = ((xmlDocPtr) node)->children; 01620 break; 01621 case XML_ATTRIBUTE_NODE: 01622 list = ((xmlAttrPtr) node)->children; 01623 break; 01624 case XML_TEXT_NODE: 01625 case XML_CDATA_SECTION_NODE: 01626 case XML_PI_NODE: 01627 case XML_COMMENT_NODE: 01628 if (node->content != NULL) { 01629 ret = xmlStrlen(node->content); 01630 } 01631 break; 01632 case XML_ENTITY_REF_NODE: 01633 case XML_DOCUMENT_TYPE_NODE: 01634 case XML_ENTITY_NODE: 01635 case XML_DOCUMENT_FRAG_NODE: 01636 case XML_NOTATION_NODE: 01637 case XML_DTD_NODE: 01638 case XML_ELEMENT_DECL: 01639 case XML_ATTRIBUTE_DECL: 01640 case XML_ENTITY_DECL: 01641 case XML_NAMESPACE_DECL: 01642 case XML_XINCLUDE_START: 01643 case XML_XINCLUDE_END: 01644 ret = 1; 01645 break; 01646 } 01647 for (;list != NULL;ret++) 01648 list = list->next; 01649 return(ret); 01650 } 01651 01659 void 01660 xmlLsOneNode(FILE *output, xmlNodePtr node) { 01661 if (output == NULL) return; 01662 if (node == NULL) { 01663 fprintf(output, "NULL\n"); 01664 return; 01665 } 01666 switch (node->type) { 01667 case XML_ELEMENT_NODE: 01668 fprintf(output, "-"); 01669 break; 01670 case XML_ATTRIBUTE_NODE: 01671 fprintf(output, "a"); 01672 break; 01673 case XML_TEXT_NODE: 01674 fprintf(output, "t"); 01675 break; 01676 case XML_CDATA_SECTION_NODE: 01677 fprintf(output, "C"); 01678 break; 01679 case XML_ENTITY_REF_NODE: 01680 fprintf(output, "e"); 01681 break; 01682 case XML_ENTITY_NODE: 01683 fprintf(output, "E"); 01684 break; 01685 case XML_PI_NODE: 01686 fprintf(output, "p"); 01687 break; 01688 case XML_COMMENT_NODE: 01689 fprintf(output, "c"); 01690 break; 01691 case XML_DOCUMENT_NODE: 01692 fprintf(output, "d"); 01693 break; 01694 case XML_HTML_DOCUMENT_NODE: 01695 fprintf(output, "h"); 01696 break; 01697 case XML_DOCUMENT_TYPE_NODE: 01698 fprintf(output, "T"); 01699 break; 01700 case XML_DOCUMENT_FRAG_NODE: 01701 fprintf(output, "F"); 01702 break; 01703 case XML_NOTATION_NODE: 01704 fprintf(output, "N"); 01705 break; 01706 case XML_NAMESPACE_DECL: 01707 fprintf(output, "n"); 01708 break; 01709 default: 01710 fprintf(output, "?"); 01711 } 01712 if (node->type != XML_NAMESPACE_DECL) { 01713 if (node->properties != NULL) 01714 fprintf(output, "a"); 01715 else 01716 fprintf(output, "-"); 01717 if (node->nsDef != NULL) 01718 fprintf(output, "n"); 01719 else 01720 fprintf(output, "-"); 01721 } 01722 01723 fprintf(output, " %8d ", xmlLsCountNode(node)); 01724 01725 switch (node->type) { 01726 case XML_ELEMENT_NODE: 01727 if (node->name != NULL) 01728 fprintf(output, "%s", (const char *) node->name); 01729 break; 01730 case XML_ATTRIBUTE_NODE: 01731 if (node->name != NULL) 01732 fprintf(output, "%s", (const char *) node->name); 01733 break; 01734 case XML_TEXT_NODE: 01735 if (node->content != NULL) { 01736 xmlDebugDumpString(output, node->content); 01737 } 01738 break; 01739 case XML_CDATA_SECTION_NODE: 01740 break; 01741 case XML_ENTITY_REF_NODE: 01742 if (node->name != NULL) 01743 fprintf(output, "%s", (const char *) node->name); 01744 break; 01745 case XML_ENTITY_NODE: 01746 if (node->name != NULL) 01747 fprintf(output, "%s", (const char *) node->name); 01748 break; 01749 case XML_PI_NODE: 01750 if (node->name != NULL) 01751 fprintf(output, "%s", (const char *) node->name); 01752 break; 01753 case XML_COMMENT_NODE: 01754 break; 01755 case XML_DOCUMENT_NODE: 01756 break; 01757 case XML_HTML_DOCUMENT_NODE: 01758 break; 01759 case XML_DOCUMENT_TYPE_NODE: 01760 break; 01761 case XML_DOCUMENT_FRAG_NODE: 01762 break; 01763 case XML_NOTATION_NODE: 01764 break; 01765 case XML_NAMESPACE_DECL: { 01766 xmlNsPtr ns = (xmlNsPtr) node; 01767 01768 if (ns->prefix == NULL) 01769 fprintf(output, "default -> %s", (char *)ns->href); 01770 else 01771 fprintf(output, "%s -> %s", (char *)ns->prefix, 01772 (char *)ns->href); 01773 break; 01774 } 01775 default: 01776 if (node->name != NULL) 01777 fprintf(output, "%s", (const char *) node->name); 01778 } 01779 fprintf(output, "\n"); 01780 } 01781 01790 const char * 01791 xmlBoolToText(int boolval) 01792 { 01793 if (boolval) 01794 return("True"); 01795 else 01796 return("False"); 01797 } 01798 01799 #ifdef LIBXML_XPATH_ENABLED 01800 /**************************************************************** 01801 * * 01802 * The XML shell related functions * 01803 * * 01804 ****************************************************************/ 01805 01806 01807 01808 /* 01809 * TODO: Improvement/cleanups for the XML shell 01810 * - allow to shell out an editor on a subpart 01811 * - cleanup function registrations (with help) and calling 01812 * - provide registration routines 01813 */ 01814 01822 void 01823 xmlShellPrintXPathError(int errorType, const char *arg) 01824 { 01825 const char *default_arg = "Result"; 01826 01827 if (!arg) 01828 arg = default_arg; 01829 01830 switch (errorType) { 01831 case XPATH_UNDEFINED: 01832 xmlGenericError(xmlGenericErrorContext, 01833 "%s: no such node\n", arg); 01834 break; 01835 01836 case XPATH_BOOLEAN: 01837 xmlGenericError(xmlGenericErrorContext, 01838 "%s is a Boolean\n", arg); 01839 break; 01840 case XPATH_NUMBER: 01841 xmlGenericError(xmlGenericErrorContext, 01842 "%s is a number\n", arg); 01843 break; 01844 case XPATH_STRING: 01845 xmlGenericError(xmlGenericErrorContext, 01846 "%s is a string\n", arg); 01847 break; 01848 case XPATH_POINT: 01849 xmlGenericError(xmlGenericErrorContext, 01850 "%s is a point\n", arg); 01851 break; 01852 case XPATH_RANGE: 01853 xmlGenericError(xmlGenericErrorContext, 01854 "%s is a range\n", arg); 01855 break; 01856 case XPATH_LOCATIONSET: 01857 xmlGenericError(xmlGenericErrorContext, 01858 "%s is a range\n", arg); 01859 break; 01860 case XPATH_USERS: 01861 xmlGenericError(xmlGenericErrorContext, 01862 "%s is user-defined\n", arg); 01863 break; 01864 case XPATH_XSLT_TREE: 01865 xmlGenericError(xmlGenericErrorContext, 01866 "%s is an XSLT value tree\n", arg); 01867 break; 01868 } 01869 #if 0 01870 xmlGenericError(xmlGenericErrorContext, 01871 "Try casting the result string function (xpath builtin)\n", 01872 arg); 01873 #endif 01874 } 01875 01876 01877 #ifdef LIBXML_OUTPUT_ENABLED 01878 01885 static void 01886 xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node) 01887 { 01888 FILE *fp; 01889 01890 if (!node) 01891 return; 01892 if (ctxt == NULL) 01893 fp = stdout; 01894 else 01895 fp = ctxt->output; 01896 01897 if (node->type == XML_DOCUMENT_NODE) 01898 xmlDocDump(fp, (xmlDocPtr) node); 01899 else if (node->type == XML_ATTRIBUTE_NODE) 01900 xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0); 01901 else 01902 xmlElemDump(fp, node->doc, node); 01903 01904 fprintf(fp, "\n"); 01905 } 01906 01913 void 01914 xmlShellPrintNode(xmlNodePtr node) 01915 { 01916 xmlShellPrintNodeCtxt(NULL, node); 01917 } 01918 #endif /* LIBXML_OUTPUT_ENABLED */ 01919 01927 static void 01928 xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list) 01929 { 01930 if (!ctxt) 01931 return; 01932 01933 if (list != NULL) { 01934 switch (list->type) { 01935 case XPATH_NODESET:{ 01936 #ifdef LIBXML_OUTPUT_ENABLED 01937 int indx; 01938 01939 if (list->nodesetval) { 01940 for (indx = 0; indx < list->nodesetval->nodeNr; 01941 indx++) { 01942 xmlShellPrintNodeCtxt(ctxt, 01943 list->nodesetval->nodeTab[indx]); 01944 } 01945 } else { 01946 xmlGenericError(xmlGenericErrorContext, 01947 "Empty node set\n"); 01948 } 01949 break; 01950 #else 01951 xmlGenericError(xmlGenericErrorContext, 01952 "Node set\n"); 01953 #endif /* LIBXML_OUTPUT_ENABLED */ 01954 } 01955 case XPATH_BOOLEAN: 01956 xmlGenericError(xmlGenericErrorContext, 01957 "Is a Boolean:%s\n", 01958 xmlBoolToText(list->boolval)); 01959 break; 01960 case XPATH_NUMBER: 01961 xmlGenericError(xmlGenericErrorContext, 01962 "Is a number:%0g\n", list->floatval); 01963 break; 01964 case XPATH_STRING: 01965 xmlGenericError(xmlGenericErrorContext, 01966 "Is a string:%s\n", list->stringval); 01967 break; 01968 01969 default: 01970 xmlShellPrintXPathError(list->type, NULL); 01971 } 01972 } 01973 } 01974 01981 void 01982 xmlShellPrintXPathResult(xmlXPathObjectPtr list) 01983 { 01984 xmlShellPrintXPathResultCtxt(NULL, list); 01985 } 01986 01999 int 02000 xmlShellList(xmlShellCtxtPtr ctxt, 02001 char *arg ATTRIBUTE_UNUSED, xmlNodePtr node, 02002 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02003 { 02004 xmlNodePtr cur; 02005 if (!ctxt) 02006 return (0); 02007 if (node == NULL) { 02008 fprintf(ctxt->output, "NULL\n"); 02009 return (0); 02010 } 02011 if ((node->type == XML_DOCUMENT_NODE) || 02012 (node->type == XML_HTML_DOCUMENT_NODE)) { 02013 cur = ((xmlDocPtr) node)->children; 02014 } else if (node->type == XML_NAMESPACE_DECL) { 02015 xmlLsOneNode(ctxt->output, node); 02016 return (0); 02017 } else if (node->children != NULL) { 02018 cur = node->children; 02019 } else { 02020 xmlLsOneNode(ctxt->output, node); 02021 return (0); 02022 } 02023 while (cur != NULL) { 02024 xmlLsOneNode(ctxt->output, cur); 02025 cur = cur->next; 02026 } 02027 return (0); 02028 } 02029 02042 int 02043 xmlShellBase(xmlShellCtxtPtr ctxt, 02044 char *arg ATTRIBUTE_UNUSED, xmlNodePtr node, 02045 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02046 { 02047 xmlChar *base; 02048 if (!ctxt) 02049 return 0; 02050 if (node == NULL) { 02051 fprintf(ctxt->output, "NULL\n"); 02052 return (0); 02053 } 02054 02055 base = xmlNodeGetBase(node->doc, node); 02056 02057 if (base == NULL) { 02058 fprintf(ctxt->output, " No base found !!!\n"); 02059 } else { 02060 fprintf(ctxt->output, "%s\n", base); 02061 xmlFree(base); 02062 } 02063 return (0); 02064 } 02065 02066 #ifdef LIBXML_TREE_ENABLED 02067 02079 static int 02080 xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, 02081 char *arg ATTRIBUTE_UNUSED, xmlNodePtr node, 02082 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02083 { 02084 xmlNodeSetBase(node, (xmlChar*) arg); 02085 return (0); 02086 } 02087 #endif 02088 02089 #ifdef LIBXML_XPATH_ENABLED 02090 02103 static int 02104 xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg, 02105 xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr node2 ATTRIBUTE_UNUSED) 02106 { 02107 xmlChar* nsListDup; 02108 xmlChar* prefix; 02109 xmlChar* href; 02110 xmlChar* next; 02111 02112 nsListDup = xmlStrdup((xmlChar *) arg); 02113 next = nsListDup; 02114 while(next != NULL) { 02115 /* skip spaces */ 02116 /*while((*next) == ' ') next++;*/ 02117 if((*next) == '\0') break; 02118 02119 /* find prefix */ 02120 prefix = next; 02121 next = (xmlChar*)xmlStrchr(next, '='); 02122 if(next == NULL) { 02123 fprintf(ctxt->output, "setns: prefix=[nsuri] required\n"); 02124 xmlFree(nsListDup); 02125 return(-1); 02126 } 02127 *(next++) = '\0'; 02128 02129 /* find href */ 02130 href = next; 02131 next = (xmlChar*)xmlStrchr(next, ' '); 02132 if(next != NULL) { 02133 *(next++) = '\0'; 02134 } 02135 02136 /* do register namespace */ 02137 if(xmlXPathRegisterNs(ctxt->pctxt, prefix, href) != 0) { 02138 fprintf(ctxt->output,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href); 02139 xmlFree(nsListDup); 02140 return(-1); 02141 } 02142 } 02143 02144 xmlFree(nsListDup); 02145 return(0); 02146 } 02159 static int 02160 xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED, 02161 xmlNodePtr root, xmlNodePtr node2 ATTRIBUTE_UNUSED) 02162 { 02163 xmlNsPtr ns; 02164 02165 if ((root == NULL) || (root->type != XML_ELEMENT_NODE) || 02166 (root->nsDef == NULL) || (ctxt == NULL) || (ctxt->pctxt == NULL)) 02167 return(-1); 02168 ns = root->nsDef; 02169 while (ns != NULL) { 02170 if (ns->prefix == NULL) 02171 xmlXPathRegisterNs(ctxt->pctxt, BAD_CAST "defaultns", ns->href); 02172 else 02173 xmlXPathRegisterNs(ctxt->pctxt, ns->prefix, ns->href); 02174 ns = ns->next; 02175 } 02176 return(0); 02177 } 02178 #endif 02179 02192 static int 02193 xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, 02194 char *arg, xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED) 02195 { 02196 if (!ctxt) 02197 return (0); 02198 if (node == NULL) 02199 return (0); 02200 if (arg == NULL) 02201 return (0); 02202 #ifdef LIBXML_REGEXP_ENABLED 02203 if ((xmlStrchr((xmlChar *) arg, '?')) || 02204 (xmlStrchr((xmlChar *) arg, '*')) || 02205 (xmlStrchr((xmlChar *) arg, '.')) || 02206 (xmlStrchr((xmlChar *) arg, '['))) { 02207 } 02208 #endif 02209 while (node != NULL) { 02210 if (node->type == XML_COMMENT_NODE) { 02211 if (xmlStrstr(node->content, (xmlChar *) arg)) { 02212 02213 fprintf(ctxt->output, "%s : ", xmlGetNodePath(node)); 02214 xmlShellList(ctxt, NULL, node, NULL); 02215 } 02216 } else if (node->type == XML_TEXT_NODE) { 02217 if (xmlStrstr(node->content, (xmlChar *) arg)) { 02218 02219 fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent)); 02220 xmlShellList(ctxt, NULL, node->parent, NULL); 02221 } 02222 } 02223 02224 /* 02225 * Browse the full subtree, deep first 02226 */ 02227 02228 if ((node->type == XML_DOCUMENT_NODE) || 02229 (node->type == XML_HTML_DOCUMENT_NODE)) { 02230 node = ((xmlDocPtr) node)->children; 02231 } else if ((node->children != NULL) 02232 && (node->type != XML_ENTITY_REF_NODE)) { 02233 /* deep first */ 02234 node = node->children; 02235 } else if (node->next != NULL) { 02236 /* then siblings */ 02237 node = node->next; 02238 } else { 02239 /* go up to parents->next if needed */ 02240 while (node != NULL) { 02241 if (node->parent != NULL) { 02242 node = node->parent; 02243 } 02244 if (node->next != NULL) { 02245 node = node->next; 02246 break; 02247 } 02248 if (node->parent == NULL) { 02249 node = NULL; 02250 break; 02251 } 02252 } 02253 } 02254 } 02255 return (0); 02256 } 02257 02270 int 02271 xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, 02272 char *arg ATTRIBUTE_UNUSED, xmlNodePtr node, 02273 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02274 { 02275 if (!ctxt) 02276 return (0); 02277 if (node == NULL) { 02278 fprintf(ctxt->output, "NULL\n"); 02279 return (0); 02280 } 02281 if ((node->type == XML_DOCUMENT_NODE) || 02282 (node->type == XML_HTML_DOCUMENT_NODE)) { 02283 xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node); 02284 } else if (node->type == XML_ATTRIBUTE_NODE) { 02285 xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0); 02286 } else { 02287 xmlDebugDumpOneNode(ctxt->output, node, 0); 02288 } 02289 return (0); 02290 } 02291 02304 static int 02305 xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, 02306 char *value, xmlNodePtr node, 02307 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02308 { 02309 xmlNodePtr results; 02310 xmlParserErrors ret; 02311 02312 if (!ctxt) 02313 return (0); 02314 if (node == NULL) { 02315 fprintf(ctxt->output, "NULL\n"); 02316 return (0); 02317 } 02318 if (value == NULL) { 02319 fprintf(ctxt->output, "NULL\n"); 02320 return (0); 02321 } 02322 02323 ret = xmlParseInNodeContext(node, value, strlen(value), 0, &results); 02324 if (ret == XML_ERR_OK) { 02325 if (node->children != NULL) { 02326 xmlFreeNodeList(node->children); 02327 node->children = NULL; 02328 node->last = NULL; 02329 } 02330 xmlAddChildList(node, results); 02331 } else { 02332 fprintf(ctxt->output, "failed to parse content\n"); 02333 } 02334 return (0); 02335 } 02336 02337 #ifdef LIBXML_SCHEMAS_ENABLED 02338 02350 static int 02351 xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas, 02352 xmlNodePtr node ATTRIBUTE_UNUSED, 02353 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02354 { 02355 xmlRelaxNGPtr relaxngschemas; 02356 xmlRelaxNGParserCtxtPtr ctxt; 02357 xmlRelaxNGValidCtxtPtr vctxt; 02358 int ret; 02359 02360 ctxt = xmlRelaxNGNewParserCtxt(schemas); 02361 xmlRelaxNGSetParserErrors(ctxt, 02362 (xmlRelaxNGValidityErrorFunc) fprintf, 02363 (xmlRelaxNGValidityWarningFunc) fprintf, 02364 stderr); 02365 relaxngschemas = xmlRelaxNGParse(ctxt); 02366 xmlRelaxNGFreeParserCtxt(ctxt); 02367 if (relaxngschemas == NULL) { 02368 xmlGenericError(xmlGenericErrorContext, 02369 "Relax-NG schema %s failed to compile\n", schemas); 02370 return(-1); 02371 } 02372 vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas); 02373 xmlRelaxNGSetValidErrors(vctxt, 02374 (xmlRelaxNGValidityErrorFunc) fprintf, 02375 (xmlRelaxNGValidityWarningFunc) fprintf, 02376 stderr); 02377 ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc); 02378 if (ret == 0) { 02379 fprintf(stderr, "%s validates\n", sctxt->filename); 02380 } else if (ret > 0) { 02381 fprintf(stderr, "%s fails to validate\n", sctxt->filename); 02382 } else { 02383 fprintf(stderr, "%s validation generated an internal error\n", 02384 sctxt->filename); 02385 } 02386 xmlRelaxNGFreeValidCtxt(vctxt); 02387 if (relaxngschemas != NULL) 02388 xmlRelaxNGFree(relaxngschemas); 02389 return(0); 02390 } 02391 #endif 02392 02393 #ifdef LIBXML_OUTPUT_ENABLED 02394 02406 int 02407 xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED, 02408 xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED) 02409 { 02410 if (!ctxt) 02411 return (0); 02412 if (node == NULL) { 02413 fprintf(ctxt->output, "NULL\n"); 02414 return (0); 02415 } 02416 if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) { 02417 #ifdef LIBXML_HTML_ENABLED 02418 if (node->type == XML_HTML_DOCUMENT_NODE) 02419 htmlDocDump(ctxt->output, (htmlDocPtr) node); 02420 else 02421 htmlNodeDumpFile(ctxt->output, ctxt->doc, node); 02422 #else 02423 if (node->type == XML_DOCUMENT_NODE) 02424 xmlDocDump(ctxt->output, (xmlDocPtr) node); 02425 else 02426 xmlElemDump(ctxt->output, ctxt->doc, node); 02427 #endif /* LIBXML_HTML_ENABLED */ 02428 } else { 02429 if (node->type == XML_DOCUMENT_NODE) 02430 xmlDocDump(ctxt->output, (xmlDocPtr) node); 02431 else 02432 xmlElemDump(ctxt->output, ctxt->doc, node); 02433 } 02434 fprintf(ctxt->output, "\n"); 02435 return (0); 02436 } 02437 #endif /* LIBXML_OUTPUT_ENABLED */ 02438 02451 int 02452 xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename, 02453 xmlNodePtr node ATTRIBUTE_UNUSED, 02454 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02455 { 02456 xmlDocPtr doc; 02457 int html = 0; 02458 02459 if ((ctxt == NULL) || (filename == NULL)) return(-1); 02460 if (ctxt->doc != NULL) 02461 html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE); 02462 02463 if (html) { 02464 #ifdef LIBXML_HTML_ENABLED 02465 doc = htmlParseFile(filename, NULL); 02466 #else 02467 fprintf(ctxt->output, "HTML support not compiled in\n"); 02468 doc = NULL; 02469 #endif /* LIBXML_HTML_ENABLED */ 02470 } else { 02471 doc = xmlReadFile(filename,NULL,0); 02472 } 02473 if (doc != NULL) { 02474 if (ctxt->loaded == 1) { 02475 xmlFreeDoc(ctxt->doc); 02476 } 02477 ctxt->loaded = 1; 02478 #ifdef LIBXML_XPATH_ENABLED 02479 xmlXPathFreeContext(ctxt->pctxt); 02480 #endif /* LIBXML_XPATH_ENABLED */ 02481 xmlFree(ctxt->filename); 02482 ctxt->doc = doc; 02483 ctxt->node = (xmlNodePtr) doc; 02484 #ifdef LIBXML_XPATH_ENABLED 02485 ctxt->pctxt = xmlXPathNewContext(doc); 02486 #endif /* LIBXML_XPATH_ENABLED */ 02487 ctxt->filename = (char *) xmlCanonicPath((xmlChar *) filename); 02488 } else 02489 return (-1); 02490 return (0); 02491 } 02492 02493 #ifdef LIBXML_OUTPUT_ENABLED 02494 02507 int 02508 xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node, 02509 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02510 { 02511 if (node == NULL) 02512 return (-1); 02513 if ((filename == NULL) || (filename[0] == 0)) { 02514 return (-1); 02515 } 02516 #ifdef W_OK 02517 if (access((char *) filename, W_OK)) { 02518 xmlGenericError(xmlGenericErrorContext, 02519 "Cannot write to %s\n", filename); 02520 return (-1); 02521 } 02522 #endif 02523 switch (node->type) { 02524 case XML_DOCUMENT_NODE: 02525 if (xmlSaveFile((char *) filename, ctxt->doc) < -1) { 02526 xmlGenericError(xmlGenericErrorContext, 02527 "Failed to write to %s\n", filename); 02528 return (-1); 02529 } 02530 break; 02531 case XML_HTML_DOCUMENT_NODE: 02532 #ifdef LIBXML_HTML_ENABLED 02533 if (htmlSaveFile((char *) filename, ctxt->doc) < 0) { 02534 xmlGenericError(xmlGenericErrorContext, 02535 "Failed to write to %s\n", filename); 02536 return (-1); 02537 } 02538 #else 02539 if (xmlSaveFile((char *) filename, ctxt->doc) < -1) { 02540 xmlGenericError(xmlGenericErrorContext, 02541 "Failed to write to %s\n", filename); 02542 return (-1); 02543 } 02544 #endif /* LIBXML_HTML_ENABLED */ 02545 break; 02546 default:{ 02547 FILE *f; 02548 02549 f = fopen((char *) filename, "w"); 02550 if (f == NULL) { 02551 xmlGenericError(xmlGenericErrorContext, 02552 "Failed to write to %s\n", filename); 02553 return (-1); 02554 } 02555 xmlElemDump(f, ctxt->doc, node); 02556 fclose(f); 02557 } 02558 } 02559 return (0); 02560 } 02561 02574 int 02575 xmlShellSave(xmlShellCtxtPtr ctxt, char *filename, 02576 xmlNodePtr node ATTRIBUTE_UNUSED, 02577 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02578 { 02579 if ((ctxt == NULL) || (ctxt->doc == NULL)) 02580 return (-1); 02581 if ((filename == NULL) || (filename[0] == 0)) 02582 filename = ctxt->filename; 02583 if (filename == NULL) 02584 return (-1); 02585 #ifdef W_OK 02586 if (access((char *) filename, W_OK)) { 02587 xmlGenericError(xmlGenericErrorContext, 02588 "Cannot save to %s\n", filename); 02589 return (-1); 02590 } 02591 #endif 02592 switch (ctxt->doc->type) { 02593 case XML_DOCUMENT_NODE: 02594 if (xmlSaveFile((char *) filename, ctxt->doc) < 0) { 02595 xmlGenericError(xmlGenericErrorContext, 02596 "Failed to save to %s\n", filename); 02597 } 02598 break; 02599 case XML_HTML_DOCUMENT_NODE: 02600 #ifdef LIBXML_HTML_ENABLED 02601 if (htmlSaveFile((char *) filename, ctxt->doc) < 0) { 02602 xmlGenericError(xmlGenericErrorContext, 02603 "Failed to save to %s\n", filename); 02604 } 02605 #else 02606 if (xmlSaveFile((char *) filename, ctxt->doc) < 0) { 02607 xmlGenericError(xmlGenericErrorContext, 02608 "Failed to save to %s\n", filename); 02609 } 02610 #endif /* LIBXML_HTML_ENABLED */ 02611 break; 02612 default: 02613 xmlGenericError(xmlGenericErrorContext, 02614 "To save to subparts of a document use the 'write' command\n"); 02615 return (-1); 02616 02617 } 02618 return (0); 02619 } 02620 #endif /* LIBXML_OUTPUT_ENABLED */ 02621 02622 #ifdef LIBXML_VALID_ENABLED 02623 02636 int 02637 xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd, 02638 xmlNodePtr node ATTRIBUTE_UNUSED, 02639 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02640 { 02641 xmlValidCtxt vctxt; 02642 int res = -1; 02643 02644 if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1); 02645 vctxt.userData = stderr; 02646 vctxt.error = (xmlValidityErrorFunc) fprintf; 02647 vctxt.warning = (xmlValidityWarningFunc) fprintf; 02648 02649 if ((dtd == NULL) || (dtd[0] == 0)) { 02650 res = xmlValidateDocument(&vctxt, ctxt->doc); 02651 } else { 02652 xmlDtdPtr subset; 02653 02654 subset = xmlParseDTD(NULL, (xmlChar *) dtd); 02655 if (subset != NULL) { 02656 res = xmlValidateDtd(&vctxt, ctxt->doc, subset); 02657 02658 xmlFreeDtd(subset); 02659 } 02660 } 02661 return (res); 02662 } 02663 #endif /* LIBXML_VALID_ENABLED */ 02664 02678 int 02679 xmlShellDu(xmlShellCtxtPtr ctxt, 02680 char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree, 02681 xmlNodePtr node2 ATTRIBUTE_UNUSED) 02682 { 02683 xmlNodePtr node; 02684 int indent = 0, i; 02685 02686 if (!ctxt) 02687 return (-1); 02688 02689 if (tree == NULL) 02690 return (-1); 02691 node = tree; 02692 while (node != NULL) { 02693 if ((node->type == XML_DOCUMENT_NODE) || 02694 (node->type == XML_HTML_DOCUMENT_NODE)) { 02695 fprintf(ctxt->output, "/\n"); 02696 } else if (node->type == XML_ELEMENT_NODE) { 02697 for (i = 0; i < indent; i++) 02698 fprintf(ctxt->output, " "); 02699 fprintf(ctxt->output, "%s\n", node->name); 02700 } else { 02701 } 02702 02703 /* 02704 * Browse the full subtree, deep first 02705 */ 02706 02707 if ((node->type == XML_DOCUMENT_NODE) || 02708 (node->type == XML_HTML_DOCUMENT_NODE)) { 02709 node = ((xmlDocPtr) node)->children; 02710 } else if ((node->children != NULL) 02711 && (node->type != XML_ENTITY_REF_NODE)) { 02712 /* deep first */ 02713 node = node->children; 02714 indent++; 02715 } else if ((node != tree) && (node->next != NULL)) { 02716 /* then siblings */ 02717 node = node->next; 02718 } else if (node != tree) { 02719 /* go up to parents->next if needed */ 02720 while (node != tree) { 02721 if (node->parent != NULL) { 02722 node = node->parent; 02723 indent--; 02724 } 02725 if ((node != tree) && (node->next != NULL)) { 02726 node = node->next; 02727 break; 02728 } 02729 if (node->parent == NULL) { 02730 node = NULL; 02731 break; 02732 } 02733 if (node == tree) { 02734 node = NULL; 02735 break; 02736 } 02737 } 02738 /* exit condition */ 02739 if (node == tree) 02740 node = NULL; 02741 } else 02742 node = NULL; 02743 } 02744 return (0); 02745 } 02746 02761 int 02762 xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer, 02763 xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED) 02764 { 02765 xmlChar *path; 02766 02767 if ((node == NULL) || (buffer == NULL)) 02768 return (-1); 02769 02770 path = xmlGetNodePath(node); 02771 if (path == NULL) 02772 return (-1); 02773 02774 /* 02775 * This test prevents buffer overflow, because this routine 02776 * is only called by xmlShell, in which the second argument is 02777 * 500 chars long. 02778 * It is a dirty hack before a cleaner solution is found. 02779 * Documentation should mention that the second argument must 02780 * be at least 500 chars long, and could be stripped if too long. 02781 */ 02782 snprintf(buffer, 499, "%s", path); 02783 buffer[499] = '0'; 02784 xmlFree(path); 02785 02786 return (0); 02787 } 02788 02800 void 02801 xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, 02802 FILE * output) 02803 { 02804 char prompt[500] = "/ > "; 02805 char *cmdline = NULL, *cur; 02806 char command[100]; 02807 char arg[400]; 02808 int i; 02809 xmlShellCtxtPtr ctxt; 02810 xmlXPathObjectPtr list; 02811 02812 if (doc == NULL) 02813 return; 02814 if (filename == NULL) 02815 return; 02816 if (input == NULL) 02817 return; 02818 if (output == NULL) 02819 output = stdout; 02820 ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt)); 02821 if (ctxt == NULL) 02822 return; 02823 ctxt->loaded = 0; 02824 ctxt->doc = doc; 02825 ctxt->input = input; 02826 ctxt->output = output; 02827 ctxt->filename = (char *) xmlStrdup((xmlChar *) filename); 02828 ctxt->node = (xmlNodePtr) ctxt->doc; 02829 02830 #ifdef LIBXML_XPATH_ENABLED 02831 ctxt->pctxt = xmlXPathNewContext(ctxt->doc); 02832 if (ctxt->pctxt == NULL) { 02833 xmlFree(ctxt); 02834 return; 02835 } 02836 #endif /* LIBXML_XPATH_ENABLED */ 02837 while (1) { 02838 if (ctxt->node == (xmlNodePtr) ctxt->doc) 02839 snprintf(prompt, sizeof(prompt), "%s > ", "/"); 02840 else if ((ctxt->node != NULL) && (ctxt->node->name)) 02841 snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name); 02842 else 02843 snprintf(prompt, sizeof(prompt), "? > "); 02844 prompt[sizeof(prompt) - 1] = 0; 02845 02846 /* 02847 * Get a new command line 02848 */ 02849 cmdline = ctxt->input(prompt); 02850 if (cmdline == NULL) 02851 break; 02852 02853 /* 02854 * Parse the command itself 02855 */ 02856 cur = cmdline; 02857 while ((*cur == ' ') || (*cur == '\t')) 02858 cur++; 02859 i = 0; 02860 while ((*cur != ' ') && (*cur != '\t') && 02861 (*cur != '\n') && (*cur != '\r')) { 02862 if (*cur == 0) 02863 break; 02864 command[i++] = *cur++; 02865 } 02866 command[i] = 0; 02867 if (i == 0) 02868 continue; 02869 02870 /* 02871 * Parse the argument 02872 */ 02873 while ((*cur == ' ') || (*cur == '\t')) 02874 cur++; 02875 i = 0; 02876 while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) { 02877 if (*cur == 0) 02878 break; 02879 arg[i++] = *cur++; 02880 } 02881 arg[i] = 0; 02882 02883 /* 02884 * start interpreting the command 02885 */ 02886 if (!strcmp(command, "exit")) 02887 break; 02888 if (!strcmp(command, "quit")) 02889 break; 02890 if (!strcmp(command, "bye")) 02891 break; 02892 if (!strcmp(command, "help")) { 02893 fprintf(ctxt->output, "\tbase display XML base of the node\n"); 02894 fprintf(ctxt->output, "\tsetbase URI change the XML base of the node\n"); 02895 fprintf(ctxt->output, "\tbye leave shell\n"); 02896 fprintf(ctxt->output, "\tcat [node] display node or current node\n"); 02897 fprintf(ctxt->output, "\tcd [path] change directory to path or to root\n"); 02898 fprintf(ctxt->output, "\tdir [path] dumps informations about the node (namespace, attributes, content)\n"); 02899 fprintf(ctxt->output, "\tdu [path] show the structure of the subtree under path or the current node\n"); 02900 fprintf(ctxt->output, "\texit leave shell\n"); 02901 fprintf(ctxt->output, "\thelp display this help\n"); 02902 fprintf(ctxt->output, "\tfree display memory usage\n"); 02903 fprintf(ctxt->output, "\tload [name] load a new document with name\n"); 02904 fprintf(ctxt->output, "\tls [path] list contents of path or the current directory\n"); 02905 fprintf(ctxt->output, "\tset xml_fragment replace the current node content with the fragment parsed in context\n"); 02906 #ifdef LIBXML_XPATH_ENABLED 02907 fprintf(ctxt->output, "\txpath expr evaluate the XPath expression in that context and print the result\n"); 02908 fprintf(ctxt->output, "\tsetns nsreg register a namespace to a prefix in the XPath evaluation context\n"); 02909 fprintf(ctxt->output, "\t format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix)\n"); 02910 fprintf(ctxt->output, "\tsetrootns register all namespace found on the root element\n"); 02911 fprintf(ctxt->output, "\t the default namespace if any uses 'defaultns' prefix\n"); 02912 #endif /* LIBXML_XPATH_ENABLED */ 02913 fprintf(ctxt->output, "\tpwd display current working directory\n"); 02914 fprintf(ctxt->output, "\tquit leave shell\n"); 02915 #ifdef LIBXML_OUTPUT_ENABLED 02916 fprintf(ctxt->output, "\tsave [name] save this document to name or the original name\n"); 02917 fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n"); 02918 #endif /* LIBXML_OUTPUT_ENABLED */ 02919 #ifdef LIBXML_VALID_ENABLED 02920 fprintf(ctxt->output, "\tvalidate check the document for errors\n"); 02921 #endif /* LIBXML_VALID_ENABLED */ 02922 #ifdef LIBXML_SCHEMAS_ENABLED 02923 fprintf(ctxt->output, "\trelaxng rng validate the document agaisnt the Relax-NG schemas\n"); 02924 #endif 02925 fprintf(ctxt->output, "\tgrep string search for a string in the subtree\n"); 02926 #ifdef LIBXML_VALID_ENABLED 02927 } else if (!strcmp(command, "validate")) { 02928 xmlShellValidate(ctxt, arg, NULL, NULL); 02929 #endif /* LIBXML_VALID_ENABLED */ 02930 } else if (!strcmp(command, "load")) { 02931 xmlShellLoad(ctxt, arg, NULL, NULL); 02932 #ifdef LIBXML_SCHEMAS_ENABLED 02933 } else if (!strcmp(command, "relaxng")) { 02934 xmlShellRNGValidate(ctxt, arg, NULL, NULL); 02935 #endif 02936 #ifdef LIBXML_OUTPUT_ENABLED 02937 } else if (!strcmp(command, "save")) { 02938 xmlShellSave(ctxt, arg, NULL, NULL); 02939 } else if (!strcmp(command, "write")) { 02940 if ((arg == NULL) || (arg[0] == 0)) 02941 xmlGenericError(xmlGenericErrorContext, 02942 "Write command requires a filename argument\n"); 02943 else 02944 xmlShellWrite(ctxt, arg, ctxt->node, NULL); 02945 #endif /* LIBXML_OUTPUT_ENABLED */ 02946 } else if (!strcmp(command, "grep")) { 02947 xmlShellGrep(ctxt, arg, ctxt->node, NULL); 02948 } else if (!strcmp(command, "free")) { 02949 if (arg[0] == 0) { 02950 xmlMemShow(ctxt->output, 0); 02951 } else { 02952 int len = 0; 02953 02954 sscanf(arg, "%d", &len); 02955 xmlMemShow(ctxt->output, len); 02956 } 02957 } else if (!strcmp(command, "pwd")) { 02958 char dir[500]; 02959 02960 if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL)) 02961 fprintf(ctxt->output, "%s\n", dir); 02962 } else if (!strcmp(command, "du")) { 02963 xmlShellDu(ctxt, NULL, ctxt->node, NULL); 02964 } else if (!strcmp(command, "base")) { 02965 xmlShellBase(ctxt, NULL, ctxt->node, NULL); 02966 } else if (!strcmp(command, "set")) { 02967 xmlShellSetContent(ctxt, arg, ctxt->node, NULL); 02968 #ifdef LIBXML_XPATH_ENABLED 02969 } else if (!strcmp(command, "setns")) { 02970 if (arg[0] == 0) { 02971 xmlGenericError(xmlGenericErrorContext, 02972 "setns: prefix=[nsuri] required\n"); 02973 } else { 02974 xmlShellRegisterNamespace(ctxt, arg, NULL, NULL); 02975 } 02976 } else if (!strcmp(command, "setrootns")) { 02977 xmlNodePtr root; 02978 02979 root = xmlDocGetRootElement(ctxt->doc); 02980 xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL); 02981 } else if (!strcmp(command, "xpath")) { 02982 if (arg[0] == 0) { 02983 xmlGenericError(xmlGenericErrorContext, 02984 "xpath: expression required\n"); 02985 } else { 02986 ctxt->pctxt->node = ctxt->node; 02987 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); 02988 xmlXPathDebugDumpObject(ctxt->output, list, 0); 02989 xmlXPathFreeObject(list); 02990 } 02991 #endif /* LIBXML_XPATH_ENABLED */ 02992 #ifdef LIBXML_TREE_ENABLED 02993 } else if (!strcmp(command, "setbase")) { 02994 xmlShellSetBase(ctxt, arg, ctxt->node, NULL); 02995 #endif 02996 } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) { 02997 int dir = (!strcmp(command, "dir")); 02998 02999 if (arg[0] == 0) { 03000 if (dir) 03001 xmlShellDir(ctxt, NULL, ctxt->node, NULL); 03002 else 03003 xmlShellList(ctxt, NULL, ctxt->node, NULL); 03004 } else { 03005 ctxt->pctxt->node = ctxt->node; 03006 #ifdef LIBXML_XPATH_ENABLED 03007 ctxt->pctxt->node = ctxt->node; 03008 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); 03009 #else 03010 list = NULL; 03011 #endif /* LIBXML_XPATH_ENABLED */ 03012 if (list != NULL) { 03013 switch (list->type) { 03014 case XPATH_UNDEFINED: 03015 xmlGenericError(xmlGenericErrorContext, 03016 "%s: no such node\n", arg); 03017 break; 03018 case XPATH_NODESET:{ 03019 int indx; 03020 03021 if (list->nodesetval == NULL) 03022 break; 03023 03024 for (indx = 0; 03025 indx < list->nodesetval->nodeNr; 03026 indx++) { 03027 if (dir) 03028 xmlShellDir(ctxt, NULL, 03029 list->nodesetval-> 03030 nodeTab[indx], NULL); 03031 else 03032 xmlShellList(ctxt, NULL, 03033 list->nodesetval-> 03034 nodeTab[indx], NULL); 03035 } 03036 break; 03037 } 03038 case XPATH_BOOLEAN: 03039 xmlGenericError(xmlGenericErrorContext, 03040 "%s is a Boolean\n", arg); 03041 break; 03042 case XPATH_NUMBER: 03043 xmlGenericError(xmlGenericErrorContext, 03044 "%s is a number\n", arg); 03045 break; 03046 case XPATH_STRING: 03047 xmlGenericError(xmlGenericErrorContext, 03048 "%s is a string\n", arg); 03049 break; 03050 case XPATH_POINT: 03051 xmlGenericError(xmlGenericErrorContext, 03052 "%s is a point\n", arg); 03053 break; 03054 case XPATH_RANGE: 03055 xmlGenericError(xmlGenericErrorContext, 03056 "%s is a range\n", arg); 03057 break; 03058 case XPATH_LOCATIONSET: 03059 xmlGenericError(xmlGenericErrorContext, 03060 "%s is a range\n", arg); 03061 break; 03062 case XPATH_USERS: 03063 xmlGenericError(xmlGenericErrorContext, 03064 "%s is user-defined\n", arg); 03065 break; 03066 case XPATH_XSLT_TREE: 03067 xmlGenericError(xmlGenericErrorContext, 03068 "%s is an XSLT value tree\n", 03069 arg); 03070 break; 03071 } 03072 #ifdef LIBXML_XPATH_ENABLED 03073 xmlXPathFreeObject(list); 03074 #endif 03075 } else { 03076 xmlGenericError(xmlGenericErrorContext, 03077 "%s: no such node\n", arg); 03078 } 03079 ctxt->pctxt->node = NULL; 03080 } 03081 } else if (!strcmp(command, "cd")) { 03082 if (arg[0] == 0) { 03083 ctxt->node = (xmlNodePtr) ctxt->doc; 03084 } else { 03085 #ifdef LIBXML_XPATH_ENABLED 03086 ctxt->pctxt->node = ctxt->node; 03087 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); 03088 #else 03089 list = NULL; 03090 #endif /* LIBXML_XPATH_ENABLED */ 03091 if (list != NULL) { 03092 switch (list->type) { 03093 case XPATH_UNDEFINED: 03094 xmlGenericError(xmlGenericErrorContext, 03095 "%s: no such node\n", arg); 03096 break; 03097 case XPATH_NODESET: 03098 if (list->nodesetval != NULL) { 03099 if (list->nodesetval->nodeNr == 1) { 03100 ctxt->node = list->nodesetval->nodeTab[0]; 03101 if ((ctxt->node != NULL) && 03102 (ctxt->node->type == 03103 XML_NAMESPACE_DECL)) { 03104 xmlGenericError(xmlGenericErrorContext, 03105 "cannot cd to namespace\n"); 03106 ctxt->node = NULL; 03107 } 03108 } else 03109 xmlGenericError(xmlGenericErrorContext, 03110 "%s is a %d Node Set\n", 03111 arg, 03112 list->nodesetval->nodeNr); 03113 } else 03114 xmlGenericError(xmlGenericErrorContext, 03115 "%s is an empty Node Set\n", 03116 arg); 03117 break; 03118 case XPATH_BOOLEAN: 03119 xmlGenericError(xmlGenericErrorContext, 03120 "%s is a Boolean\n", arg); 03121 break; 03122 case XPATH_NUMBER: 03123 xmlGenericError(xmlGenericErrorContext, 03124 "%s is a number\n", arg); 03125 break; 03126 case XPATH_STRING: 03127 xmlGenericError(xmlGenericErrorContext, 03128 "%s is a string\n", arg); 03129 break; 03130 case XPATH_POINT: 03131 xmlGenericError(xmlGenericErrorContext, 03132 "%s is a point\n", arg); 03133 break; 03134 case XPATH_RANGE: 03135 xmlGenericError(xmlGenericErrorContext, 03136 "%s is a range\n", arg); 03137 break; 03138 case XPATH_LOCATIONSET: 03139 xmlGenericError(xmlGenericErrorContext, 03140 "%s is a range\n", arg); 03141 break; 03142 case XPATH_USERS: 03143 xmlGenericError(xmlGenericErrorContext, 03144 "%s is user-defined\n", arg); 03145 break; 03146 case XPATH_XSLT_TREE: 03147 xmlGenericError(xmlGenericErrorContext, 03148 "%s is an XSLT value tree\n", 03149 arg); 03150 break; 03151 } 03152 #ifdef LIBXML_XPATH_ENABLED 03153 xmlXPathFreeObject(list); 03154 #endif 03155 } else { 03156 xmlGenericError(xmlGenericErrorContext, 03157 "%s: no such node\n", arg); 03158 } 03159 ctxt->pctxt->node = NULL; 03160 } 03161 #ifdef LIBXML_OUTPUT_ENABLED 03162 } else if (!strcmp(command, "cat")) { 03163 if (arg[0] == 0) { 03164 xmlShellCat(ctxt, NULL, ctxt->node, NULL); 03165 } else { 03166 ctxt->pctxt->node = ctxt->node; 03167 #ifdef LIBXML_XPATH_ENABLED 03168 ctxt->pctxt->node = ctxt->node; 03169 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt); 03170 #else 03171 list = NULL; 03172 #endif /* LIBXML_XPATH_ENABLED */ 03173 if (list != NULL) { 03174 switch (list->type) { 03175 case XPATH_UNDEFINED: 03176 xmlGenericError(xmlGenericErrorContext, 03177 "%s: no such node\n", arg); 03178 break; 03179 case XPATH_NODESET:{ 03180 int indx; 03181 03182 if (list->nodesetval == NULL) 03183 break; 03184 03185 for (indx = 0; 03186 indx < list->nodesetval->nodeNr; 03187 indx++) { 03188 if (i > 0) 03189 fprintf(ctxt->output, " -------\n"); 03190 xmlShellCat(ctxt, NULL, 03191 list->nodesetval-> 03192 nodeTab[indx], NULL); 03193 } 03194 break; 03195 } 03196 case XPATH_BOOLEAN: 03197 xmlGenericError(xmlGenericErrorContext, 03198 "%s is a Boolean\n", arg); 03199 break; 03200 case XPATH_NUMBER: 03201 xmlGenericError(xmlGenericErrorContext, 03202 "%s is a number\n", arg); 03203 break; 03204 case XPATH_STRING: 03205 xmlGenericError(xmlGenericErrorContext, 03206 "%s is a string\n", arg); 03207 break; 03208 case XPATH_POINT: 03209 xmlGenericError(xmlGenericErrorContext, 03210 "%s is a point\n", arg); 03211 break; 03212 case XPATH_RANGE: 03213 xmlGenericError(xmlGenericErrorContext, 03214 "%s is a range\n", arg); 03215 break; 03216 case XPATH_LOCATIONSET: 03217 xmlGenericError(xmlGenericErrorContext, 03218 "%s is a range\n", arg); 03219 break; 03220 case XPATH_USERS: 03221 xmlGenericError(xmlGenericErrorContext, 03222 "%s is user-defined\n", arg); 03223 break; 03224 case XPATH_XSLT_TREE: 03225 xmlGenericError(xmlGenericErrorContext, 03226 "%s is an XSLT value tree\n", 03227 arg); 03228 break; 03229 } 03230 #ifdef LIBXML_XPATH_ENABLED 03231 xmlXPathFreeObject(list); 03232 #endif 03233 } else { 03234 xmlGenericError(xmlGenericErrorContext, 03235 "%s: no such node\n", arg); 03236 } 03237 ctxt->pctxt->node = NULL; 03238 } 03239 #endif /* LIBXML_OUTPUT_ENABLED */ 03240 } else { 03241 xmlGenericError(xmlGenericErrorContext, 03242 "Unknown command %s\n", command); 03243 } 03244 free(cmdline); /* not xmlFree here ! */ 03245 cmdline = NULL; 03246 } 03247 #ifdef LIBXML_XPATH_ENABLED 03248 xmlXPathFreeContext(ctxt->pctxt); 03249 #endif /* LIBXML_XPATH_ENABLED */ 03250 if (ctxt->loaded) { 03251 xmlFreeDoc(ctxt->doc); 03252 } 03253 if (ctxt->filename != NULL) 03254 xmlFree(ctxt->filename); 03255 xmlFree(ctxt); 03256 if (cmdline != NULL) 03257 free(cmdline); /* not xmlFree here ! */ 03258 } 03259 03260 #endif /* LIBXML_XPATH_ENABLED */ 03261 #define bottom_debugXML 03262 #include "elfgcchack.h" 03263 #endif /* LIBXML_DEBUG_ENABLED */ Generated on Sun May 27 2012 04:34:14 for ReactOS by
1.7.6.1
|