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>