Annotation of embedaddon/libxml2/debugXML.c, revision 1.1
1.1 ! misho 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 dictionnary */
! 48: int check; /* do just checkings */
! 49: int errors; /* number of errors found */
! 50: int nodict; /* if the document has no dictionnary */
! 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
! 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
! 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 dictionnary 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 (xmlValidateName(name, 0)) {
! 258: xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
! 259: "Name is not an NCName '%s'", (const char *) name);
! 260: }
! 261: if ((ctxt->dict != NULL) &&
! 262: (!xmlDictOwns(ctxt->dict, name)) &&
! 263: ((ctxt->doc == NULL) ||
! 264: ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) {
! 265: xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT,
! 266: "Name is not from the document dictionnary '%s'",
! 267: (const char *) name);
! 268: }
! 269: }
! 270: }
! 271:
! 272: static void
! 273: xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) {
! 274: xmlDocPtr doc;
! 275: xmlDictPtr dict;
! 276:
! 277: doc = node->doc;
! 278:
! 279: if (node->parent == NULL)
! 280: xmlDebugErr(ctxt, XML_CHECK_NO_PARENT,
! 281: "Node has no parent\n");
! 282: if (node->doc == NULL) {
! 283: xmlDebugErr(ctxt, XML_CHECK_NO_DOC,
! 284: "Node has no doc\n");
! 285: dict = NULL;
! 286: } else {
! 287: dict = doc->dict;
! 288: if ((dict == NULL) && (ctxt->nodict == 0)) {
! 289: #if 0
! 290: /* desactivated right now as it raises too many errors */
! 291: if (doc->type == XML_DOCUMENT_NODE)
! 292: xmlDebugErr(ctxt, XML_CHECK_NO_DICT,
! 293: "Document has no dictionnary\n");
! 294: #endif
! 295: ctxt->nodict = 1;
! 296: }
! 297: if (ctxt->doc == NULL)
! 298: ctxt->doc = doc;
! 299:
! 300: if (ctxt->dict == NULL) {
! 301: ctxt->dict = dict;
! 302: }
! 303: }
! 304: if ((node->parent != NULL) && (node->doc != node->parent->doc) &&
! 305: (!xmlStrEqual(node->name, BAD_CAST "pseudoroot")))
! 306: xmlDebugErr(ctxt, XML_CHECK_WRONG_DOC,
! 307: "Node doc differs from parent's one\n");
! 308: if (node->prev == NULL) {
! 309: if (node->type == XML_ATTRIBUTE_NODE) {
! 310: if ((node->parent != NULL) &&
! 311: (node != (xmlNodePtr) node->parent->properties))
! 312: xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
! 313: "Attr has no prev and not first of attr list\n");
! 314:
! 315: } else if ((node->parent != NULL) && (node->parent->children != node))
! 316: xmlDebugErr(ctxt, XML_CHECK_NO_PREV,
! 317: "Node has no prev and not first of parent list\n");
! 318: } else {
! 319: if (node->prev->next != node)
! 320: xmlDebugErr(ctxt, XML_CHECK_WRONG_PREV,
! 321: "Node prev->next : back link wrong\n");
! 322: }
! 323: if (node->next == NULL) {
! 324: if ((node->parent != NULL) && (node->type != XML_ATTRIBUTE_NODE) &&
! 325: (node->parent->last != node) &&
! 326: (node->parent->type == XML_ELEMENT_NODE))
! 327: xmlDebugErr(ctxt, XML_CHECK_NO_NEXT,
! 328: "Node has no next and not last of parent list\n");
! 329: } else {
! 330: if (node->next->prev != node)
! 331: xmlDebugErr(ctxt, XML_CHECK_WRONG_NEXT,
! 332: "Node next->prev : forward link wrong\n");
! 333: if (node->next->parent != node->parent)
! 334: xmlDebugErr(ctxt, XML_CHECK_WRONG_PARENT,
! 335: "Node next->prev : forward link wrong\n");
! 336: }
! 337: if (node->type == XML_ELEMENT_NODE) {
! 338: xmlNsPtr ns;
! 339:
! 340: ns = node->nsDef;
! 341: while (ns != NULL) {
! 342: xmlCtxtNsCheckScope(ctxt, node, ns);
! 343: ns = ns->next;
! 344: }
! 345: if (node->ns != NULL)
! 346: xmlCtxtNsCheckScope(ctxt, node, node->ns);
! 347: } else if (node->type == XML_ATTRIBUTE_NODE) {
! 348: if (node->ns != NULL)
! 349: xmlCtxtNsCheckScope(ctxt, node, node->ns);
! 350: }
! 351:
! 352: if ((node->type != XML_ELEMENT_NODE) &&
! 353: (node->type != XML_ATTRIBUTE_NODE) &&
! 354: (node->type != XML_ELEMENT_DECL) &&
! 355: (node->type != XML_ATTRIBUTE_DECL) &&
! 356: (node->type != XML_DTD_NODE) &&
! 357: (node->type != XML_ELEMENT_DECL) &&
! 358: (node->type != XML_HTML_DOCUMENT_NODE) &&
! 359: (node->type != XML_DOCUMENT_NODE)) {
! 360: if (node->content != NULL)
! 361: xmlCtxtCheckString(ctxt, (const xmlChar *) node->content);
! 362: }
! 363: switch (node->type) {
! 364: case XML_ELEMENT_NODE:
! 365: case XML_ATTRIBUTE_NODE:
! 366: xmlCtxtCheckName(ctxt, node->name);
! 367: break;
! 368: case XML_TEXT_NODE:
! 369: if ((node->name == xmlStringText) ||
! 370: (node->name == xmlStringTextNoenc))
! 371: break;
! 372: /* some case of entity substitution can lead to this */
! 373: if ((ctxt->dict != NULL) &&
! 374: (node->name == xmlDictLookup(ctxt->dict, BAD_CAST "nbktext",
! 375: 7)))
! 376: break;
! 377:
! 378: xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
! 379: "Text node has wrong name '%s'",
! 380: (const char *) node->name);
! 381: break;
! 382: case XML_COMMENT_NODE:
! 383: if (node->name == xmlStringComment)
! 384: break;
! 385: xmlDebugErr3(ctxt, XML_CHECK_WRONG_NAME,
! 386: "Comment node has wrong name '%s'",
! 387: (const char *) node->name);
! 388: break;
! 389: case XML_PI_NODE:
! 390: xmlCtxtCheckName(ctxt, node->name);
! 391: break;
! 392: case XML_CDATA_SECTION_NODE:
! 393: if (node->name == NULL)
! 394: break;
! 395: xmlDebugErr3(ctxt, XML_CHECK_NAME_NOT_NULL,
! 396: "CData section has non NULL name '%s'",
! 397: (const char *) node->name);
! 398: break;
! 399: case XML_ENTITY_REF_NODE:
! 400: case XML_ENTITY_NODE:
! 401: case XML_DOCUMENT_TYPE_NODE:
! 402: case XML_DOCUMENT_FRAG_NODE:
! 403: case XML_NOTATION_NODE:
! 404: case XML_DTD_NODE:
! 405: case XML_ELEMENT_DECL:
! 406: case XML_ATTRIBUTE_DECL:
! 407: case XML_ENTITY_DECL:
! 408: case XML_NAMESPACE_DECL:
! 409: case XML_XINCLUDE_START:
! 410: case XML_XINCLUDE_END:
! 411: #ifdef LIBXML_DOCB_ENABLED
! 412: case XML_DOCB_DOCUMENT_NODE:
! 413: #endif
! 414: case XML_DOCUMENT_NODE:
! 415: case XML_HTML_DOCUMENT_NODE:
! 416: break;
! 417: }
! 418: }
! 419:
! 420: static void
! 421: xmlCtxtDumpString(xmlDebugCtxtPtr ctxt, const xmlChar * str)
! 422: {
! 423: int i;
! 424:
! 425: if (ctxt->check) {
! 426: return;
! 427: }
! 428: /* TODO: check UTF8 content of the string */
! 429: if (str == NULL) {
! 430: fprintf(ctxt->output, "(NULL)");
! 431: return;
! 432: }
! 433: for (i = 0; i < 40; i++)
! 434: if (str[i] == 0)
! 435: return;
! 436: else if (IS_BLANK_CH(str[i]))
! 437: fputc(' ', ctxt->output);
! 438: else if (str[i] >= 0x80)
! 439: fprintf(ctxt->output, "#%X", str[i]);
! 440: else
! 441: fputc(str[i], ctxt->output);
! 442: fprintf(ctxt->output, "...");
! 443: }
! 444:
! 445: static void
! 446: xmlCtxtDumpDtdNode(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
! 447: {
! 448: xmlCtxtDumpSpaces(ctxt);
! 449:
! 450: if (dtd == NULL) {
! 451: if (!ctxt->check)
! 452: fprintf(ctxt->output, "DTD node is NULL\n");
! 453: return;
! 454: }
! 455:
! 456: if (dtd->type != XML_DTD_NODE) {
! 457: xmlDebugErr(ctxt, XML_CHECK_NOT_DTD,
! 458: "Node is not a DTD");
! 459: return;
! 460: }
! 461: if (!ctxt->check) {
! 462: if (dtd->name != NULL)
! 463: fprintf(ctxt->output, "DTD(%s)", (char *) dtd->name);
! 464: else
! 465: fprintf(ctxt->output, "DTD");
! 466: if (dtd->ExternalID != NULL)
! 467: fprintf(ctxt->output, ", PUBLIC %s", (char *) dtd->ExternalID);
! 468: if (dtd->SystemID != NULL)
! 469: fprintf(ctxt->output, ", SYSTEM %s", (char *) dtd->SystemID);
! 470: fprintf(ctxt->output, "\n");
! 471: }
! 472: /*
! 473: * Do a bit of checking
! 474: */
! 475: xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) dtd);
! 476: }
! 477:
! 478: static void
! 479: xmlCtxtDumpAttrDecl(xmlDebugCtxtPtr ctxt, xmlAttributePtr attr)
! 480: {
! 481: xmlCtxtDumpSpaces(ctxt);
! 482:
! 483: if (attr == NULL) {
! 484: if (!ctxt->check)
! 485: fprintf(ctxt->output, "Attribute declaration is NULL\n");
! 486: return;
! 487: }
! 488: if (attr->type != XML_ATTRIBUTE_DECL) {
! 489: xmlDebugErr(ctxt, XML_CHECK_NOT_ATTR_DECL,
! 490: "Node is not an attribute declaration");
! 491: return;
! 492: }
! 493: if (attr->name != NULL) {
! 494: if (!ctxt->check)
! 495: fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name);
! 496: } else
! 497: xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
! 498: "Node attribute declaration has no name");
! 499: if (attr->elem != NULL) {
! 500: if (!ctxt->check)
! 501: fprintf(ctxt->output, " for %s", (char *) attr->elem);
! 502: } else
! 503: xmlDebugErr(ctxt, XML_CHECK_NO_ELEM,
! 504: "Node attribute declaration has no element name");
! 505: if (!ctxt->check) {
! 506: switch (attr->atype) {
! 507: case XML_ATTRIBUTE_CDATA:
! 508: fprintf(ctxt->output, " CDATA");
! 509: break;
! 510: case XML_ATTRIBUTE_ID:
! 511: fprintf(ctxt->output, " ID");
! 512: break;
! 513: case XML_ATTRIBUTE_IDREF:
! 514: fprintf(ctxt->output, " IDREF");
! 515: break;
! 516: case XML_ATTRIBUTE_IDREFS:
! 517: fprintf(ctxt->output, " IDREFS");
! 518: break;
! 519: case XML_ATTRIBUTE_ENTITY:
! 520: fprintf(ctxt->output, " ENTITY");
! 521: break;
! 522: case XML_ATTRIBUTE_ENTITIES:
! 523: fprintf(ctxt->output, " ENTITIES");
! 524: break;
! 525: case XML_ATTRIBUTE_NMTOKEN:
! 526: fprintf(ctxt->output, " NMTOKEN");
! 527: break;
! 528: case XML_ATTRIBUTE_NMTOKENS:
! 529: fprintf(ctxt->output, " NMTOKENS");
! 530: break;
! 531: case XML_ATTRIBUTE_ENUMERATION:
! 532: fprintf(ctxt->output, " ENUMERATION");
! 533: break;
! 534: case XML_ATTRIBUTE_NOTATION:
! 535: fprintf(ctxt->output, " NOTATION ");
! 536: break;
! 537: }
! 538: if (attr->tree != NULL) {
! 539: int indx;
! 540: xmlEnumerationPtr cur = attr->tree;
! 541:
! 542: for (indx = 0; indx < 5; indx++) {
! 543: if (indx != 0)
! 544: fprintf(ctxt->output, "|%s", (char *) cur->name);
! 545: else
! 546: fprintf(ctxt->output, " (%s", (char *) cur->name);
! 547: cur = cur->next;
! 548: if (cur == NULL)
! 549: break;
! 550: }
! 551: if (cur == NULL)
! 552: fprintf(ctxt->output, ")");
! 553: else
! 554: fprintf(ctxt->output, "...)");
! 555: }
! 556: switch (attr->def) {
! 557: case XML_ATTRIBUTE_NONE:
! 558: break;
! 559: case XML_ATTRIBUTE_REQUIRED:
! 560: fprintf(ctxt->output, " REQUIRED");
! 561: break;
! 562: case XML_ATTRIBUTE_IMPLIED:
! 563: fprintf(ctxt->output, " IMPLIED");
! 564: break;
! 565: case XML_ATTRIBUTE_FIXED:
! 566: fprintf(ctxt->output, " FIXED");
! 567: break;
! 568: }
! 569: if (attr->defaultValue != NULL) {
! 570: fprintf(ctxt->output, "\"");
! 571: xmlCtxtDumpString(ctxt, attr->defaultValue);
! 572: fprintf(ctxt->output, "\"");
! 573: }
! 574: fprintf(ctxt->output, "\n");
! 575: }
! 576:
! 577: /*
! 578: * Do a bit of checking
! 579: */
! 580: xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
! 581: }
! 582:
! 583: static void
! 584: xmlCtxtDumpElemDecl(xmlDebugCtxtPtr ctxt, xmlElementPtr elem)
! 585: {
! 586: xmlCtxtDumpSpaces(ctxt);
! 587:
! 588: if (elem == NULL) {
! 589: if (!ctxt->check)
! 590: fprintf(ctxt->output, "Element declaration is NULL\n");
! 591: return;
! 592: }
! 593: if (elem->type != XML_ELEMENT_DECL) {
! 594: xmlDebugErr(ctxt, XML_CHECK_NOT_ELEM_DECL,
! 595: "Node is not an element declaration");
! 596: return;
! 597: }
! 598: if (elem->name != NULL) {
! 599: if (!ctxt->check) {
! 600: fprintf(ctxt->output, "ELEMDECL(");
! 601: xmlCtxtDumpString(ctxt, elem->name);
! 602: fprintf(ctxt->output, ")");
! 603: }
! 604: } else
! 605: xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
! 606: "Element declaration has no name");
! 607: if (!ctxt->check) {
! 608: switch (elem->etype) {
! 609: case XML_ELEMENT_TYPE_UNDEFINED:
! 610: fprintf(ctxt->output, ", UNDEFINED");
! 611: break;
! 612: case XML_ELEMENT_TYPE_EMPTY:
! 613: fprintf(ctxt->output, ", EMPTY");
! 614: break;
! 615: case XML_ELEMENT_TYPE_ANY:
! 616: fprintf(ctxt->output, ", ANY");
! 617: break;
! 618: case XML_ELEMENT_TYPE_MIXED:
! 619: fprintf(ctxt->output, ", MIXED ");
! 620: break;
! 621: case XML_ELEMENT_TYPE_ELEMENT:
! 622: fprintf(ctxt->output, ", MIXED ");
! 623: break;
! 624: }
! 625: if ((elem->type != XML_ELEMENT_NODE) && (elem->content != NULL)) {
! 626: char buf[5001];
! 627:
! 628: buf[0] = 0;
! 629: xmlSnprintfElementContent(buf, 5000, elem->content, 1);
! 630: buf[5000] = 0;
! 631: fprintf(ctxt->output, "%s", buf);
! 632: }
! 633: fprintf(ctxt->output, "\n");
! 634: }
! 635:
! 636: /*
! 637: * Do a bit of checking
! 638: */
! 639: xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) elem);
! 640: }
! 641:
! 642: static void
! 643: xmlCtxtDumpEntityDecl(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
! 644: {
! 645: xmlCtxtDumpSpaces(ctxt);
! 646:
! 647: if (ent == NULL) {
! 648: if (!ctxt->check)
! 649: fprintf(ctxt->output, "Entity declaration is NULL\n");
! 650: return;
! 651: }
! 652: if (ent->type != XML_ENTITY_DECL) {
! 653: xmlDebugErr(ctxt, XML_CHECK_NOT_ENTITY_DECL,
! 654: "Node is not an entity declaration");
! 655: return;
! 656: }
! 657: if (ent->name != NULL) {
! 658: if (!ctxt->check) {
! 659: fprintf(ctxt->output, "ENTITYDECL(");
! 660: xmlCtxtDumpString(ctxt, ent->name);
! 661: fprintf(ctxt->output, ")");
! 662: }
! 663: } else
! 664: xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
! 665: "Entity declaration has no name");
! 666: if (!ctxt->check) {
! 667: switch (ent->etype) {
! 668: case XML_INTERNAL_GENERAL_ENTITY:
! 669: fprintf(ctxt->output, ", internal\n");
! 670: break;
! 671: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
! 672: fprintf(ctxt->output, ", external parsed\n");
! 673: break;
! 674: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
! 675: fprintf(ctxt->output, ", unparsed\n");
! 676: break;
! 677: case XML_INTERNAL_PARAMETER_ENTITY:
! 678: fprintf(ctxt->output, ", parameter\n");
! 679: break;
! 680: case XML_EXTERNAL_PARAMETER_ENTITY:
! 681: fprintf(ctxt->output, ", external parameter\n");
! 682: break;
! 683: case XML_INTERNAL_PREDEFINED_ENTITY:
! 684: fprintf(ctxt->output, ", predefined\n");
! 685: break;
! 686: }
! 687: if (ent->ExternalID) {
! 688: xmlCtxtDumpSpaces(ctxt);
! 689: fprintf(ctxt->output, " ExternalID=%s\n",
! 690: (char *) ent->ExternalID);
! 691: }
! 692: if (ent->SystemID) {
! 693: xmlCtxtDumpSpaces(ctxt);
! 694: fprintf(ctxt->output, " SystemID=%s\n",
! 695: (char *) ent->SystemID);
! 696: }
! 697: if (ent->URI != NULL) {
! 698: xmlCtxtDumpSpaces(ctxt);
! 699: fprintf(ctxt->output, " URI=%s\n", (char *) ent->URI);
! 700: }
! 701: if (ent->content) {
! 702: xmlCtxtDumpSpaces(ctxt);
! 703: fprintf(ctxt->output, " content=");
! 704: xmlCtxtDumpString(ctxt, ent->content);
! 705: fprintf(ctxt->output, "\n");
! 706: }
! 707: }
! 708:
! 709: /*
! 710: * Do a bit of checking
! 711: */
! 712: xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) ent);
! 713: }
! 714:
! 715: static void
! 716: xmlCtxtDumpNamespace(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
! 717: {
! 718: xmlCtxtDumpSpaces(ctxt);
! 719:
! 720: if (ns == NULL) {
! 721: if (!ctxt->check)
! 722: fprintf(ctxt->output, "namespace node is NULL\n");
! 723: return;
! 724: }
! 725: if (ns->type != XML_NAMESPACE_DECL) {
! 726: xmlDebugErr(ctxt, XML_CHECK_NOT_NS_DECL,
! 727: "Node is not a namespace declaration");
! 728: return;
! 729: }
! 730: if (ns->href == NULL) {
! 731: if (ns->prefix != NULL)
! 732: xmlDebugErr3(ctxt, XML_CHECK_NO_HREF,
! 733: "Incomplete namespace %s href=NULL\n",
! 734: (char *) ns->prefix);
! 735: else
! 736: xmlDebugErr(ctxt, XML_CHECK_NO_HREF,
! 737: "Incomplete default namespace href=NULL\n");
! 738: } else {
! 739: if (!ctxt->check) {
! 740: if (ns->prefix != NULL)
! 741: fprintf(ctxt->output, "namespace %s href=",
! 742: (char *) ns->prefix);
! 743: else
! 744: fprintf(ctxt->output, "default namespace href=");
! 745:
! 746: xmlCtxtDumpString(ctxt, ns->href);
! 747: fprintf(ctxt->output, "\n");
! 748: }
! 749: }
! 750: }
! 751:
! 752: static void
! 753: xmlCtxtDumpNamespaceList(xmlDebugCtxtPtr ctxt, xmlNsPtr ns)
! 754: {
! 755: while (ns != NULL) {
! 756: xmlCtxtDumpNamespace(ctxt, ns);
! 757: ns = ns->next;
! 758: }
! 759: }
! 760:
! 761: static void
! 762: xmlCtxtDumpEntity(xmlDebugCtxtPtr ctxt, xmlEntityPtr ent)
! 763: {
! 764: xmlCtxtDumpSpaces(ctxt);
! 765:
! 766: if (ent == NULL) {
! 767: if (!ctxt->check)
! 768: fprintf(ctxt->output, "Entity is NULL\n");
! 769: return;
! 770: }
! 771: if (!ctxt->check) {
! 772: switch (ent->etype) {
! 773: case XML_INTERNAL_GENERAL_ENTITY:
! 774: fprintf(ctxt->output, "INTERNAL_GENERAL_ENTITY ");
! 775: break;
! 776: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
! 777: fprintf(ctxt->output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
! 778: break;
! 779: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
! 780: fprintf(ctxt->output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
! 781: break;
! 782: case XML_INTERNAL_PARAMETER_ENTITY:
! 783: fprintf(ctxt->output, "INTERNAL_PARAMETER_ENTITY ");
! 784: break;
! 785: case XML_EXTERNAL_PARAMETER_ENTITY:
! 786: fprintf(ctxt->output, "EXTERNAL_PARAMETER_ENTITY ");
! 787: break;
! 788: default:
! 789: fprintf(ctxt->output, "ENTITY_%d ! ", (int) ent->etype);
! 790: }
! 791: fprintf(ctxt->output, "%s\n", ent->name);
! 792: if (ent->ExternalID) {
! 793: xmlCtxtDumpSpaces(ctxt);
! 794: fprintf(ctxt->output, "ExternalID=%s\n",
! 795: (char *) ent->ExternalID);
! 796: }
! 797: if (ent->SystemID) {
! 798: xmlCtxtDumpSpaces(ctxt);
! 799: fprintf(ctxt->output, "SystemID=%s\n", (char *) ent->SystemID);
! 800: }
! 801: if (ent->URI) {
! 802: xmlCtxtDumpSpaces(ctxt);
! 803: fprintf(ctxt->output, "URI=%s\n", (char *) ent->URI);
! 804: }
! 805: if (ent->content) {
! 806: xmlCtxtDumpSpaces(ctxt);
! 807: fprintf(ctxt->output, "content=");
! 808: xmlCtxtDumpString(ctxt, ent->content);
! 809: fprintf(ctxt->output, "\n");
! 810: }
! 811: }
! 812: }
! 813:
! 814: /**
! 815: * xmlCtxtDumpAttr:
! 816: * @output: the FILE * for the output
! 817: * @attr: the attribute
! 818: * @depth: the indentation level.
! 819: *
! 820: * Dumps debug information for the attribute
! 821: */
! 822: static void
! 823: xmlCtxtDumpAttr(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
! 824: {
! 825: xmlCtxtDumpSpaces(ctxt);
! 826:
! 827: if (attr == NULL) {
! 828: if (!ctxt->check)
! 829: fprintf(ctxt->output, "Attr is NULL");
! 830: return;
! 831: }
! 832: if (!ctxt->check) {
! 833: fprintf(ctxt->output, "ATTRIBUTE ");
! 834: xmlCtxtDumpString(ctxt, attr->name);
! 835: fprintf(ctxt->output, "\n");
! 836: if (attr->children != NULL) {
! 837: ctxt->depth++;
! 838: xmlCtxtDumpNodeList(ctxt, attr->children);
! 839: ctxt->depth--;
! 840: }
! 841: }
! 842: if (attr->name == NULL)
! 843: xmlDebugErr(ctxt, XML_CHECK_NO_NAME,
! 844: "Attribute has no name");
! 845:
! 846: /*
! 847: * Do a bit of checking
! 848: */
! 849: xmlCtxtGenericNodeCheck(ctxt, (xmlNodePtr) attr);
! 850: }
! 851:
! 852: /**
! 853: * xmlCtxtDumpAttrList:
! 854: * @output: the FILE * for the output
! 855: * @attr: the attribute list
! 856: * @depth: the indentation level.
! 857: *
! 858: * Dumps debug information for the attribute list
! 859: */
! 860: static void
! 861: xmlCtxtDumpAttrList(xmlDebugCtxtPtr ctxt, xmlAttrPtr attr)
! 862: {
! 863: while (attr != NULL) {
! 864: xmlCtxtDumpAttr(ctxt, attr);
! 865: attr = attr->next;
! 866: }
! 867: }
! 868:
! 869: /**
! 870: * xmlCtxtDumpOneNode:
! 871: * @output: the FILE * for the output
! 872: * @node: the node
! 873: * @depth: the indentation level.
! 874: *
! 875: * Dumps debug information for the element node, it is not recursive
! 876: */
! 877: static void
! 878: xmlCtxtDumpOneNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
! 879: {
! 880: if (node == NULL) {
! 881: if (!ctxt->check) {
! 882: xmlCtxtDumpSpaces(ctxt);
! 883: fprintf(ctxt->output, "node is NULL\n");
! 884: }
! 885: return;
! 886: }
! 887: ctxt->node = node;
! 888:
! 889: switch (node->type) {
! 890: case XML_ELEMENT_NODE:
! 891: if (!ctxt->check) {
! 892: xmlCtxtDumpSpaces(ctxt);
! 893: fprintf(ctxt->output, "ELEMENT ");
! 894: if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
! 895: xmlCtxtDumpString(ctxt, node->ns->prefix);
! 896: fprintf(ctxt->output, ":");
! 897: }
! 898: xmlCtxtDumpString(ctxt, node->name);
! 899: fprintf(ctxt->output, "\n");
! 900: }
! 901: break;
! 902: case XML_ATTRIBUTE_NODE:
! 903: if (!ctxt->check)
! 904: xmlCtxtDumpSpaces(ctxt);
! 905: fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
! 906: xmlCtxtGenericNodeCheck(ctxt, node);
! 907: return;
! 908: case XML_TEXT_NODE:
! 909: if (!ctxt->check) {
! 910: xmlCtxtDumpSpaces(ctxt);
! 911: if (node->name == (const xmlChar *) xmlStringTextNoenc)
! 912: fprintf(ctxt->output, "TEXT no enc");
! 913: else
! 914: fprintf(ctxt->output, "TEXT");
! 915: if (ctxt->options & DUMP_TEXT_TYPE) {
! 916: if (node->content == (xmlChar *) &(node->properties))
! 917: fprintf(ctxt->output, " compact\n");
! 918: else if (xmlDictOwns(ctxt->dict, node->content) == 1)
! 919: fprintf(ctxt->output, " interned\n");
! 920: else
! 921: fprintf(ctxt->output, "\n");
! 922: } else
! 923: fprintf(ctxt->output, "\n");
! 924: }
! 925: break;
! 926: case XML_CDATA_SECTION_NODE:
! 927: if (!ctxt->check) {
! 928: xmlCtxtDumpSpaces(ctxt);
! 929: fprintf(ctxt->output, "CDATA_SECTION\n");
! 930: }
! 931: break;
! 932: case XML_ENTITY_REF_NODE:
! 933: if (!ctxt->check) {
! 934: xmlCtxtDumpSpaces(ctxt);
! 935: fprintf(ctxt->output, "ENTITY_REF(%s)\n",
! 936: (char *) node->name);
! 937: }
! 938: break;
! 939: case XML_ENTITY_NODE:
! 940: if (!ctxt->check) {
! 941: xmlCtxtDumpSpaces(ctxt);
! 942: fprintf(ctxt->output, "ENTITY\n");
! 943: }
! 944: break;
! 945: case XML_PI_NODE:
! 946: if (!ctxt->check) {
! 947: xmlCtxtDumpSpaces(ctxt);
! 948: fprintf(ctxt->output, "PI %s\n", (char *) node->name);
! 949: }
! 950: break;
! 951: case XML_COMMENT_NODE:
! 952: if (!ctxt->check) {
! 953: xmlCtxtDumpSpaces(ctxt);
! 954: fprintf(ctxt->output, "COMMENT\n");
! 955: }
! 956: break;
! 957: case XML_DOCUMENT_NODE:
! 958: case XML_HTML_DOCUMENT_NODE:
! 959: if (!ctxt->check) {
! 960: xmlCtxtDumpSpaces(ctxt);
! 961: }
! 962: fprintf(ctxt->output, "Error, DOCUMENT found here\n");
! 963: xmlCtxtGenericNodeCheck(ctxt, node);
! 964: return;
! 965: case XML_DOCUMENT_TYPE_NODE:
! 966: if (!ctxt->check) {
! 967: xmlCtxtDumpSpaces(ctxt);
! 968: fprintf(ctxt->output, "DOCUMENT_TYPE\n");
! 969: }
! 970: break;
! 971: case XML_DOCUMENT_FRAG_NODE:
! 972: if (!ctxt->check) {
! 973: xmlCtxtDumpSpaces(ctxt);
! 974: fprintf(ctxt->output, "DOCUMENT_FRAG\n");
! 975: }
! 976: break;
! 977: case XML_NOTATION_NODE:
! 978: if (!ctxt->check) {
! 979: xmlCtxtDumpSpaces(ctxt);
! 980: fprintf(ctxt->output, "NOTATION\n");
! 981: }
! 982: break;
! 983: case XML_DTD_NODE:
! 984: xmlCtxtDumpDtdNode(ctxt, (xmlDtdPtr) node);
! 985: return;
! 986: case XML_ELEMENT_DECL:
! 987: xmlCtxtDumpElemDecl(ctxt, (xmlElementPtr) node);
! 988: return;
! 989: case XML_ATTRIBUTE_DECL:
! 990: xmlCtxtDumpAttrDecl(ctxt, (xmlAttributePtr) node);
! 991: return;
! 992: case XML_ENTITY_DECL:
! 993: xmlCtxtDumpEntityDecl(ctxt, (xmlEntityPtr) node);
! 994: return;
! 995: case XML_NAMESPACE_DECL:
! 996: xmlCtxtDumpNamespace(ctxt, (xmlNsPtr) node);
! 997: return;
! 998: case XML_XINCLUDE_START:
! 999: if (!ctxt->check) {
! 1000: xmlCtxtDumpSpaces(ctxt);
! 1001: fprintf(ctxt->output, "INCLUDE START\n");
! 1002: }
! 1003: return;
! 1004: case XML_XINCLUDE_END:
! 1005: if (!ctxt->check) {
! 1006: xmlCtxtDumpSpaces(ctxt);
! 1007: fprintf(ctxt->output, "INCLUDE END\n");
! 1008: }
! 1009: return;
! 1010: default:
! 1011: if (!ctxt->check)
! 1012: xmlCtxtDumpSpaces(ctxt);
! 1013: xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
! 1014: "Unknown node type %d\n", node->type);
! 1015: return;
! 1016: }
! 1017: if (node->doc == NULL) {
! 1018: if (!ctxt->check) {
! 1019: xmlCtxtDumpSpaces(ctxt);
! 1020: }
! 1021: fprintf(ctxt->output, "PBM: doc == NULL !!!\n");
! 1022: }
! 1023: ctxt->depth++;
! 1024: if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
! 1025: xmlCtxtDumpNamespaceList(ctxt, node->nsDef);
! 1026: if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
! 1027: xmlCtxtDumpAttrList(ctxt, node->properties);
! 1028: if (node->type != XML_ENTITY_REF_NODE) {
! 1029: if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
! 1030: if (!ctxt->check) {
! 1031: xmlCtxtDumpSpaces(ctxt);
! 1032: fprintf(ctxt->output, "content=");
! 1033: xmlCtxtDumpString(ctxt, node->content);
! 1034: fprintf(ctxt->output, "\n");
! 1035: }
! 1036: }
! 1037: } else {
! 1038: xmlEntityPtr ent;
! 1039:
! 1040: ent = xmlGetDocEntity(node->doc, node->name);
! 1041: if (ent != NULL)
! 1042: xmlCtxtDumpEntity(ctxt, ent);
! 1043: }
! 1044: ctxt->depth--;
! 1045:
! 1046: /*
! 1047: * Do a bit of checking
! 1048: */
! 1049: xmlCtxtGenericNodeCheck(ctxt, node);
! 1050: }
! 1051:
! 1052: /**
! 1053: * xmlCtxtDumpNode:
! 1054: * @output: the FILE * for the output
! 1055: * @node: the node
! 1056: * @depth: the indentation level.
! 1057: *
! 1058: * Dumps debug information for the element node, it is recursive
! 1059: */
! 1060: static void
! 1061: xmlCtxtDumpNode(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
! 1062: {
! 1063: if (node == NULL) {
! 1064: if (!ctxt->check) {
! 1065: xmlCtxtDumpSpaces(ctxt);
! 1066: fprintf(ctxt->output, "node is NULL\n");
! 1067: }
! 1068: return;
! 1069: }
! 1070: xmlCtxtDumpOneNode(ctxt, node);
! 1071: if ((node->type != XML_NAMESPACE_DECL) &&
! 1072: (node->children != NULL) && (node->type != XML_ENTITY_REF_NODE)) {
! 1073: ctxt->depth++;
! 1074: xmlCtxtDumpNodeList(ctxt, node->children);
! 1075: ctxt->depth--;
! 1076: }
! 1077: }
! 1078:
! 1079: /**
! 1080: * xmlCtxtDumpNodeList:
! 1081: * @output: the FILE * for the output
! 1082: * @node: the node list
! 1083: * @depth: the indentation level.
! 1084: *
! 1085: * Dumps debug information for the list of element node, it is recursive
! 1086: */
! 1087: static void
! 1088: xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node)
! 1089: {
! 1090: while (node != NULL) {
! 1091: xmlCtxtDumpNode(ctxt, node);
! 1092: node = node->next;
! 1093: }
! 1094: }
! 1095:
! 1096: static void
! 1097: xmlCtxtDumpDocHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
! 1098: {
! 1099: if (doc == NULL) {
! 1100: if (!ctxt->check)
! 1101: fprintf(ctxt->output, "DOCUMENT == NULL !\n");
! 1102: return;
! 1103: }
! 1104: ctxt->node = (xmlNodePtr) doc;
! 1105:
! 1106: switch (doc->type) {
! 1107: case XML_ELEMENT_NODE:
! 1108: xmlDebugErr(ctxt, XML_CHECK_FOUND_ELEMENT,
! 1109: "Misplaced ELEMENT node\n");
! 1110: break;
! 1111: case XML_ATTRIBUTE_NODE:
! 1112: xmlDebugErr(ctxt, XML_CHECK_FOUND_ATTRIBUTE,
! 1113: "Misplaced ATTRIBUTE node\n");
! 1114: break;
! 1115: case XML_TEXT_NODE:
! 1116: xmlDebugErr(ctxt, XML_CHECK_FOUND_TEXT,
! 1117: "Misplaced TEXT node\n");
! 1118: break;
! 1119: case XML_CDATA_SECTION_NODE:
! 1120: xmlDebugErr(ctxt, XML_CHECK_FOUND_CDATA,
! 1121: "Misplaced CDATA node\n");
! 1122: break;
! 1123: case XML_ENTITY_REF_NODE:
! 1124: xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITYREF,
! 1125: "Misplaced ENTITYREF node\n");
! 1126: break;
! 1127: case XML_ENTITY_NODE:
! 1128: xmlDebugErr(ctxt, XML_CHECK_FOUND_ENTITY,
! 1129: "Misplaced ENTITY node\n");
! 1130: break;
! 1131: case XML_PI_NODE:
! 1132: xmlDebugErr(ctxt, XML_CHECK_FOUND_PI,
! 1133: "Misplaced PI node\n");
! 1134: break;
! 1135: case XML_COMMENT_NODE:
! 1136: xmlDebugErr(ctxt, XML_CHECK_FOUND_COMMENT,
! 1137: "Misplaced COMMENT node\n");
! 1138: break;
! 1139: case XML_DOCUMENT_NODE:
! 1140: if (!ctxt->check)
! 1141: fprintf(ctxt->output, "DOCUMENT\n");
! 1142: break;
! 1143: case XML_HTML_DOCUMENT_NODE:
! 1144: if (!ctxt->check)
! 1145: fprintf(ctxt->output, "HTML DOCUMENT\n");
! 1146: break;
! 1147: case XML_DOCUMENT_TYPE_NODE:
! 1148: xmlDebugErr(ctxt, XML_CHECK_FOUND_DOCTYPE,
! 1149: "Misplaced DOCTYPE node\n");
! 1150: break;
! 1151: case XML_DOCUMENT_FRAG_NODE:
! 1152: xmlDebugErr(ctxt, XML_CHECK_FOUND_FRAGMENT,
! 1153: "Misplaced FRAGMENT node\n");
! 1154: break;
! 1155: case XML_NOTATION_NODE:
! 1156: xmlDebugErr(ctxt, XML_CHECK_FOUND_NOTATION,
! 1157: "Misplaced NOTATION node\n");
! 1158: break;
! 1159: default:
! 1160: xmlDebugErr2(ctxt, XML_CHECK_UNKNOWN_NODE,
! 1161: "Unknown node type %d\n", doc->type);
! 1162: }
! 1163: }
! 1164:
! 1165: /**
! 1166: * xmlCtxtDumpDocumentHead:
! 1167: * @output: the FILE * for the output
! 1168: * @doc: the document
! 1169: *
! 1170: * Dumps debug information cncerning the document, not recursive
! 1171: */
! 1172: static void
! 1173: xmlCtxtDumpDocumentHead(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
! 1174: {
! 1175: if (doc == NULL) return;
! 1176: xmlCtxtDumpDocHead(ctxt, doc);
! 1177: if (!ctxt->check) {
! 1178: if (doc->name != NULL) {
! 1179: fprintf(ctxt->output, "name=");
! 1180: xmlCtxtDumpString(ctxt, BAD_CAST doc->name);
! 1181: fprintf(ctxt->output, "\n");
! 1182: }
! 1183: if (doc->version != NULL) {
! 1184: fprintf(ctxt->output, "version=");
! 1185: xmlCtxtDumpString(ctxt, doc->version);
! 1186: fprintf(ctxt->output, "\n");
! 1187: }
! 1188: if (doc->encoding != NULL) {
! 1189: fprintf(ctxt->output, "encoding=");
! 1190: xmlCtxtDumpString(ctxt, doc->encoding);
! 1191: fprintf(ctxt->output, "\n");
! 1192: }
! 1193: if (doc->URL != NULL) {
! 1194: fprintf(ctxt->output, "URL=");
! 1195: xmlCtxtDumpString(ctxt, doc->URL);
! 1196: fprintf(ctxt->output, "\n");
! 1197: }
! 1198: if (doc->standalone)
! 1199: fprintf(ctxt->output, "standalone=true\n");
! 1200: }
! 1201: if (doc->oldNs != NULL)
! 1202: xmlCtxtDumpNamespaceList(ctxt, doc->oldNs);
! 1203: }
! 1204:
! 1205: /**
! 1206: * xmlCtxtDumpDocument:
! 1207: * @output: the FILE * for the output
! 1208: * @doc: the document
! 1209: *
! 1210: * Dumps debug information for the document, it's recursive
! 1211: */
! 1212: static void
! 1213: xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
! 1214: {
! 1215: if (doc == NULL) {
! 1216: if (!ctxt->check)
! 1217: fprintf(ctxt->output, "DOCUMENT == NULL !\n");
! 1218: return;
! 1219: }
! 1220: xmlCtxtDumpDocumentHead(ctxt, doc);
! 1221: if (((doc->type == XML_DOCUMENT_NODE) ||
! 1222: (doc->type == XML_HTML_DOCUMENT_NODE))
! 1223: && (doc->children != NULL)) {
! 1224: ctxt->depth++;
! 1225: xmlCtxtDumpNodeList(ctxt, doc->children);
! 1226: ctxt->depth--;
! 1227: }
! 1228: }
! 1229:
! 1230: static void
! 1231: xmlCtxtDumpEntityCallback(xmlEntityPtr cur, xmlDebugCtxtPtr ctxt)
! 1232: {
! 1233: if (cur == NULL) {
! 1234: if (!ctxt->check)
! 1235: fprintf(ctxt->output, "Entity is NULL");
! 1236: return;
! 1237: }
! 1238: if (!ctxt->check) {
! 1239: fprintf(ctxt->output, "%s : ", (char *) cur->name);
! 1240: switch (cur->etype) {
! 1241: case XML_INTERNAL_GENERAL_ENTITY:
! 1242: fprintf(ctxt->output, "INTERNAL GENERAL, ");
! 1243: break;
! 1244: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
! 1245: fprintf(ctxt->output, "EXTERNAL PARSED, ");
! 1246: break;
! 1247: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
! 1248: fprintf(ctxt->output, "EXTERNAL UNPARSED, ");
! 1249: break;
! 1250: case XML_INTERNAL_PARAMETER_ENTITY:
! 1251: fprintf(ctxt->output, "INTERNAL PARAMETER, ");
! 1252: break;
! 1253: case XML_EXTERNAL_PARAMETER_ENTITY:
! 1254: fprintf(ctxt->output, "EXTERNAL PARAMETER, ");
! 1255: break;
! 1256: default:
! 1257: xmlDebugErr2(ctxt, XML_CHECK_ENTITY_TYPE,
! 1258: "Unknown entity type %d\n", cur->etype);
! 1259: }
! 1260: if (cur->ExternalID != NULL)
! 1261: fprintf(ctxt->output, "ID \"%s\"", (char *) cur->ExternalID);
! 1262: if (cur->SystemID != NULL)
! 1263: fprintf(ctxt->output, "SYSTEM \"%s\"", (char *) cur->SystemID);
! 1264: if (cur->orig != NULL)
! 1265: fprintf(ctxt->output, "\n orig \"%s\"", (char *) cur->orig);
! 1266: if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL))
! 1267: fprintf(ctxt->output, "\n content \"%s\"",
! 1268: (char *) cur->content);
! 1269: fprintf(ctxt->output, "\n");
! 1270: }
! 1271: }
! 1272:
! 1273: /**
! 1274: * xmlCtxtDumpEntities:
! 1275: * @output: the FILE * for the output
! 1276: * @doc: the document
! 1277: *
! 1278: * Dumps debug information for all the entities in use by the document
! 1279: */
! 1280: static void
! 1281: xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc)
! 1282: {
! 1283: if (doc == NULL) return;
! 1284: xmlCtxtDumpDocHead(ctxt, doc);
! 1285: if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
! 1286: xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
! 1287: doc->intSubset->entities;
! 1288:
! 1289: if (!ctxt->check)
! 1290: fprintf(ctxt->output, "Entities in internal subset\n");
! 1291: xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback,
! 1292: ctxt);
! 1293: } else
! 1294: fprintf(ctxt->output, "No entities in internal subset\n");
! 1295: if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
! 1296: xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
! 1297: doc->extSubset->entities;
! 1298:
! 1299: if (!ctxt->check)
! 1300: fprintf(ctxt->output, "Entities in external subset\n");
! 1301: xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback,
! 1302: ctxt);
! 1303: } else if (!ctxt->check)
! 1304: fprintf(ctxt->output, "No entities in external subset\n");
! 1305: }
! 1306:
! 1307: /**
! 1308: * xmlCtxtDumpDTD:
! 1309: * @output: the FILE * for the output
! 1310: * @dtd: the DTD
! 1311: *
! 1312: * Dumps debug information for the DTD
! 1313: */
! 1314: static void
! 1315: xmlCtxtDumpDTD(xmlDebugCtxtPtr ctxt, xmlDtdPtr dtd)
! 1316: {
! 1317: if (dtd == NULL) {
! 1318: if (!ctxt->check)
! 1319: fprintf(ctxt->output, "DTD is NULL\n");
! 1320: return;
! 1321: }
! 1322: xmlCtxtDumpDtdNode(ctxt, dtd);
! 1323: if (dtd->children == NULL)
! 1324: fprintf(ctxt->output, " DTD is empty\n");
! 1325: else {
! 1326: ctxt->depth++;
! 1327: xmlCtxtDumpNodeList(ctxt, dtd->children);
! 1328: ctxt->depth--;
! 1329: }
! 1330: }
! 1331:
! 1332: /************************************************************************
! 1333: * *
! 1334: * Public entry points for dump *
! 1335: * *
! 1336: ************************************************************************/
! 1337:
! 1338: /**
! 1339: * xmlDebugDumpString:
! 1340: * @output: the FILE * for the output
! 1341: * @str: the string
! 1342: *
! 1343: * Dumps informations about the string, shorten it if necessary
! 1344: */
! 1345: void
! 1346: xmlDebugDumpString(FILE * output, const xmlChar * str)
! 1347: {
! 1348: int i;
! 1349:
! 1350: if (output == NULL)
! 1351: output = stdout;
! 1352: if (str == NULL) {
! 1353: fprintf(output, "(NULL)");
! 1354: return;
! 1355: }
! 1356: for (i = 0; i < 40; i++)
! 1357: if (str[i] == 0)
! 1358: return;
! 1359: else if (IS_BLANK_CH(str[i]))
! 1360: fputc(' ', output);
! 1361: else if (str[i] >= 0x80)
! 1362: fprintf(output, "#%X", str[i]);
! 1363: else
! 1364: fputc(str[i], output);
! 1365: fprintf(output, "...");
! 1366: }
! 1367:
! 1368: /**
! 1369: * xmlDebugDumpAttr:
! 1370: * @output: the FILE * for the output
! 1371: * @attr: the attribute
! 1372: * @depth: the indentation level.
! 1373: *
! 1374: * Dumps debug information for the attribute
! 1375: */
! 1376: void
! 1377: xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
! 1378: xmlDebugCtxt ctxt;
! 1379:
! 1380: if (output == NULL) return;
! 1381: xmlCtxtDumpInitCtxt(&ctxt);
! 1382: ctxt.output = output;
! 1383: ctxt.depth = depth;
! 1384: xmlCtxtDumpAttr(&ctxt, attr);
! 1385: xmlCtxtDumpCleanCtxt(&ctxt);
! 1386: }
! 1387:
! 1388:
! 1389: /**
! 1390: * xmlDebugDumpEntities:
! 1391: * @output: the FILE * for the output
! 1392: * @doc: the document
! 1393: *
! 1394: * Dumps debug information for all the entities in use by the document
! 1395: */
! 1396: void
! 1397: xmlDebugDumpEntities(FILE * output, xmlDocPtr doc)
! 1398: {
! 1399: xmlDebugCtxt ctxt;
! 1400:
! 1401: if (output == NULL) return;
! 1402: xmlCtxtDumpInitCtxt(&ctxt);
! 1403: ctxt.output = output;
! 1404: xmlCtxtDumpEntities(&ctxt, doc);
! 1405: xmlCtxtDumpCleanCtxt(&ctxt);
! 1406: }
! 1407:
! 1408: /**
! 1409: * xmlDebugDumpAttrList:
! 1410: * @output: the FILE * for the output
! 1411: * @attr: the attribute list
! 1412: * @depth: the indentation level.
! 1413: *
! 1414: * Dumps debug information for the attribute list
! 1415: */
! 1416: void
! 1417: xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
! 1418: {
! 1419: xmlDebugCtxt ctxt;
! 1420:
! 1421: if (output == NULL) return;
! 1422: xmlCtxtDumpInitCtxt(&ctxt);
! 1423: ctxt.output = output;
! 1424: ctxt.depth = depth;
! 1425: xmlCtxtDumpAttrList(&ctxt, attr);
! 1426: xmlCtxtDumpCleanCtxt(&ctxt);
! 1427: }
! 1428:
! 1429: /**
! 1430: * xmlDebugDumpOneNode:
! 1431: * @output: the FILE * for the output
! 1432: * @node: the node
! 1433: * @depth: the indentation level.
! 1434: *
! 1435: * Dumps debug information for the element node, it is not recursive
! 1436: */
! 1437: void
! 1438: xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
! 1439: {
! 1440: xmlDebugCtxt ctxt;
! 1441:
! 1442: if (output == NULL) return;
! 1443: xmlCtxtDumpInitCtxt(&ctxt);
! 1444: ctxt.output = output;
! 1445: ctxt.depth = depth;
! 1446: xmlCtxtDumpOneNode(&ctxt, node);
! 1447: xmlCtxtDumpCleanCtxt(&ctxt);
! 1448: }
! 1449:
! 1450: /**
! 1451: * xmlDebugDumpNode:
! 1452: * @output: the FILE * for the output
! 1453: * @node: the node
! 1454: * @depth: the indentation level.
! 1455: *
! 1456: * Dumps debug information for the element node, it is recursive
! 1457: */
! 1458: void
! 1459: xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
! 1460: {
! 1461: xmlDebugCtxt ctxt;
! 1462:
! 1463: if (output == NULL)
! 1464: output = stdout;
! 1465: xmlCtxtDumpInitCtxt(&ctxt);
! 1466: ctxt.output = output;
! 1467: ctxt.depth = depth;
! 1468: xmlCtxtDumpNode(&ctxt, node);
! 1469: xmlCtxtDumpCleanCtxt(&ctxt);
! 1470: }
! 1471:
! 1472: /**
! 1473: * xmlDebugDumpNodeList:
! 1474: * @output: the FILE * for the output
! 1475: * @node: the node list
! 1476: * @depth: the indentation level.
! 1477: *
! 1478: * Dumps debug information for the list of element node, it is recursive
! 1479: */
! 1480: void
! 1481: xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
! 1482: {
! 1483: xmlDebugCtxt ctxt;
! 1484:
! 1485: if (output == NULL)
! 1486: output = stdout;
! 1487: xmlCtxtDumpInitCtxt(&ctxt);
! 1488: ctxt.output = output;
! 1489: ctxt.depth = depth;
! 1490: xmlCtxtDumpNodeList(&ctxt, node);
! 1491: xmlCtxtDumpCleanCtxt(&ctxt);
! 1492: }
! 1493:
! 1494: /**
! 1495: * xmlDebugDumpDocumentHead:
! 1496: * @output: the FILE * for the output
! 1497: * @doc: the document
! 1498: *
! 1499: * Dumps debug information cncerning the document, not recursive
! 1500: */
! 1501: void
! 1502: xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
! 1503: {
! 1504: xmlDebugCtxt ctxt;
! 1505:
! 1506: if (output == NULL)
! 1507: output = stdout;
! 1508: xmlCtxtDumpInitCtxt(&ctxt);
! 1509: ctxt.options |= DUMP_TEXT_TYPE;
! 1510: ctxt.output = output;
! 1511: xmlCtxtDumpDocumentHead(&ctxt, doc);
! 1512: xmlCtxtDumpCleanCtxt(&ctxt);
! 1513: }
! 1514:
! 1515: /**
! 1516: * xmlDebugDumpDocument:
! 1517: * @output: the FILE * for the output
! 1518: * @doc: the document
! 1519: *
! 1520: * Dumps debug information for the document, it's recursive
! 1521: */
! 1522: void
! 1523: xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
! 1524: {
! 1525: xmlDebugCtxt ctxt;
! 1526:
! 1527: if (output == NULL)
! 1528: output = stdout;
! 1529: xmlCtxtDumpInitCtxt(&ctxt);
! 1530: ctxt.options |= DUMP_TEXT_TYPE;
! 1531: ctxt.output = output;
! 1532: xmlCtxtDumpDocument(&ctxt, doc);
! 1533: xmlCtxtDumpCleanCtxt(&ctxt);
! 1534: }
! 1535:
! 1536: /**
! 1537: * xmlDebugDumpDTD:
! 1538: * @output: the FILE * for the output
! 1539: * @dtd: the DTD
! 1540: *
! 1541: * Dumps debug information for the DTD
! 1542: */
! 1543: void
! 1544: xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
! 1545: {
! 1546: xmlDebugCtxt ctxt;
! 1547:
! 1548: if (output == NULL)
! 1549: output = stdout;
! 1550: xmlCtxtDumpInitCtxt(&ctxt);
! 1551: ctxt.options |= DUMP_TEXT_TYPE;
! 1552: ctxt.output = output;
! 1553: xmlCtxtDumpDTD(&ctxt, dtd);
! 1554: xmlCtxtDumpCleanCtxt(&ctxt);
! 1555: }
! 1556:
! 1557: /************************************************************************
! 1558: * *
! 1559: * Public entry points for checkings *
! 1560: * *
! 1561: ************************************************************************/
! 1562:
! 1563: /**
! 1564: * xmlDebugCheckDocument:
! 1565: * @output: the FILE * for the output
! 1566: * @doc: the document
! 1567: *
! 1568: * Check the document for potential content problems, and output
! 1569: * the errors to @output
! 1570: *
! 1571: * Returns the number of errors found
! 1572: */
! 1573: int
! 1574: xmlDebugCheckDocument(FILE * output, xmlDocPtr doc)
! 1575: {
! 1576: xmlDebugCtxt ctxt;
! 1577:
! 1578: if (output == NULL)
! 1579: output = stdout;
! 1580: xmlCtxtDumpInitCtxt(&ctxt);
! 1581: ctxt.output = output;
! 1582: ctxt.check = 1;
! 1583: xmlCtxtDumpDocument(&ctxt, doc);
! 1584: xmlCtxtDumpCleanCtxt(&ctxt);
! 1585: return(ctxt.errors);
! 1586: }
! 1587:
! 1588: /************************************************************************
! 1589: * *
! 1590: * Helpers for Shell *
! 1591: * *
! 1592: ************************************************************************/
! 1593:
! 1594: /**
! 1595: * xmlLsCountNode:
! 1596: * @node: the node to count
! 1597: *
! 1598: * Count the children of @node.
! 1599: *
! 1600: * Returns the number of children of @node.
! 1601: */
! 1602: int
! 1603: xmlLsCountNode(xmlNodePtr node) {
! 1604: int ret = 0;
! 1605: xmlNodePtr list = NULL;
! 1606:
! 1607: if (node == NULL)
! 1608: return(0);
! 1609:
! 1610: switch (node->type) {
! 1611: case XML_ELEMENT_NODE:
! 1612: list = node->children;
! 1613: break;
! 1614: case XML_DOCUMENT_NODE:
! 1615: case XML_HTML_DOCUMENT_NODE:
! 1616: #ifdef LIBXML_DOCB_ENABLED
! 1617: case XML_DOCB_DOCUMENT_NODE:
! 1618: #endif
! 1619: list = ((xmlDocPtr) node)->children;
! 1620: break;
! 1621: case XML_ATTRIBUTE_NODE:
! 1622: list = ((xmlAttrPtr) node)->children;
! 1623: break;
! 1624: case XML_TEXT_NODE:
! 1625: case XML_CDATA_SECTION_NODE:
! 1626: case XML_PI_NODE:
! 1627: case XML_COMMENT_NODE:
! 1628: if (node->content != NULL) {
! 1629: ret = xmlStrlen(node->content);
! 1630: }
! 1631: break;
! 1632: case XML_ENTITY_REF_NODE:
! 1633: case XML_DOCUMENT_TYPE_NODE:
! 1634: case XML_ENTITY_NODE:
! 1635: case XML_DOCUMENT_FRAG_NODE:
! 1636: case XML_NOTATION_NODE:
! 1637: case XML_DTD_NODE:
! 1638: case XML_ELEMENT_DECL:
! 1639: case XML_ATTRIBUTE_DECL:
! 1640: case XML_ENTITY_DECL:
! 1641: case XML_NAMESPACE_DECL:
! 1642: case XML_XINCLUDE_START:
! 1643: case XML_XINCLUDE_END:
! 1644: ret = 1;
! 1645: break;
! 1646: }
! 1647: for (;list != NULL;ret++)
! 1648: list = list->next;
! 1649: return(ret);
! 1650: }
! 1651:
! 1652: /**
! 1653: * xmlLsOneNode:
! 1654: * @output: the FILE * for the output
! 1655: * @node: the node to dump
! 1656: *
! 1657: * Dump to @output the type and name of @node.
! 1658: */
! 1659: void
! 1660: xmlLsOneNode(FILE *output, xmlNodePtr node) {
! 1661: if (output == NULL) return;
! 1662: if (node == NULL) {
! 1663: fprintf(output, "NULL\n");
! 1664: return;
! 1665: }
! 1666: switch (node->type) {
! 1667: case XML_ELEMENT_NODE:
! 1668: fprintf(output, "-");
! 1669: break;
! 1670: case XML_ATTRIBUTE_NODE:
! 1671: fprintf(output, "a");
! 1672: break;
! 1673: case XML_TEXT_NODE:
! 1674: fprintf(output, "t");
! 1675: break;
! 1676: case XML_CDATA_SECTION_NODE:
! 1677: fprintf(output, "C");
! 1678: break;
! 1679: case XML_ENTITY_REF_NODE:
! 1680: fprintf(output, "e");
! 1681: break;
! 1682: case XML_ENTITY_NODE:
! 1683: fprintf(output, "E");
! 1684: break;
! 1685: case XML_PI_NODE:
! 1686: fprintf(output, "p");
! 1687: break;
! 1688: case XML_COMMENT_NODE:
! 1689: fprintf(output, "c");
! 1690: break;
! 1691: case XML_DOCUMENT_NODE:
! 1692: fprintf(output, "d");
! 1693: break;
! 1694: case XML_HTML_DOCUMENT_NODE:
! 1695: fprintf(output, "h");
! 1696: break;
! 1697: case XML_DOCUMENT_TYPE_NODE:
! 1698: fprintf(output, "T");
! 1699: break;
! 1700: case XML_DOCUMENT_FRAG_NODE:
! 1701: fprintf(output, "F");
! 1702: break;
! 1703: case XML_NOTATION_NODE:
! 1704: fprintf(output, "N");
! 1705: break;
! 1706: case XML_NAMESPACE_DECL:
! 1707: fprintf(output, "n");
! 1708: break;
! 1709: default:
! 1710: fprintf(output, "?");
! 1711: }
! 1712: if (node->type != XML_NAMESPACE_DECL) {
! 1713: if (node->properties != NULL)
! 1714: fprintf(output, "a");
! 1715: else
! 1716: fprintf(output, "-");
! 1717: if (node->nsDef != NULL)
! 1718: fprintf(output, "n");
! 1719: else
! 1720: fprintf(output, "-");
! 1721: }
! 1722:
! 1723: fprintf(output, " %8d ", xmlLsCountNode(node));
! 1724:
! 1725: switch (node->type) {
! 1726: case XML_ELEMENT_NODE:
! 1727: if (node->name != NULL)
! 1728: fprintf(output, "%s", (const char *) node->name);
! 1729: break;
! 1730: case XML_ATTRIBUTE_NODE:
! 1731: if (node->name != NULL)
! 1732: fprintf(output, "%s", (const char *) node->name);
! 1733: break;
! 1734: case XML_TEXT_NODE:
! 1735: if (node->content != NULL) {
! 1736: xmlDebugDumpString(output, node->content);
! 1737: }
! 1738: break;
! 1739: case XML_CDATA_SECTION_NODE:
! 1740: break;
! 1741: case XML_ENTITY_REF_NODE:
! 1742: if (node->name != NULL)
! 1743: fprintf(output, "%s", (const char *) node->name);
! 1744: break;
! 1745: case XML_ENTITY_NODE:
! 1746: if (node->name != NULL)
! 1747: fprintf(output, "%s", (const char *) node->name);
! 1748: break;
! 1749: case XML_PI_NODE:
! 1750: if (node->name != NULL)
! 1751: fprintf(output, "%s", (const char *) node->name);
! 1752: break;
! 1753: case XML_COMMENT_NODE:
! 1754: break;
! 1755: case XML_DOCUMENT_NODE:
! 1756: break;
! 1757: case XML_HTML_DOCUMENT_NODE:
! 1758: break;
! 1759: case XML_DOCUMENT_TYPE_NODE:
! 1760: break;
! 1761: case XML_DOCUMENT_FRAG_NODE:
! 1762: break;
! 1763: case XML_NOTATION_NODE:
! 1764: break;
! 1765: case XML_NAMESPACE_DECL: {
! 1766: xmlNsPtr ns = (xmlNsPtr) node;
! 1767:
! 1768: if (ns->prefix == NULL)
! 1769: fprintf(output, "default -> %s", (char *)ns->href);
! 1770: else
! 1771: fprintf(output, "%s -> %s", (char *)ns->prefix,
! 1772: (char *)ns->href);
! 1773: break;
! 1774: }
! 1775: default:
! 1776: if (node->name != NULL)
! 1777: fprintf(output, "%s", (const char *) node->name);
! 1778: }
! 1779: fprintf(output, "\n");
! 1780: }
! 1781:
! 1782: /**
! 1783: * xmlBoolToText:
! 1784: * @boolval: a bool to turn into text
! 1785: *
! 1786: * Convenient way to turn bool into text
! 1787: *
! 1788: * Returns a pointer to either "True" or "False"
! 1789: */
! 1790: const char *
! 1791: xmlBoolToText(int boolval)
! 1792: {
! 1793: if (boolval)
! 1794: return("True");
! 1795: else
! 1796: return("False");
! 1797: }
! 1798:
! 1799: #ifdef LIBXML_XPATH_ENABLED
! 1800: /****************************************************************
! 1801: * *
! 1802: * The XML shell related functions *
! 1803: * *
! 1804: ****************************************************************/
! 1805:
! 1806:
! 1807:
! 1808: /*
! 1809: * TODO: Improvement/cleanups for the XML shell
! 1810: * - allow to shell out an editor on a subpart
! 1811: * - cleanup function registrations (with help) and calling
! 1812: * - provide registration routines
! 1813: */
! 1814:
! 1815: /**
! 1816: * xmlShellPrintXPathError:
! 1817: * @errorType: valid xpath error id
! 1818: * @arg: the argument that cause xpath to fail
! 1819: *
! 1820: * Print the xpath error to libxml default error channel
! 1821: */
! 1822: void
! 1823: xmlShellPrintXPathError(int errorType, const char *arg)
! 1824: {
! 1825: const char *default_arg = "Result";
! 1826:
! 1827: if (!arg)
! 1828: arg = default_arg;
! 1829:
! 1830: switch (errorType) {
! 1831: case XPATH_UNDEFINED:
! 1832: xmlGenericError(xmlGenericErrorContext,
! 1833: "%s: no such node\n", arg);
! 1834: break;
! 1835:
! 1836: case XPATH_BOOLEAN:
! 1837: xmlGenericError(xmlGenericErrorContext,
! 1838: "%s is a Boolean\n", arg);
! 1839: break;
! 1840: case XPATH_NUMBER:
! 1841: xmlGenericError(xmlGenericErrorContext,
! 1842: "%s is a number\n", arg);
! 1843: break;
! 1844: case XPATH_STRING:
! 1845: xmlGenericError(xmlGenericErrorContext,
! 1846: "%s is a string\n", arg);
! 1847: break;
! 1848: case XPATH_POINT:
! 1849: xmlGenericError(xmlGenericErrorContext,
! 1850: "%s is a point\n", arg);
! 1851: break;
! 1852: case XPATH_RANGE:
! 1853: xmlGenericError(xmlGenericErrorContext,
! 1854: "%s is a range\n", arg);
! 1855: break;
! 1856: case XPATH_LOCATIONSET:
! 1857: xmlGenericError(xmlGenericErrorContext,
! 1858: "%s is a range\n", arg);
! 1859: break;
! 1860: case XPATH_USERS:
! 1861: xmlGenericError(xmlGenericErrorContext,
! 1862: "%s is user-defined\n", arg);
! 1863: break;
! 1864: case XPATH_XSLT_TREE:
! 1865: xmlGenericError(xmlGenericErrorContext,
! 1866: "%s is an XSLT value tree\n", arg);
! 1867: break;
! 1868: }
! 1869: #if 0
! 1870: xmlGenericError(xmlGenericErrorContext,
! 1871: "Try casting the result string function (xpath builtin)\n",
! 1872: arg);
! 1873: #endif
! 1874: }
! 1875:
! 1876:
! 1877: #ifdef LIBXML_OUTPUT_ENABLED
! 1878: /**
! 1879: * xmlShellPrintNodeCtxt:
! 1880: * @ctxt : a non-null shell context
! 1881: * @node : a non-null node to print to the output FILE
! 1882: *
! 1883: * Print node to the output FILE
! 1884: */
! 1885: static void
! 1886: xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node)
! 1887: {
! 1888: FILE *fp;
! 1889:
! 1890: if (!node)
! 1891: return;
! 1892: if (ctxt == NULL)
! 1893: fp = stdout;
! 1894: else
! 1895: fp = ctxt->output;
! 1896:
! 1897: if (node->type == XML_DOCUMENT_NODE)
! 1898: xmlDocDump(fp, (xmlDocPtr) node);
! 1899: else if (node->type == XML_ATTRIBUTE_NODE)
! 1900: xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0);
! 1901: else
! 1902: xmlElemDump(fp, node->doc, node);
! 1903:
! 1904: fprintf(fp, "\n");
! 1905: }
! 1906:
! 1907: /**
! 1908: * xmlShellPrintNode:
! 1909: * @node : a non-null node to print to the output FILE
! 1910: *
! 1911: * Print node to the output FILE
! 1912: */
! 1913: void
! 1914: xmlShellPrintNode(xmlNodePtr node)
! 1915: {
! 1916: xmlShellPrintNodeCtxt(NULL, node);
! 1917: }
! 1918: #endif /* LIBXML_OUTPUT_ENABLED */
! 1919:
! 1920: /**
! 1921: * xmlShellPrintXPathResultCtxt:
! 1922: * @ctxt: a valid shell context
! 1923: * @list: a valid result generated by an xpath evaluation
! 1924: *
! 1925: * Prints result to the output FILE
! 1926: */
! 1927: static void
! 1928: xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
! 1929: {
! 1930: if (!ctxt)
! 1931: return;
! 1932:
! 1933: if (list != NULL) {
! 1934: switch (list->type) {
! 1935: case XPATH_NODESET:{
! 1936: #ifdef LIBXML_OUTPUT_ENABLED
! 1937: int indx;
! 1938:
! 1939: if (list->nodesetval) {
! 1940: for (indx = 0; indx < list->nodesetval->nodeNr;
! 1941: indx++) {
! 1942: xmlShellPrintNodeCtxt(ctxt,
! 1943: list->nodesetval->nodeTab[indx]);
! 1944: }
! 1945: } else {
! 1946: xmlGenericError(xmlGenericErrorContext,
! 1947: "Empty node set\n");
! 1948: }
! 1949: break;
! 1950: #else
! 1951: xmlGenericError(xmlGenericErrorContext,
! 1952: "Node set\n");
! 1953: #endif /* LIBXML_OUTPUT_ENABLED */
! 1954: }
! 1955: case XPATH_BOOLEAN:
! 1956: xmlGenericError(xmlGenericErrorContext,
! 1957: "Is a Boolean:%s\n",
! 1958: xmlBoolToText(list->boolval));
! 1959: break;
! 1960: case XPATH_NUMBER:
! 1961: xmlGenericError(xmlGenericErrorContext,
! 1962: "Is a number:%0g\n", list->floatval);
! 1963: break;
! 1964: case XPATH_STRING:
! 1965: xmlGenericError(xmlGenericErrorContext,
! 1966: "Is a string:%s\n", list->stringval);
! 1967: break;
! 1968:
! 1969: default:
! 1970: xmlShellPrintXPathError(list->type, NULL);
! 1971: }
! 1972: }
! 1973: }
! 1974:
! 1975: /**
! 1976: * xmlShellPrintXPathResult:
! 1977: * @list: a valid result generated by an xpath evaluation
! 1978: *
! 1979: * Prints result to the output FILE
! 1980: */
! 1981: void
! 1982: xmlShellPrintXPathResult(xmlXPathObjectPtr list)
! 1983: {
! 1984: xmlShellPrintXPathResultCtxt(NULL, list);
! 1985: }
! 1986:
! 1987: /**
! 1988: * xmlShellList:
! 1989: * @ctxt: the shell context
! 1990: * @arg: unused
! 1991: * @node: a node
! 1992: * @node2: unused
! 1993: *
! 1994: * Implements the XML shell function "ls"
! 1995: * Does an Unix like listing of the given node (like a directory)
! 1996: *
! 1997: * Returns 0
! 1998: */
! 1999: int
! 2000: xmlShellList(xmlShellCtxtPtr ctxt,
! 2001: char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
! 2002: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2003: {
! 2004: xmlNodePtr cur;
! 2005: if (!ctxt)
! 2006: return (0);
! 2007: if (node == NULL) {
! 2008: fprintf(ctxt->output, "NULL\n");
! 2009: return (0);
! 2010: }
! 2011: if ((node->type == XML_DOCUMENT_NODE) ||
! 2012: (node->type == XML_HTML_DOCUMENT_NODE)) {
! 2013: cur = ((xmlDocPtr) node)->children;
! 2014: } else if (node->type == XML_NAMESPACE_DECL) {
! 2015: xmlLsOneNode(ctxt->output, node);
! 2016: return (0);
! 2017: } else if (node->children != NULL) {
! 2018: cur = node->children;
! 2019: } else {
! 2020: xmlLsOneNode(ctxt->output, node);
! 2021: return (0);
! 2022: }
! 2023: while (cur != NULL) {
! 2024: xmlLsOneNode(ctxt->output, cur);
! 2025: cur = cur->next;
! 2026: }
! 2027: return (0);
! 2028: }
! 2029:
! 2030: /**
! 2031: * xmlShellBase:
! 2032: * @ctxt: the shell context
! 2033: * @arg: unused
! 2034: * @node: a node
! 2035: * @node2: unused
! 2036: *
! 2037: * Implements the XML shell function "base"
! 2038: * dumps the current XML base of the node
! 2039: *
! 2040: * Returns 0
! 2041: */
! 2042: int
! 2043: xmlShellBase(xmlShellCtxtPtr ctxt,
! 2044: char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
! 2045: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2046: {
! 2047: xmlChar *base;
! 2048: if (!ctxt)
! 2049: return 0;
! 2050: if (node == NULL) {
! 2051: fprintf(ctxt->output, "NULL\n");
! 2052: return (0);
! 2053: }
! 2054:
! 2055: base = xmlNodeGetBase(node->doc, node);
! 2056:
! 2057: if (base == NULL) {
! 2058: fprintf(ctxt->output, " No base found !!!\n");
! 2059: } else {
! 2060: fprintf(ctxt->output, "%s\n", base);
! 2061: xmlFree(base);
! 2062: }
! 2063: return (0);
! 2064: }
! 2065:
! 2066: #ifdef LIBXML_TREE_ENABLED
! 2067: /**
! 2068: * xmlShellSetBase:
! 2069: * @ctxt: the shell context
! 2070: * @arg: the new base
! 2071: * @node: a node
! 2072: * @node2: unused
! 2073: *
! 2074: * Implements the XML shell function "setbase"
! 2075: * change the current XML base of the node
! 2076: *
! 2077: * Returns 0
! 2078: */
! 2079: static int
! 2080: xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
! 2081: char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
! 2082: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2083: {
! 2084: xmlNodeSetBase(node, (xmlChar*) arg);
! 2085: return (0);
! 2086: }
! 2087: #endif
! 2088:
! 2089: #ifdef LIBXML_XPATH_ENABLED
! 2090: /**
! 2091: * xmlShellRegisterNamespace:
! 2092: * @ctxt: the shell context
! 2093: * @arg: a string in prefix=nsuri format
! 2094: * @node: unused
! 2095: * @node2: unused
! 2096: *
! 2097: * Implements the XML shell function "setns"
! 2098: * register/unregister a prefix=namespace pair
! 2099: * on the XPath context
! 2100: *
! 2101: * Returns 0 on success and a negative value otherwise.
! 2102: */
! 2103: static int
! 2104: xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg,
! 2105: xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2106: {
! 2107: xmlChar* nsListDup;
! 2108: xmlChar* prefix;
! 2109: xmlChar* href;
! 2110: xmlChar* next;
! 2111:
! 2112: nsListDup = xmlStrdup((xmlChar *) arg);
! 2113: next = nsListDup;
! 2114: while(next != NULL) {
! 2115: /* skip spaces */
! 2116: /*while((*next) == ' ') next++;*/
! 2117: if((*next) == '\0') break;
! 2118:
! 2119: /* find prefix */
! 2120: prefix = next;
! 2121: next = (xmlChar*)xmlStrchr(next, '=');
! 2122: if(next == NULL) {
! 2123: fprintf(ctxt->output, "setns: prefix=[nsuri] required\n");
! 2124: xmlFree(nsListDup);
! 2125: return(-1);
! 2126: }
! 2127: *(next++) = '\0';
! 2128:
! 2129: /* find href */
! 2130: href = next;
! 2131: next = (xmlChar*)xmlStrchr(next, ' ');
! 2132: if(next != NULL) {
! 2133: *(next++) = '\0';
! 2134: }
! 2135:
! 2136: /* do register namespace */
! 2137: if(xmlXPathRegisterNs(ctxt->pctxt, prefix, href) != 0) {
! 2138: fprintf(ctxt->output,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
! 2139: xmlFree(nsListDup);
! 2140: return(-1);
! 2141: }
! 2142: }
! 2143:
! 2144: xmlFree(nsListDup);
! 2145: return(0);
! 2146: }
! 2147: /**
! 2148: * xmlShellRegisterRootNamespaces:
! 2149: * @ctxt: the shell context
! 2150: * @arg: unused
! 2151: * @node: the root element
! 2152: * @node2: unused
! 2153: *
! 2154: * Implements the XML shell function "setrootns"
! 2155: * which registers all namespaces declarations found on the root element.
! 2156: *
! 2157: * Returns 0 on success and a negative value otherwise.
! 2158: */
! 2159: static int
! 2160: xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
! 2161: xmlNodePtr root, xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2162: {
! 2163: xmlNsPtr ns;
! 2164:
! 2165: if ((root == NULL) || (root->type != XML_ELEMENT_NODE) ||
! 2166: (root->nsDef == NULL) || (ctxt == NULL) || (ctxt->pctxt == NULL))
! 2167: return(-1);
! 2168: ns = root->nsDef;
! 2169: while (ns != NULL) {
! 2170: if (ns->prefix == NULL)
! 2171: xmlXPathRegisterNs(ctxt->pctxt, BAD_CAST "defaultns", ns->href);
! 2172: else
! 2173: xmlXPathRegisterNs(ctxt->pctxt, ns->prefix, ns->href);
! 2174: ns = ns->next;
! 2175: }
! 2176: return(0);
! 2177: }
! 2178: #endif
! 2179:
! 2180: /**
! 2181: * xmlShellGrep:
! 2182: * @ctxt: the shell context
! 2183: * @arg: the string or regular expression to find
! 2184: * @node: a node
! 2185: * @node2: unused
! 2186: *
! 2187: * Implements the XML shell function "grep"
! 2188: * dumps informations about the node (namespace, attributes, content).
! 2189: *
! 2190: * Returns 0
! 2191: */
! 2192: static int
! 2193: xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
! 2194: char *arg, xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2195: {
! 2196: if (!ctxt)
! 2197: return (0);
! 2198: if (node == NULL)
! 2199: return (0);
! 2200: if (arg == NULL)
! 2201: return (0);
! 2202: #ifdef LIBXML_REGEXP_ENABLED
! 2203: if ((xmlStrchr((xmlChar *) arg, '?')) ||
! 2204: (xmlStrchr((xmlChar *) arg, '*')) ||
! 2205: (xmlStrchr((xmlChar *) arg, '.')) ||
! 2206: (xmlStrchr((xmlChar *) arg, '['))) {
! 2207: }
! 2208: #endif
! 2209: while (node != NULL) {
! 2210: if (node->type == XML_COMMENT_NODE) {
! 2211: if (xmlStrstr(node->content, (xmlChar *) arg)) {
! 2212:
! 2213: fprintf(ctxt->output, "%s : ", xmlGetNodePath(node));
! 2214: xmlShellList(ctxt, NULL, node, NULL);
! 2215: }
! 2216: } else if (node->type == XML_TEXT_NODE) {
! 2217: if (xmlStrstr(node->content, (xmlChar *) arg)) {
! 2218:
! 2219: fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent));
! 2220: xmlShellList(ctxt, NULL, node->parent, NULL);
! 2221: }
! 2222: }
! 2223:
! 2224: /*
! 2225: * Browse the full subtree, deep first
! 2226: */
! 2227:
! 2228: if ((node->type == XML_DOCUMENT_NODE) ||
! 2229: (node->type == XML_HTML_DOCUMENT_NODE)) {
! 2230: node = ((xmlDocPtr) node)->children;
! 2231: } else if ((node->children != NULL)
! 2232: && (node->type != XML_ENTITY_REF_NODE)) {
! 2233: /* deep first */
! 2234: node = node->children;
! 2235: } else if (node->next != NULL) {
! 2236: /* then siblings */
! 2237: node = node->next;
! 2238: } else {
! 2239: /* go up to parents->next if needed */
! 2240: while (node != NULL) {
! 2241: if (node->parent != NULL) {
! 2242: node = node->parent;
! 2243: }
! 2244: if (node->next != NULL) {
! 2245: node = node->next;
! 2246: break;
! 2247: }
! 2248: if (node->parent == NULL) {
! 2249: node = NULL;
! 2250: break;
! 2251: }
! 2252: }
! 2253: }
! 2254: }
! 2255: return (0);
! 2256: }
! 2257:
! 2258: /**
! 2259: * xmlShellDir:
! 2260: * @ctxt: the shell context
! 2261: * @arg: unused
! 2262: * @node: a node
! 2263: * @node2: unused
! 2264: *
! 2265: * Implements the XML shell function "dir"
! 2266: * dumps informations about the node (namespace, attributes, content).
! 2267: *
! 2268: * Returns 0
! 2269: */
! 2270: int
! 2271: xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
! 2272: char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
! 2273: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2274: {
! 2275: if (!ctxt)
! 2276: return (0);
! 2277: if (node == NULL) {
! 2278: fprintf(ctxt->output, "NULL\n");
! 2279: return (0);
! 2280: }
! 2281: if ((node->type == XML_DOCUMENT_NODE) ||
! 2282: (node->type == XML_HTML_DOCUMENT_NODE)) {
! 2283: xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node);
! 2284: } else if (node->type == XML_ATTRIBUTE_NODE) {
! 2285: xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0);
! 2286: } else {
! 2287: xmlDebugDumpOneNode(ctxt->output, node, 0);
! 2288: }
! 2289: return (0);
! 2290: }
! 2291:
! 2292: /**
! 2293: * xmlShellSetContent:
! 2294: * @ctxt: the shell context
! 2295: * @value: the content as a string
! 2296: * @node: a node
! 2297: * @node2: unused
! 2298: *
! 2299: * Implements the XML shell function "dir"
! 2300: * dumps informations about the node (namespace, attributes, content).
! 2301: *
! 2302: * Returns 0
! 2303: */
! 2304: static int
! 2305: xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
! 2306: char *value, xmlNodePtr node,
! 2307: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2308: {
! 2309: xmlNodePtr results;
! 2310: xmlParserErrors ret;
! 2311:
! 2312: if (!ctxt)
! 2313: return (0);
! 2314: if (node == NULL) {
! 2315: fprintf(ctxt->output, "NULL\n");
! 2316: return (0);
! 2317: }
! 2318: if (value == NULL) {
! 2319: fprintf(ctxt->output, "NULL\n");
! 2320: return (0);
! 2321: }
! 2322:
! 2323: ret = xmlParseInNodeContext(node, value, strlen(value), 0, &results);
! 2324: if (ret == XML_ERR_OK) {
! 2325: if (node->children != NULL) {
! 2326: xmlFreeNodeList(node->children);
! 2327: node->children = NULL;
! 2328: node->last = NULL;
! 2329: }
! 2330: xmlAddChildList(node, results);
! 2331: } else {
! 2332: fprintf(ctxt->output, "failed to parse content\n");
! 2333: }
! 2334: return (0);
! 2335: }
! 2336:
! 2337: #ifdef LIBXML_SCHEMAS_ENABLED
! 2338: /**
! 2339: * xmlShellRNGValidate:
! 2340: * @ctxt: the shell context
! 2341: * @schemas: the path to the Relax-NG schemas
! 2342: * @node: a node
! 2343: * @node2: unused
! 2344: *
! 2345: * Implements the XML shell function "relaxng"
! 2346: * validating the instance against a Relax-NG schemas
! 2347: *
! 2348: * Returns 0
! 2349: */
! 2350: static int
! 2351: xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
! 2352: xmlNodePtr node ATTRIBUTE_UNUSED,
! 2353: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2354: {
! 2355: xmlRelaxNGPtr relaxngschemas;
! 2356: xmlRelaxNGParserCtxtPtr ctxt;
! 2357: xmlRelaxNGValidCtxtPtr vctxt;
! 2358: int ret;
! 2359:
! 2360: ctxt = xmlRelaxNGNewParserCtxt(schemas);
! 2361: xmlRelaxNGSetParserErrors(ctxt,
! 2362: (xmlRelaxNGValidityErrorFunc) fprintf,
! 2363: (xmlRelaxNGValidityWarningFunc) fprintf,
! 2364: stderr);
! 2365: relaxngschemas = xmlRelaxNGParse(ctxt);
! 2366: xmlRelaxNGFreeParserCtxt(ctxt);
! 2367: if (relaxngschemas == NULL) {
! 2368: xmlGenericError(xmlGenericErrorContext,
! 2369: "Relax-NG schema %s failed to compile\n", schemas);
! 2370: return(-1);
! 2371: }
! 2372: vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
! 2373: xmlRelaxNGSetValidErrors(vctxt,
! 2374: (xmlRelaxNGValidityErrorFunc) fprintf,
! 2375: (xmlRelaxNGValidityWarningFunc) fprintf,
! 2376: stderr);
! 2377: ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc);
! 2378: if (ret == 0) {
! 2379: fprintf(stderr, "%s validates\n", sctxt->filename);
! 2380: } else if (ret > 0) {
! 2381: fprintf(stderr, "%s fails to validate\n", sctxt->filename);
! 2382: } else {
! 2383: fprintf(stderr, "%s validation generated an internal error\n",
! 2384: sctxt->filename);
! 2385: }
! 2386: xmlRelaxNGFreeValidCtxt(vctxt);
! 2387: if (relaxngschemas != NULL)
! 2388: xmlRelaxNGFree(relaxngschemas);
! 2389: return(0);
! 2390: }
! 2391: #endif
! 2392:
! 2393: #ifdef LIBXML_OUTPUT_ENABLED
! 2394: /**
! 2395: * xmlShellCat:
! 2396: * @ctxt: the shell context
! 2397: * @arg: unused
! 2398: * @node: a node
! 2399: * @node2: unused
! 2400: *
! 2401: * Implements the XML shell function "cat"
! 2402: * dumps the serialization node content (XML or HTML).
! 2403: *
! 2404: * Returns 0
! 2405: */
! 2406: int
! 2407: xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
! 2408: xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2409: {
! 2410: if (!ctxt)
! 2411: return (0);
! 2412: if (node == NULL) {
! 2413: fprintf(ctxt->output, "NULL\n");
! 2414: return (0);
! 2415: }
! 2416: if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
! 2417: #ifdef LIBXML_HTML_ENABLED
! 2418: if (node->type == XML_HTML_DOCUMENT_NODE)
! 2419: htmlDocDump(ctxt->output, (htmlDocPtr) node);
! 2420: else
! 2421: htmlNodeDumpFile(ctxt->output, ctxt->doc, node);
! 2422: #else
! 2423: if (node->type == XML_DOCUMENT_NODE)
! 2424: xmlDocDump(ctxt->output, (xmlDocPtr) node);
! 2425: else
! 2426: xmlElemDump(ctxt->output, ctxt->doc, node);
! 2427: #endif /* LIBXML_HTML_ENABLED */
! 2428: } else {
! 2429: if (node->type == XML_DOCUMENT_NODE)
! 2430: xmlDocDump(ctxt->output, (xmlDocPtr) node);
! 2431: else
! 2432: xmlElemDump(ctxt->output, ctxt->doc, node);
! 2433: }
! 2434: fprintf(ctxt->output, "\n");
! 2435: return (0);
! 2436: }
! 2437: #endif /* LIBXML_OUTPUT_ENABLED */
! 2438:
! 2439: /**
! 2440: * xmlShellLoad:
! 2441: * @ctxt: the shell context
! 2442: * @filename: the file name
! 2443: * @node: unused
! 2444: * @node2: unused
! 2445: *
! 2446: * Implements the XML shell function "load"
! 2447: * loads a new document specified by the filename
! 2448: *
! 2449: * Returns 0 or -1 if loading failed
! 2450: */
! 2451: int
! 2452: xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
! 2453: xmlNodePtr node ATTRIBUTE_UNUSED,
! 2454: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2455: {
! 2456: xmlDocPtr doc;
! 2457: int html = 0;
! 2458:
! 2459: if ((ctxt == NULL) || (filename == NULL)) return(-1);
! 2460: if (ctxt->doc != NULL)
! 2461: html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
! 2462:
! 2463: if (html) {
! 2464: #ifdef LIBXML_HTML_ENABLED
! 2465: doc = htmlParseFile(filename, NULL);
! 2466: #else
! 2467: fprintf(ctxt->output, "HTML support not compiled in\n");
! 2468: doc = NULL;
! 2469: #endif /* LIBXML_HTML_ENABLED */
! 2470: } else {
! 2471: doc = xmlReadFile(filename,NULL,0);
! 2472: }
! 2473: if (doc != NULL) {
! 2474: if (ctxt->loaded == 1) {
! 2475: xmlFreeDoc(ctxt->doc);
! 2476: }
! 2477: ctxt->loaded = 1;
! 2478: #ifdef LIBXML_XPATH_ENABLED
! 2479: xmlXPathFreeContext(ctxt->pctxt);
! 2480: #endif /* LIBXML_XPATH_ENABLED */
! 2481: xmlFree(ctxt->filename);
! 2482: ctxt->doc = doc;
! 2483: ctxt->node = (xmlNodePtr) doc;
! 2484: #ifdef LIBXML_XPATH_ENABLED
! 2485: ctxt->pctxt = xmlXPathNewContext(doc);
! 2486: #endif /* LIBXML_XPATH_ENABLED */
! 2487: ctxt->filename = (char *) xmlCanonicPath((xmlChar *) filename);
! 2488: } else
! 2489: return (-1);
! 2490: return (0);
! 2491: }
! 2492:
! 2493: #ifdef LIBXML_OUTPUT_ENABLED
! 2494: /**
! 2495: * xmlShellWrite:
! 2496: * @ctxt: the shell context
! 2497: * @filename: the file name
! 2498: * @node: a node in the tree
! 2499: * @node2: unused
! 2500: *
! 2501: * Implements the XML shell function "write"
! 2502: * Write the current node to the filename, it saves the serialization
! 2503: * of the subtree under the @node specified
! 2504: *
! 2505: * Returns 0 or -1 in case of error
! 2506: */
! 2507: int
! 2508: xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
! 2509: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2510: {
! 2511: if (node == NULL)
! 2512: return (-1);
! 2513: if ((filename == NULL) || (filename[0] == 0)) {
! 2514: return (-1);
! 2515: }
! 2516: #ifdef W_OK
! 2517: if (access((char *) filename, W_OK)) {
! 2518: xmlGenericError(xmlGenericErrorContext,
! 2519: "Cannot write to %s\n", filename);
! 2520: return (-1);
! 2521: }
! 2522: #endif
! 2523: switch (node->type) {
! 2524: case XML_DOCUMENT_NODE:
! 2525: if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
! 2526: xmlGenericError(xmlGenericErrorContext,
! 2527: "Failed to write to %s\n", filename);
! 2528: return (-1);
! 2529: }
! 2530: break;
! 2531: case XML_HTML_DOCUMENT_NODE:
! 2532: #ifdef LIBXML_HTML_ENABLED
! 2533: if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
! 2534: xmlGenericError(xmlGenericErrorContext,
! 2535: "Failed to write to %s\n", filename);
! 2536: return (-1);
! 2537: }
! 2538: #else
! 2539: if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
! 2540: xmlGenericError(xmlGenericErrorContext,
! 2541: "Failed to write to %s\n", filename);
! 2542: return (-1);
! 2543: }
! 2544: #endif /* LIBXML_HTML_ENABLED */
! 2545: break;
! 2546: default:{
! 2547: FILE *f;
! 2548:
! 2549: f = fopen((char *) filename, "w");
! 2550: if (f == NULL) {
! 2551: xmlGenericError(xmlGenericErrorContext,
! 2552: "Failed to write to %s\n", filename);
! 2553: return (-1);
! 2554: }
! 2555: xmlElemDump(f, ctxt->doc, node);
! 2556: fclose(f);
! 2557: }
! 2558: }
! 2559: return (0);
! 2560: }
! 2561:
! 2562: /**
! 2563: * xmlShellSave:
! 2564: * @ctxt: the shell context
! 2565: * @filename: the file name (optional)
! 2566: * @node: unused
! 2567: * @node2: unused
! 2568: *
! 2569: * Implements the XML shell function "save"
! 2570: * Write the current document to the filename, or it's original name
! 2571: *
! 2572: * Returns 0 or -1 in case of error
! 2573: */
! 2574: int
! 2575: xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
! 2576: xmlNodePtr node ATTRIBUTE_UNUSED,
! 2577: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2578: {
! 2579: if ((ctxt == NULL) || (ctxt->doc == NULL))
! 2580: return (-1);
! 2581: if ((filename == NULL) || (filename[0] == 0))
! 2582: filename = ctxt->filename;
! 2583: if (filename == NULL)
! 2584: return (-1);
! 2585: #ifdef W_OK
! 2586: if (access((char *) filename, W_OK)) {
! 2587: xmlGenericError(xmlGenericErrorContext,
! 2588: "Cannot save to %s\n", filename);
! 2589: return (-1);
! 2590: }
! 2591: #endif
! 2592: switch (ctxt->doc->type) {
! 2593: case XML_DOCUMENT_NODE:
! 2594: if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
! 2595: xmlGenericError(xmlGenericErrorContext,
! 2596: "Failed to save to %s\n", filename);
! 2597: }
! 2598: break;
! 2599: case XML_HTML_DOCUMENT_NODE:
! 2600: #ifdef LIBXML_HTML_ENABLED
! 2601: if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
! 2602: xmlGenericError(xmlGenericErrorContext,
! 2603: "Failed to save to %s\n", filename);
! 2604: }
! 2605: #else
! 2606: if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
! 2607: xmlGenericError(xmlGenericErrorContext,
! 2608: "Failed to save to %s\n", filename);
! 2609: }
! 2610: #endif /* LIBXML_HTML_ENABLED */
! 2611: break;
! 2612: default:
! 2613: xmlGenericError(xmlGenericErrorContext,
! 2614: "To save to subparts of a document use the 'write' command\n");
! 2615: return (-1);
! 2616:
! 2617: }
! 2618: return (0);
! 2619: }
! 2620: #endif /* LIBXML_OUTPUT_ENABLED */
! 2621:
! 2622: #ifdef LIBXML_VALID_ENABLED
! 2623: /**
! 2624: * xmlShellValidate:
! 2625: * @ctxt: the shell context
! 2626: * @dtd: the DTD URI (optional)
! 2627: * @node: unused
! 2628: * @node2: unused
! 2629: *
! 2630: * Implements the XML shell function "validate"
! 2631: * Validate the document, if a DTD path is provided, then the validation
! 2632: * is done against the given DTD.
! 2633: *
! 2634: * Returns 0 or -1 in case of error
! 2635: */
! 2636: int
! 2637: xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
! 2638: xmlNodePtr node ATTRIBUTE_UNUSED,
! 2639: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2640: {
! 2641: xmlValidCtxt vctxt;
! 2642: int res = -1;
! 2643:
! 2644: if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1);
! 2645: vctxt.userData = stderr;
! 2646: vctxt.error = (xmlValidityErrorFunc) fprintf;
! 2647: vctxt.warning = (xmlValidityWarningFunc) fprintf;
! 2648:
! 2649: if ((dtd == NULL) || (dtd[0] == 0)) {
! 2650: res = xmlValidateDocument(&vctxt, ctxt->doc);
! 2651: } else {
! 2652: xmlDtdPtr subset;
! 2653:
! 2654: subset = xmlParseDTD(NULL, (xmlChar *) dtd);
! 2655: if (subset != NULL) {
! 2656: res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
! 2657:
! 2658: xmlFreeDtd(subset);
! 2659: }
! 2660: }
! 2661: return (res);
! 2662: }
! 2663: #endif /* LIBXML_VALID_ENABLED */
! 2664:
! 2665: /**
! 2666: * xmlShellDu:
! 2667: * @ctxt: the shell context
! 2668: * @arg: unused
! 2669: * @tree: a node defining a subtree
! 2670: * @node2: unused
! 2671: *
! 2672: * Implements the XML shell function "du"
! 2673: * show the structure of the subtree under node @tree
! 2674: * If @tree is null, the command works on the current node.
! 2675: *
! 2676: * Returns 0 or -1 in case of error
! 2677: */
! 2678: int
! 2679: xmlShellDu(xmlShellCtxtPtr ctxt,
! 2680: char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
! 2681: xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2682: {
! 2683: xmlNodePtr node;
! 2684: int indent = 0, i;
! 2685:
! 2686: if (!ctxt)
! 2687: return (-1);
! 2688:
! 2689: if (tree == NULL)
! 2690: return (-1);
! 2691: node = tree;
! 2692: while (node != NULL) {
! 2693: if ((node->type == XML_DOCUMENT_NODE) ||
! 2694: (node->type == XML_HTML_DOCUMENT_NODE)) {
! 2695: fprintf(ctxt->output, "/\n");
! 2696: } else if (node->type == XML_ELEMENT_NODE) {
! 2697: for (i = 0; i < indent; i++)
! 2698: fprintf(ctxt->output, " ");
! 2699: fprintf(ctxt->output, "%s\n", node->name);
! 2700: } else {
! 2701: }
! 2702:
! 2703: /*
! 2704: * Browse the full subtree, deep first
! 2705: */
! 2706:
! 2707: if ((node->type == XML_DOCUMENT_NODE) ||
! 2708: (node->type == XML_HTML_DOCUMENT_NODE)) {
! 2709: node = ((xmlDocPtr) node)->children;
! 2710: } else if ((node->children != NULL)
! 2711: && (node->type != XML_ENTITY_REF_NODE)) {
! 2712: /* deep first */
! 2713: node = node->children;
! 2714: indent++;
! 2715: } else if ((node != tree) && (node->next != NULL)) {
! 2716: /* then siblings */
! 2717: node = node->next;
! 2718: } else if (node != tree) {
! 2719: /* go up to parents->next if needed */
! 2720: while (node != tree) {
! 2721: if (node->parent != NULL) {
! 2722: node = node->parent;
! 2723: indent--;
! 2724: }
! 2725: if ((node != tree) && (node->next != NULL)) {
! 2726: node = node->next;
! 2727: break;
! 2728: }
! 2729: if (node->parent == NULL) {
! 2730: node = NULL;
! 2731: break;
! 2732: }
! 2733: if (node == tree) {
! 2734: node = NULL;
! 2735: break;
! 2736: }
! 2737: }
! 2738: /* exit condition */
! 2739: if (node == tree)
! 2740: node = NULL;
! 2741: } else
! 2742: node = NULL;
! 2743: }
! 2744: return (0);
! 2745: }
! 2746:
! 2747: /**
! 2748: * xmlShellPwd:
! 2749: * @ctxt: the shell context
! 2750: * @buffer: the output buffer
! 2751: * @node: a node
! 2752: * @node2: unused
! 2753: *
! 2754: * Implements the XML shell function "pwd"
! 2755: * Show the full path from the root to the node, if needed building
! 2756: * thumblers when similar elements exists at a given ancestor level.
! 2757: * The output is compatible with XPath commands.
! 2758: *
! 2759: * Returns 0 or -1 in case of error
! 2760: */
! 2761: int
! 2762: xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
! 2763: xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
! 2764: {
! 2765: xmlChar *path;
! 2766:
! 2767: if ((node == NULL) || (buffer == NULL))
! 2768: return (-1);
! 2769:
! 2770: path = xmlGetNodePath(node);
! 2771: if (path == NULL)
! 2772: return (-1);
! 2773:
! 2774: /*
! 2775: * This test prevents buffer overflow, because this routine
! 2776: * is only called by xmlShell, in which the second argument is
! 2777: * 500 chars long.
! 2778: * It is a dirty hack before a cleaner solution is found.
! 2779: * Documentation should mention that the second argument must
! 2780: * be at least 500 chars long, and could be stripped if too long.
! 2781: */
! 2782: snprintf(buffer, 499, "%s", path);
! 2783: buffer[499] = '0';
! 2784: xmlFree(path);
! 2785:
! 2786: return (0);
! 2787: }
! 2788:
! 2789: /**
! 2790: * xmlShell:
! 2791: * @doc: the initial document
! 2792: * @filename: the output buffer
! 2793: * @input: the line reading function
! 2794: * @output: the output FILE*, defaults to stdout if NULL
! 2795: *
! 2796: * Implements the XML shell
! 2797: * This allow to load, validate, view, modify and save a document
! 2798: * using a environment similar to a UNIX commandline.
! 2799: */
! 2800: void
! 2801: xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
! 2802: FILE * output)
! 2803: {
! 2804: char prompt[500] = "/ > ";
! 2805: char *cmdline = NULL, *cur;
! 2806: char command[100];
! 2807: char arg[400];
! 2808: int i;
! 2809: xmlShellCtxtPtr ctxt;
! 2810: xmlXPathObjectPtr list;
! 2811:
! 2812: if (doc == NULL)
! 2813: return;
! 2814: if (filename == NULL)
! 2815: return;
! 2816: if (input == NULL)
! 2817: return;
! 2818: if (output == NULL)
! 2819: output = stdout;
! 2820: ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
! 2821: if (ctxt == NULL)
! 2822: return;
! 2823: ctxt->loaded = 0;
! 2824: ctxt->doc = doc;
! 2825: ctxt->input = input;
! 2826: ctxt->output = output;
! 2827: ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
! 2828: ctxt->node = (xmlNodePtr) ctxt->doc;
! 2829:
! 2830: #ifdef LIBXML_XPATH_ENABLED
! 2831: ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
! 2832: if (ctxt->pctxt == NULL) {
! 2833: xmlFree(ctxt);
! 2834: return;
! 2835: }
! 2836: #endif /* LIBXML_XPATH_ENABLED */
! 2837: while (1) {
! 2838: if (ctxt->node == (xmlNodePtr) ctxt->doc)
! 2839: snprintf(prompt, sizeof(prompt), "%s > ", "/");
! 2840: else if ((ctxt->node != NULL) && (ctxt->node->name))
! 2841: snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
! 2842: else
! 2843: snprintf(prompt, sizeof(prompt), "? > ");
! 2844: prompt[sizeof(prompt) - 1] = 0;
! 2845:
! 2846: /*
! 2847: * Get a new command line
! 2848: */
! 2849: cmdline = ctxt->input(prompt);
! 2850: if (cmdline == NULL)
! 2851: break;
! 2852:
! 2853: /*
! 2854: * Parse the command itself
! 2855: */
! 2856: cur = cmdline;
! 2857: while ((*cur == ' ') || (*cur == '\t'))
! 2858: cur++;
! 2859: i = 0;
! 2860: while ((*cur != ' ') && (*cur != '\t') &&
! 2861: (*cur != '\n') && (*cur != '\r')) {
! 2862: if (*cur == 0)
! 2863: break;
! 2864: command[i++] = *cur++;
! 2865: }
! 2866: command[i] = 0;
! 2867: if (i == 0)
! 2868: continue;
! 2869:
! 2870: /*
! 2871: * Parse the argument
! 2872: */
! 2873: while ((*cur == ' ') || (*cur == '\t'))
! 2874: cur++;
! 2875: i = 0;
! 2876: while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
! 2877: if (*cur == 0)
! 2878: break;
! 2879: arg[i++] = *cur++;
! 2880: }
! 2881: arg[i] = 0;
! 2882:
! 2883: /*
! 2884: * start interpreting the command
! 2885: */
! 2886: if (!strcmp(command, "exit"))
! 2887: break;
! 2888: if (!strcmp(command, "quit"))
! 2889: break;
! 2890: if (!strcmp(command, "bye"))
! 2891: break;
! 2892: if (!strcmp(command, "help")) {
! 2893: fprintf(ctxt->output, "\tbase display XML base of the node\n");
! 2894: fprintf(ctxt->output, "\tsetbase URI change the XML base of the node\n");
! 2895: fprintf(ctxt->output, "\tbye leave shell\n");
! 2896: fprintf(ctxt->output, "\tcat [node] display node or current node\n");
! 2897: fprintf(ctxt->output, "\tcd [path] change directory to path or to root\n");
! 2898: fprintf(ctxt->output, "\tdir [path] dumps informations about the node (namespace, attributes, content)\n");
! 2899: fprintf(ctxt->output, "\tdu [path] show the structure of the subtree under path or the current node\n");
! 2900: fprintf(ctxt->output, "\texit leave shell\n");
! 2901: fprintf(ctxt->output, "\thelp display this help\n");
! 2902: fprintf(ctxt->output, "\tfree display memory usage\n");
! 2903: fprintf(ctxt->output, "\tload [name] load a new document with name\n");
! 2904: fprintf(ctxt->output, "\tls [path] list contents of path or the current directory\n");
! 2905: fprintf(ctxt->output, "\tset xml_fragment replace the current node content with the fragment parsed in context\n");
! 2906: #ifdef LIBXML_XPATH_ENABLED
! 2907: fprintf(ctxt->output, "\txpath expr evaluate the XPath expression in that context and print the result\n");
! 2908: fprintf(ctxt->output, "\tsetns nsreg register a namespace to a prefix in the XPath evaluation context\n");
! 2909: fprintf(ctxt->output, "\t format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix)\n");
! 2910: fprintf(ctxt->output, "\tsetrootns register all namespace found on the root element\n");
! 2911: fprintf(ctxt->output, "\t the default namespace if any uses 'defaultns' prefix\n");
! 2912: #endif /* LIBXML_XPATH_ENABLED */
! 2913: fprintf(ctxt->output, "\tpwd display current working directory\n");
! 2914: fprintf(ctxt->output, "\tquit leave shell\n");
! 2915: #ifdef LIBXML_OUTPUT_ENABLED
! 2916: fprintf(ctxt->output, "\tsave [name] save this document to name or the original name\n");
! 2917: fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n");
! 2918: #endif /* LIBXML_OUTPUT_ENABLED */
! 2919: #ifdef LIBXML_VALID_ENABLED
! 2920: fprintf(ctxt->output, "\tvalidate check the document for errors\n");
! 2921: #endif /* LIBXML_VALID_ENABLED */
! 2922: #ifdef LIBXML_SCHEMAS_ENABLED
! 2923: fprintf(ctxt->output, "\trelaxng rng validate the document agaisnt the Relax-NG schemas\n");
! 2924: #endif
! 2925: fprintf(ctxt->output, "\tgrep string search for a string in the subtree\n");
! 2926: #ifdef LIBXML_VALID_ENABLED
! 2927: } else if (!strcmp(command, "validate")) {
! 2928: xmlShellValidate(ctxt, arg, NULL, NULL);
! 2929: #endif /* LIBXML_VALID_ENABLED */
! 2930: } else if (!strcmp(command, "load")) {
! 2931: xmlShellLoad(ctxt, arg, NULL, NULL);
! 2932: #ifdef LIBXML_SCHEMAS_ENABLED
! 2933: } else if (!strcmp(command, "relaxng")) {
! 2934: xmlShellRNGValidate(ctxt, arg, NULL, NULL);
! 2935: #endif
! 2936: #ifdef LIBXML_OUTPUT_ENABLED
! 2937: } else if (!strcmp(command, "save")) {
! 2938: xmlShellSave(ctxt, arg, NULL, NULL);
! 2939: } else if (!strcmp(command, "write")) {
! 2940: if ((arg == NULL) || (arg[0] == 0))
! 2941: xmlGenericError(xmlGenericErrorContext,
! 2942: "Write command requires a filename argument\n");
! 2943: else
! 2944: xmlShellWrite(ctxt, arg, ctxt->node, NULL);
! 2945: #endif /* LIBXML_OUTPUT_ENABLED */
! 2946: } else if (!strcmp(command, "grep")) {
! 2947: xmlShellGrep(ctxt, arg, ctxt->node, NULL);
! 2948: } else if (!strcmp(command, "free")) {
! 2949: if (arg[0] == 0) {
! 2950: xmlMemShow(ctxt->output, 0);
! 2951: } else {
! 2952: int len = 0;
! 2953:
! 2954: sscanf(arg, "%d", &len);
! 2955: xmlMemShow(ctxt->output, len);
! 2956: }
! 2957: } else if (!strcmp(command, "pwd")) {
! 2958: char dir[500];
! 2959:
! 2960: if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
! 2961: fprintf(ctxt->output, "%s\n", dir);
! 2962: } else if (!strcmp(command, "du")) {
! 2963: xmlShellDu(ctxt, NULL, ctxt->node, NULL);
! 2964: } else if (!strcmp(command, "base")) {
! 2965: xmlShellBase(ctxt, NULL, ctxt->node, NULL);
! 2966: } else if (!strcmp(command, "set")) {
! 2967: xmlShellSetContent(ctxt, arg, ctxt->node, NULL);
! 2968: #ifdef LIBXML_XPATH_ENABLED
! 2969: } else if (!strcmp(command, "setns")) {
! 2970: if (arg[0] == 0) {
! 2971: xmlGenericError(xmlGenericErrorContext,
! 2972: "setns: prefix=[nsuri] required\n");
! 2973: } else {
! 2974: xmlShellRegisterNamespace(ctxt, arg, NULL, NULL);
! 2975: }
! 2976: } else if (!strcmp(command, "setrootns")) {
! 2977: xmlNodePtr root;
! 2978:
! 2979: root = xmlDocGetRootElement(ctxt->doc);
! 2980: xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL);
! 2981: } else if (!strcmp(command, "xpath")) {
! 2982: if (arg[0] == 0) {
! 2983: xmlGenericError(xmlGenericErrorContext,
! 2984: "xpath: expression required\n");
! 2985: } else {
! 2986: ctxt->pctxt->node = ctxt->node;
! 2987: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
! 2988: xmlXPathDebugDumpObject(ctxt->output, list, 0);
! 2989: xmlXPathFreeObject(list);
! 2990: }
! 2991: #endif /* LIBXML_XPATH_ENABLED */
! 2992: #ifdef LIBXML_TREE_ENABLED
! 2993: } else if (!strcmp(command, "setbase")) {
! 2994: xmlShellSetBase(ctxt, arg, ctxt->node, NULL);
! 2995: #endif
! 2996: } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
! 2997: int dir = (!strcmp(command, "dir"));
! 2998:
! 2999: if (arg[0] == 0) {
! 3000: if (dir)
! 3001: xmlShellDir(ctxt, NULL, ctxt->node, NULL);
! 3002: else
! 3003: xmlShellList(ctxt, NULL, ctxt->node, NULL);
! 3004: } else {
! 3005: ctxt->pctxt->node = ctxt->node;
! 3006: #ifdef LIBXML_XPATH_ENABLED
! 3007: ctxt->pctxt->node = ctxt->node;
! 3008: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
! 3009: #else
! 3010: list = NULL;
! 3011: #endif /* LIBXML_XPATH_ENABLED */
! 3012: if (list != NULL) {
! 3013: switch (list->type) {
! 3014: case XPATH_UNDEFINED:
! 3015: xmlGenericError(xmlGenericErrorContext,
! 3016: "%s: no such node\n", arg);
! 3017: break;
! 3018: case XPATH_NODESET:{
! 3019: int indx;
! 3020:
! 3021: if (list->nodesetval == NULL)
! 3022: break;
! 3023:
! 3024: for (indx = 0;
! 3025: indx < list->nodesetval->nodeNr;
! 3026: indx++) {
! 3027: if (dir)
! 3028: xmlShellDir(ctxt, NULL,
! 3029: list->nodesetval->
! 3030: nodeTab[indx], NULL);
! 3031: else
! 3032: xmlShellList(ctxt, NULL,
! 3033: list->nodesetval->
! 3034: nodeTab[indx], NULL);
! 3035: }
! 3036: break;
! 3037: }
! 3038: case XPATH_BOOLEAN:
! 3039: xmlGenericError(xmlGenericErrorContext,
! 3040: "%s is a Boolean\n", arg);
! 3041: break;
! 3042: case XPATH_NUMBER:
! 3043: xmlGenericError(xmlGenericErrorContext,
! 3044: "%s is a number\n", arg);
! 3045: break;
! 3046: case XPATH_STRING:
! 3047: xmlGenericError(xmlGenericErrorContext,
! 3048: "%s is a string\n", arg);
! 3049: break;
! 3050: case XPATH_POINT:
! 3051: xmlGenericError(xmlGenericErrorContext,
! 3052: "%s is a point\n", arg);
! 3053: break;
! 3054: case XPATH_RANGE:
! 3055: xmlGenericError(xmlGenericErrorContext,
! 3056: "%s is a range\n", arg);
! 3057: break;
! 3058: case XPATH_LOCATIONSET:
! 3059: xmlGenericError(xmlGenericErrorContext,
! 3060: "%s is a range\n", arg);
! 3061: break;
! 3062: case XPATH_USERS:
! 3063: xmlGenericError(xmlGenericErrorContext,
! 3064: "%s is user-defined\n", arg);
! 3065: break;
! 3066: case XPATH_XSLT_TREE:
! 3067: xmlGenericError(xmlGenericErrorContext,
! 3068: "%s is an XSLT value tree\n",
! 3069: arg);
! 3070: break;
! 3071: }
! 3072: #ifdef LIBXML_XPATH_ENABLED
! 3073: xmlXPathFreeObject(list);
! 3074: #endif
! 3075: } else {
! 3076: xmlGenericError(xmlGenericErrorContext,
! 3077: "%s: no such node\n", arg);
! 3078: }
! 3079: ctxt->pctxt->node = NULL;
! 3080: }
! 3081: } else if (!strcmp(command, "cd")) {
! 3082: if (arg[0] == 0) {
! 3083: ctxt->node = (xmlNodePtr) ctxt->doc;
! 3084: } else {
! 3085: #ifdef LIBXML_XPATH_ENABLED
! 3086: ctxt->pctxt->node = ctxt->node;
! 3087: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
! 3088: #else
! 3089: list = NULL;
! 3090: #endif /* LIBXML_XPATH_ENABLED */
! 3091: if (list != NULL) {
! 3092: switch (list->type) {
! 3093: case XPATH_UNDEFINED:
! 3094: xmlGenericError(xmlGenericErrorContext,
! 3095: "%s: no such node\n", arg);
! 3096: break;
! 3097: case XPATH_NODESET:
! 3098: if (list->nodesetval != NULL) {
! 3099: if (list->nodesetval->nodeNr == 1) {
! 3100: ctxt->node = list->nodesetval->nodeTab[0];
! 3101: if ((ctxt->node != NULL) &&
! 3102: (ctxt->node->type ==
! 3103: XML_NAMESPACE_DECL)) {
! 3104: xmlGenericError(xmlGenericErrorContext,
! 3105: "cannot cd to namespace\n");
! 3106: ctxt->node = NULL;
! 3107: }
! 3108: } else
! 3109: xmlGenericError(xmlGenericErrorContext,
! 3110: "%s is a %d Node Set\n",
! 3111: arg,
! 3112: list->nodesetval->nodeNr);
! 3113: } else
! 3114: xmlGenericError(xmlGenericErrorContext,
! 3115: "%s is an empty Node Set\n",
! 3116: arg);
! 3117: break;
! 3118: case XPATH_BOOLEAN:
! 3119: xmlGenericError(xmlGenericErrorContext,
! 3120: "%s is a Boolean\n", arg);
! 3121: break;
! 3122: case XPATH_NUMBER:
! 3123: xmlGenericError(xmlGenericErrorContext,
! 3124: "%s is a number\n", arg);
! 3125: break;
! 3126: case XPATH_STRING:
! 3127: xmlGenericError(xmlGenericErrorContext,
! 3128: "%s is a string\n", arg);
! 3129: break;
! 3130: case XPATH_POINT:
! 3131: xmlGenericError(xmlGenericErrorContext,
! 3132: "%s is a point\n", arg);
! 3133: break;
! 3134: case XPATH_RANGE:
! 3135: xmlGenericError(xmlGenericErrorContext,
! 3136: "%s is a range\n", arg);
! 3137: break;
! 3138: case XPATH_LOCATIONSET:
! 3139: xmlGenericError(xmlGenericErrorContext,
! 3140: "%s is a range\n", arg);
! 3141: break;
! 3142: case XPATH_USERS:
! 3143: xmlGenericError(xmlGenericErrorContext,
! 3144: "%s is user-defined\n", arg);
! 3145: break;
! 3146: case XPATH_XSLT_TREE:
! 3147: xmlGenericError(xmlGenericErrorContext,
! 3148: "%s is an XSLT value tree\n",
! 3149: arg);
! 3150: break;
! 3151: }
! 3152: #ifdef LIBXML_XPATH_ENABLED
! 3153: xmlXPathFreeObject(list);
! 3154: #endif
! 3155: } else {
! 3156: xmlGenericError(xmlGenericErrorContext,
! 3157: "%s: no such node\n", arg);
! 3158: }
! 3159: ctxt->pctxt->node = NULL;
! 3160: }
! 3161: #ifdef LIBXML_OUTPUT_ENABLED
! 3162: } else if (!strcmp(command, "cat")) {
! 3163: if (arg[0] == 0) {
! 3164: xmlShellCat(ctxt, NULL, ctxt->node, NULL);
! 3165: } else {
! 3166: ctxt->pctxt->node = ctxt->node;
! 3167: #ifdef LIBXML_XPATH_ENABLED
! 3168: ctxt->pctxt->node = ctxt->node;
! 3169: list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
! 3170: #else
! 3171: list = NULL;
! 3172: #endif /* LIBXML_XPATH_ENABLED */
! 3173: if (list != NULL) {
! 3174: switch (list->type) {
! 3175: case XPATH_UNDEFINED:
! 3176: xmlGenericError(xmlGenericErrorContext,
! 3177: "%s: no such node\n", arg);
! 3178: break;
! 3179: case XPATH_NODESET:{
! 3180: int indx;
! 3181:
! 3182: if (list->nodesetval == NULL)
! 3183: break;
! 3184:
! 3185: for (indx = 0;
! 3186: indx < list->nodesetval->nodeNr;
! 3187: indx++) {
! 3188: if (i > 0)
! 3189: fprintf(ctxt->output, " -------\n");
! 3190: xmlShellCat(ctxt, NULL,
! 3191: list->nodesetval->
! 3192: nodeTab[indx], NULL);
! 3193: }
! 3194: break;
! 3195: }
! 3196: case XPATH_BOOLEAN:
! 3197: xmlGenericError(xmlGenericErrorContext,
! 3198: "%s is a Boolean\n", arg);
! 3199: break;
! 3200: case XPATH_NUMBER:
! 3201: xmlGenericError(xmlGenericErrorContext,
! 3202: "%s is a number\n", arg);
! 3203: break;
! 3204: case XPATH_STRING:
! 3205: xmlGenericError(xmlGenericErrorContext,
! 3206: "%s is a string\n", arg);
! 3207: break;
! 3208: case XPATH_POINT:
! 3209: xmlGenericError(xmlGenericErrorContext,
! 3210: "%s is a point\n", arg);
! 3211: break;
! 3212: case XPATH_RANGE:
! 3213: xmlGenericError(xmlGenericErrorContext,
! 3214: "%s is a range\n", arg);
! 3215: break;
! 3216: case XPATH_LOCATIONSET:
! 3217: xmlGenericError(xmlGenericErrorContext,
! 3218: "%s is a range\n", arg);
! 3219: break;
! 3220: case XPATH_USERS:
! 3221: xmlGenericError(xmlGenericErrorContext,
! 3222: "%s is user-defined\n", arg);
! 3223: break;
! 3224: case XPATH_XSLT_TREE:
! 3225: xmlGenericError(xmlGenericErrorContext,
! 3226: "%s is an XSLT value tree\n",
! 3227: arg);
! 3228: break;
! 3229: }
! 3230: #ifdef LIBXML_XPATH_ENABLED
! 3231: xmlXPathFreeObject(list);
! 3232: #endif
! 3233: } else {
! 3234: xmlGenericError(xmlGenericErrorContext,
! 3235: "%s: no such node\n", arg);
! 3236: }
! 3237: ctxt->pctxt->node = NULL;
! 3238: }
! 3239: #endif /* LIBXML_OUTPUT_ENABLED */
! 3240: } else {
! 3241: xmlGenericError(xmlGenericErrorContext,
! 3242: "Unknown command %s\n", command);
! 3243: }
! 3244: free(cmdline); /* not xmlFree here ! */
! 3245: cmdline = NULL;
! 3246: }
! 3247: #ifdef LIBXML_XPATH_ENABLED
! 3248: xmlXPathFreeContext(ctxt->pctxt);
! 3249: #endif /* LIBXML_XPATH_ENABLED */
! 3250: if (ctxt->loaded) {
! 3251: xmlFreeDoc(ctxt->doc);
! 3252: }
! 3253: if (ctxt->filename != NULL)
! 3254: xmlFree(ctxt->filename);
! 3255: xmlFree(ctxt);
! 3256: if (cmdline != NULL)
! 3257: free(cmdline); /* not xmlFree here ! */
! 3258: }
! 3259:
! 3260: #endif /* LIBXML_XPATH_ENABLED */
! 3261: #define bottom_debugXML
! 3262: #include "elfgcchack.h"
! 3263: #endif /* LIBXML_DEBUG_ENABLED */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>