Annotation of embedaddon/libxml2/debugXML.c, revision 1.1.1.2

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:
1.1.1.2 ! misho    1727:            if (node->name != NULL) {
        !          1728:                 if ((node->ns != NULL) && (node->ns->prefix != NULL))
        !          1729:                     fprintf(output, "%s:", node->ns->prefix);
1.1       misho    1730:                fprintf(output, "%s", (const char *) node->name);
1.1.1.2 ! misho    1731:             }
1.1       misho    1732:            break;
                   1733:        case XML_ATTRIBUTE_NODE:
                   1734:            if (node->name != NULL)
                   1735:                fprintf(output, "%s", (const char *) node->name);
                   1736:            break;
                   1737:        case XML_TEXT_NODE:
                   1738:            if (node->content != NULL) {
                   1739:                xmlDebugDumpString(output, node->content);
                   1740:             }
                   1741:            break;
                   1742:        case XML_CDATA_SECTION_NODE:
                   1743:            break;
                   1744:        case XML_ENTITY_REF_NODE:
                   1745:            if (node->name != NULL)
                   1746:                fprintf(output, "%s", (const char *) node->name);
                   1747:            break;
                   1748:        case XML_ENTITY_NODE:
                   1749:            if (node->name != NULL)
                   1750:                fprintf(output, "%s", (const char *) node->name);
                   1751:            break;
                   1752:        case XML_PI_NODE:
                   1753:            if (node->name != NULL)
                   1754:                fprintf(output, "%s", (const char *) node->name);
                   1755:            break;
                   1756:        case XML_COMMENT_NODE:
                   1757:            break;
                   1758:        case XML_DOCUMENT_NODE:
                   1759:            break;
                   1760:        case XML_HTML_DOCUMENT_NODE:
                   1761:            break;
                   1762:        case XML_DOCUMENT_TYPE_NODE:
                   1763:            break;
                   1764:        case XML_DOCUMENT_FRAG_NODE:
                   1765:            break;
                   1766:        case XML_NOTATION_NODE:
                   1767:            break;
                   1768:        case XML_NAMESPACE_DECL: {
                   1769:            xmlNsPtr ns = (xmlNsPtr) node;
                   1770: 
                   1771:            if (ns->prefix == NULL)
                   1772:                fprintf(output, "default -> %s", (char *)ns->href);
                   1773:            else
                   1774:                fprintf(output, "%s -> %s", (char *)ns->prefix,
                   1775:                        (char *)ns->href);
                   1776:            break;
                   1777:        }
                   1778:        default:
                   1779:            if (node->name != NULL)
                   1780:                fprintf(output, "%s", (const char *) node->name);
                   1781:     }
                   1782:     fprintf(output, "\n");
                   1783: }
                   1784: 
                   1785: /**
                   1786:  * xmlBoolToText:
                   1787:  * @boolval: a bool to turn into text
                   1788:  *
                   1789:  * Convenient way to turn bool into text 
                   1790:  *
                   1791:  * Returns a pointer to either "True" or "False"
                   1792:  */
                   1793: const char *
                   1794: xmlBoolToText(int boolval)
                   1795: {
                   1796:     if (boolval)
                   1797:         return("True");
                   1798:     else
                   1799:         return("False");
                   1800: }
                   1801: 
                   1802: #ifdef LIBXML_XPATH_ENABLED
                   1803: /****************************************************************
                   1804:  *                                                             *
                   1805:  *             The XML shell related functions                 *
                   1806:  *                                                             *
                   1807:  ****************************************************************/
                   1808: 
                   1809: 
                   1810: 
                   1811: /*
                   1812:  * TODO: Improvement/cleanups for the XML shell
                   1813:  *     - allow to shell out an editor on a subpart
                   1814:  *     - cleanup function registrations (with help) and calling
                   1815:  *     - provide registration routines
                   1816:  */
                   1817: 
                   1818: /**
                   1819:  * xmlShellPrintXPathError:
                   1820:  * @errorType: valid xpath error id
                   1821:  * @arg: the argument that cause xpath to fail
                   1822:  *
                   1823:  * Print the xpath error to libxml default error channel
                   1824:  */
                   1825: void
                   1826: xmlShellPrintXPathError(int errorType, const char *arg)
                   1827: {
                   1828:     const char *default_arg = "Result";
                   1829: 
                   1830:     if (!arg)
                   1831:         arg = default_arg;
                   1832: 
                   1833:     switch (errorType) {
                   1834:         case XPATH_UNDEFINED:
                   1835:             xmlGenericError(xmlGenericErrorContext,
                   1836:                             "%s: no such node\n", arg);
                   1837:             break;
                   1838: 
                   1839:         case XPATH_BOOLEAN:
                   1840:             xmlGenericError(xmlGenericErrorContext,
                   1841:                             "%s is a Boolean\n", arg);
                   1842:             break;
                   1843:         case XPATH_NUMBER:
                   1844:             xmlGenericError(xmlGenericErrorContext,
                   1845:                             "%s is a number\n", arg);
                   1846:             break;
                   1847:         case XPATH_STRING:
                   1848:             xmlGenericError(xmlGenericErrorContext,
                   1849:                             "%s is a string\n", arg);
                   1850:             break;
                   1851:         case XPATH_POINT:
                   1852:             xmlGenericError(xmlGenericErrorContext,
                   1853:                             "%s is a point\n", arg);
                   1854:             break;
                   1855:         case XPATH_RANGE:
                   1856:             xmlGenericError(xmlGenericErrorContext,
                   1857:                             "%s is a range\n", arg);
                   1858:             break;
                   1859:         case XPATH_LOCATIONSET:
                   1860:             xmlGenericError(xmlGenericErrorContext,
                   1861:                             "%s is a range\n", arg);
                   1862:             break;
                   1863:         case XPATH_USERS:
                   1864:             xmlGenericError(xmlGenericErrorContext,
                   1865:                             "%s is user-defined\n", arg);
                   1866:             break;
                   1867:         case XPATH_XSLT_TREE:
                   1868:             xmlGenericError(xmlGenericErrorContext,
                   1869:                             "%s is an XSLT value tree\n", arg);
                   1870:             break;
                   1871:     }
                   1872: #if 0
                   1873:     xmlGenericError(xmlGenericErrorContext,
                   1874:                     "Try casting the result string function (xpath builtin)\n",
                   1875:                     arg);
                   1876: #endif
                   1877: }
                   1878: 
                   1879: 
                   1880: #ifdef LIBXML_OUTPUT_ENABLED
                   1881: /**
                   1882:  * xmlShellPrintNodeCtxt:
                   1883:  * @ctxt : a non-null shell context
                   1884:  * @node : a non-null node to print to the output FILE
                   1885:  *
                   1886:  * Print node to the output FILE
                   1887:  */
                   1888: static void
                   1889: xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node)
                   1890: {
                   1891:     FILE *fp;
                   1892: 
                   1893:     if (!node)
                   1894:         return;
                   1895:     if (ctxt == NULL)
                   1896:        fp = stdout;
                   1897:     else
                   1898:        fp = ctxt->output;
                   1899: 
                   1900:     if (node->type == XML_DOCUMENT_NODE)
                   1901:         xmlDocDump(fp, (xmlDocPtr) node);
                   1902:     else if (node->type == XML_ATTRIBUTE_NODE)
                   1903:         xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0);
                   1904:     else
                   1905:         xmlElemDump(fp, node->doc, node);
                   1906: 
                   1907:     fprintf(fp, "\n");
                   1908: }
                   1909: 
                   1910: /**
                   1911:  * xmlShellPrintNode:
                   1912:  * @node : a non-null node to print to the output FILE
                   1913:  *
                   1914:  * Print node to the output FILE
                   1915:  */
                   1916: void
                   1917: xmlShellPrintNode(xmlNodePtr node)
                   1918: {
                   1919:     xmlShellPrintNodeCtxt(NULL, node);
                   1920: }
                   1921: #endif /* LIBXML_OUTPUT_ENABLED */
                   1922: 
                   1923: /**
                   1924:  * xmlShellPrintXPathResultCtxt:
                   1925:  * @ctxt: a valid shell context
                   1926:  * @list: a valid result generated by an xpath evaluation
                   1927:  *
                   1928:  * Prints result to the output FILE
                   1929:  */
                   1930: static void
                   1931: xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
                   1932: {
                   1933:     if (!ctxt)
                   1934:        return;
                   1935: 
                   1936:     if (list != NULL) {
                   1937:         switch (list->type) {
                   1938:             case XPATH_NODESET:{
                   1939: #ifdef LIBXML_OUTPUT_ENABLED
                   1940:                     int indx;
                   1941: 
                   1942:                     if (list->nodesetval) {
                   1943:                         for (indx = 0; indx < list->nodesetval->nodeNr;
                   1944:                              indx++) {
                   1945:                             xmlShellPrintNodeCtxt(ctxt,
                   1946:                                    list->nodesetval->nodeTab[indx]);
                   1947:                         }
                   1948:                     } else {
                   1949:                         xmlGenericError(xmlGenericErrorContext,
                   1950:                                         "Empty node set\n");
                   1951:                     }
                   1952:                     break;
                   1953: #else
                   1954:                    xmlGenericError(xmlGenericErrorContext,
                   1955:                                    "Node set\n");
                   1956: #endif /* LIBXML_OUTPUT_ENABLED */
                   1957:                 }
                   1958:             case XPATH_BOOLEAN:
                   1959:                 xmlGenericError(xmlGenericErrorContext,
                   1960:                                 "Is a Boolean:%s\n",
                   1961:                                 xmlBoolToText(list->boolval));
                   1962:                 break;
                   1963:             case XPATH_NUMBER:
                   1964:                 xmlGenericError(xmlGenericErrorContext,
                   1965:                                 "Is a number:%0g\n", list->floatval);
                   1966:                 break;
                   1967:             case XPATH_STRING:
                   1968:                 xmlGenericError(xmlGenericErrorContext,
                   1969:                                 "Is a string:%s\n", list->stringval);
                   1970:                 break;
                   1971: 
                   1972:             default:
                   1973:                 xmlShellPrintXPathError(list->type, NULL);
                   1974:         }
                   1975:     }
                   1976: }
                   1977: 
                   1978: /**
                   1979:  * xmlShellPrintXPathResult:
                   1980:  * @list: a valid result generated by an xpath evaluation
                   1981:  *
                   1982:  * Prints result to the output FILE
                   1983:  */
                   1984: void
                   1985: xmlShellPrintXPathResult(xmlXPathObjectPtr list)
                   1986: {
                   1987:     xmlShellPrintXPathResultCtxt(NULL, list);
                   1988: }
                   1989: 
                   1990: /**
                   1991:  * xmlShellList:
                   1992:  * @ctxt:  the shell context
                   1993:  * @arg:  unused
                   1994:  * @node:  a node
                   1995:  * @node2:  unused
                   1996:  *
                   1997:  * Implements the XML shell function "ls"
                   1998:  * Does an Unix like listing of the given node (like a directory)
                   1999:  *
                   2000:  * Returns 0
                   2001:  */
                   2002: int
                   2003: xmlShellList(xmlShellCtxtPtr ctxt,
                   2004:              char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
                   2005:              xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2006: {
                   2007:     xmlNodePtr cur;
                   2008:     if (!ctxt)
                   2009:         return (0);
                   2010:     if (node == NULL) {
                   2011:        fprintf(ctxt->output, "NULL\n");
                   2012:        return (0);
                   2013:     }
                   2014:     if ((node->type == XML_DOCUMENT_NODE) ||
                   2015:         (node->type == XML_HTML_DOCUMENT_NODE)) {
                   2016:         cur = ((xmlDocPtr) node)->children;
                   2017:     } else if (node->type == XML_NAMESPACE_DECL) {
                   2018:         xmlLsOneNode(ctxt->output, node);
                   2019:         return (0);
                   2020:     } else if (node->children != NULL) {
                   2021:         cur = node->children;
                   2022:     } else {
                   2023:         xmlLsOneNode(ctxt->output, node);
                   2024:         return (0);
                   2025:     }
                   2026:     while (cur != NULL) {
                   2027:         xmlLsOneNode(ctxt->output, cur);
                   2028:         cur = cur->next;
                   2029:     }
                   2030:     return (0);
                   2031: }
                   2032: 
                   2033: /**
                   2034:  * xmlShellBase:
                   2035:  * @ctxt:  the shell context
                   2036:  * @arg:  unused
                   2037:  * @node:  a node
                   2038:  * @node2:  unused
                   2039:  *
                   2040:  * Implements the XML shell function "base"
                   2041:  * dumps the current XML base of the node
                   2042:  *
                   2043:  * Returns 0
                   2044:  */
                   2045: int
                   2046: xmlShellBase(xmlShellCtxtPtr ctxt,
                   2047:              char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
                   2048:              xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2049: {
                   2050:     xmlChar *base;
                   2051:     if (!ctxt)
                   2052:         return 0;
                   2053:     if (node == NULL) {
                   2054:        fprintf(ctxt->output, "NULL\n");
                   2055:        return (0);
                   2056:     }    
                   2057: 
                   2058:     base = xmlNodeGetBase(node->doc, node);
                   2059: 
                   2060:     if (base == NULL) {
                   2061:         fprintf(ctxt->output, " No base found !!!\n");
                   2062:     } else {
                   2063:         fprintf(ctxt->output, "%s\n", base);
                   2064:         xmlFree(base);
                   2065:     }
                   2066:     return (0);
                   2067: }
                   2068: 
                   2069: #ifdef LIBXML_TREE_ENABLED
                   2070: /**
                   2071:  * xmlShellSetBase:
                   2072:  * @ctxt:  the shell context
                   2073:  * @arg:  the new base
                   2074:  * @node:  a node
                   2075:  * @node2:  unused
                   2076:  *
                   2077:  * Implements the XML shell function "setbase"
                   2078:  * change the current XML base of the node
                   2079:  *
                   2080:  * Returns 0
                   2081:  */
                   2082: static int
                   2083: xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
                   2084:              char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
                   2085:              xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2086: {
                   2087:     xmlNodeSetBase(node, (xmlChar*) arg);
                   2088:     return (0);
                   2089: }
                   2090: #endif
                   2091: 
                   2092: #ifdef LIBXML_XPATH_ENABLED
                   2093: /**
                   2094:  * xmlShellRegisterNamespace:
                   2095:  * @ctxt:  the shell context
                   2096:  * @arg:  a string in prefix=nsuri format
                   2097:  * @node:  unused
                   2098:  * @node2:  unused
                   2099:  *
                   2100:  * Implements the XML shell function "setns"
                   2101:  * register/unregister a prefix=namespace pair
                   2102:  * on the XPath context
                   2103:  *
                   2104:  * Returns 0 on success and a negative value otherwise.
                   2105:  */
                   2106: static int
                   2107: xmlShellRegisterNamespace(xmlShellCtxtPtr ctxt, char *arg,
                   2108:       xmlNodePtr node ATTRIBUTE_UNUSED, xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2109: {
                   2110:     xmlChar* nsListDup;
                   2111:     xmlChar* prefix;
                   2112:     xmlChar* href;
                   2113:     xmlChar* next;
                   2114: 
                   2115:     nsListDup = xmlStrdup((xmlChar *) arg);
                   2116:     next = nsListDup;
                   2117:     while(next != NULL) {
                   2118:        /* skip spaces */
                   2119:        /*while((*next) == ' ') next++;*/
                   2120:        if((*next) == '\0') break;
                   2121: 
                   2122:        /* find prefix */
                   2123:        prefix = next;
                   2124:        next = (xmlChar*)xmlStrchr(next, '=');
                   2125:        if(next == NULL) {
                   2126:            fprintf(ctxt->output, "setns: prefix=[nsuri] required\n");
                   2127:            xmlFree(nsListDup);
                   2128:            return(-1);
                   2129:        }
                   2130:        *(next++) = '\0';
                   2131: 
                   2132:        /* find href */
                   2133:        href = next;
                   2134:        next = (xmlChar*)xmlStrchr(next, ' ');
                   2135:        if(next != NULL) {
                   2136:            *(next++) = '\0';
                   2137:        }
                   2138: 
                   2139:        /* do register namespace */
                   2140:        if(xmlXPathRegisterNs(ctxt->pctxt, prefix, href) != 0) {
                   2141:            fprintf(ctxt->output,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href);
                   2142:            xmlFree(nsListDup);
                   2143:            return(-1);
                   2144:        }
                   2145:     }
                   2146: 
                   2147:     xmlFree(nsListDup);
                   2148:     return(0);
                   2149: }
                   2150: /**
                   2151:  * xmlShellRegisterRootNamespaces:
                   2152:  * @ctxt:  the shell context
                   2153:  * @arg:  unused
                   2154:  * @node:  the root element
                   2155:  * @node2:  unused
                   2156:  *
                   2157:  * Implements the XML shell function "setrootns"
                   2158:  * which registers all namespaces declarations found on the root element.
                   2159:  *
                   2160:  * Returns 0 on success and a negative value otherwise.
                   2161:  */
                   2162: static int
                   2163: xmlShellRegisterRootNamespaces(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
                   2164:       xmlNodePtr root, xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2165: {
                   2166:     xmlNsPtr ns;
                   2167: 
                   2168:     if ((root == NULL) || (root->type != XML_ELEMENT_NODE) ||
                   2169:         (root->nsDef == NULL) || (ctxt == NULL) || (ctxt->pctxt == NULL))
                   2170:        return(-1);
                   2171:     ns = root->nsDef;
                   2172:     while (ns != NULL) {
                   2173:         if (ns->prefix == NULL)
                   2174:            xmlXPathRegisterNs(ctxt->pctxt, BAD_CAST "defaultns", ns->href);
                   2175:        else
                   2176:            xmlXPathRegisterNs(ctxt->pctxt, ns->prefix, ns->href);
                   2177:         ns = ns->next;
                   2178:     }
                   2179:     return(0);
                   2180: }
                   2181: #endif
                   2182: 
                   2183: /**
                   2184:  * xmlShellGrep:
                   2185:  * @ctxt:  the shell context
                   2186:  * @arg:  the string or regular expression to find
                   2187:  * @node:  a node
                   2188:  * @node2:  unused
                   2189:  *
                   2190:  * Implements the XML shell function "grep"
                   2191:  * dumps informations about the node (namespace, attributes, content).
                   2192:  *
                   2193:  * Returns 0
                   2194:  */
                   2195: static int
                   2196: xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
                   2197:             char *arg, xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2198: {
                   2199:     if (!ctxt)
                   2200:         return (0);
                   2201:     if (node == NULL)
                   2202:        return (0);
                   2203:     if (arg == NULL)
                   2204:        return (0);
                   2205: #ifdef LIBXML_REGEXP_ENABLED
                   2206:     if ((xmlStrchr((xmlChar *) arg, '?')) ||
                   2207:        (xmlStrchr((xmlChar *) arg, '*')) ||
                   2208:        (xmlStrchr((xmlChar *) arg, '.')) ||
                   2209:        (xmlStrchr((xmlChar *) arg, '['))) {
                   2210:     }
                   2211: #endif
                   2212:     while (node != NULL) {
                   2213:         if (node->type == XML_COMMENT_NODE) {
                   2214:            if (xmlStrstr(node->content, (xmlChar *) arg)) {
                   2215: 
                   2216:                fprintf(ctxt->output, "%s : ", xmlGetNodePath(node));
                   2217:                 xmlShellList(ctxt, NULL, node, NULL);
                   2218:            }
                   2219:         } else if (node->type == XML_TEXT_NODE) {
                   2220:            if (xmlStrstr(node->content, (xmlChar *) arg)) {
                   2221: 
                   2222:                fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent));
                   2223:                 xmlShellList(ctxt, NULL, node->parent, NULL);
                   2224:            }
                   2225:         }
                   2226: 
                   2227:         /*
                   2228:          * Browse the full subtree, deep first
                   2229:          */
                   2230: 
                   2231:         if ((node->type == XML_DOCUMENT_NODE) ||
                   2232:             (node->type == XML_HTML_DOCUMENT_NODE)) {
                   2233:             node = ((xmlDocPtr) node)->children;
                   2234:         } else if ((node->children != NULL)
                   2235:                    && (node->type != XML_ENTITY_REF_NODE)) {
                   2236:             /* deep first */
                   2237:             node = node->children;
                   2238:         } else if (node->next != NULL) {
                   2239:             /* then siblings */
                   2240:             node = node->next;
                   2241:         } else {
                   2242:             /* go up to parents->next if needed */
                   2243:             while (node != NULL) {
                   2244:                 if (node->parent != NULL) {
                   2245:                     node = node->parent;
                   2246:                 }
                   2247:                 if (node->next != NULL) {
                   2248:                     node = node->next;
                   2249:                     break;
                   2250:                 }
                   2251:                 if (node->parent == NULL) {
                   2252:                     node = NULL;
                   2253:                     break;
                   2254:                 }
                   2255:             }
                   2256:        }
                   2257:     }
                   2258:     return (0);
                   2259: }
                   2260: 
                   2261: /**
                   2262:  * xmlShellDir:
                   2263:  * @ctxt:  the shell context
                   2264:  * @arg:  unused
                   2265:  * @node:  a node
                   2266:  * @node2:  unused
                   2267:  *
                   2268:  * Implements the XML shell function "dir"
                   2269:  * dumps informations about the node (namespace, attributes, content).
                   2270:  *
                   2271:  * Returns 0
                   2272:  */
                   2273: int
                   2274: xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
                   2275:             char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
                   2276:             xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2277: {
                   2278:     if (!ctxt)
                   2279:         return (0);
                   2280:     if (node == NULL) {
                   2281:        fprintf(ctxt->output, "NULL\n");
                   2282:        return (0);
                   2283:     }    
                   2284:     if ((node->type == XML_DOCUMENT_NODE) ||
                   2285:         (node->type == XML_HTML_DOCUMENT_NODE)) {
                   2286:         xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node);
                   2287:     } else if (node->type == XML_ATTRIBUTE_NODE) {
                   2288:         xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0);
                   2289:     } else {
                   2290:         xmlDebugDumpOneNode(ctxt->output, node, 0);
                   2291:     }
                   2292:     return (0);
                   2293: }
                   2294: 
                   2295: /**
                   2296:  * xmlShellSetContent:
                   2297:  * @ctxt:  the shell context
                   2298:  * @value:  the content as a string
                   2299:  * @node:  a node
                   2300:  * @node2:  unused
                   2301:  *
                   2302:  * Implements the XML shell function "dir"
                   2303:  * dumps informations about the node (namespace, attributes, content).
                   2304:  *
                   2305:  * Returns 0
                   2306:  */
                   2307: static int
                   2308: xmlShellSetContent(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
                   2309:             char *value, xmlNodePtr node,
                   2310:             xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2311: {
                   2312:     xmlNodePtr results;
                   2313:     xmlParserErrors ret;
                   2314: 
                   2315:     if (!ctxt)
                   2316:         return (0);
                   2317:     if (node == NULL) {
                   2318:        fprintf(ctxt->output, "NULL\n");
                   2319:        return (0);
                   2320:     }
                   2321:     if (value == NULL) {
                   2322:         fprintf(ctxt->output, "NULL\n");
                   2323:        return (0);
                   2324:     }
                   2325: 
                   2326:     ret = xmlParseInNodeContext(node, value, strlen(value), 0, &results);
                   2327:     if (ret == XML_ERR_OK) {
                   2328:        if (node->children != NULL) {
                   2329:            xmlFreeNodeList(node->children);
                   2330:            node->children = NULL;
                   2331:            node->last = NULL;
                   2332:        }
                   2333:        xmlAddChildList(node, results);
                   2334:     } else {
                   2335:         fprintf(ctxt->output, "failed to parse content\n");
                   2336:     }
                   2337:     return (0);
                   2338: }
                   2339: 
                   2340: #ifdef LIBXML_SCHEMAS_ENABLED
                   2341: /**
                   2342:  * xmlShellRNGValidate:
                   2343:  * @ctxt:  the shell context
                   2344:  * @schemas:  the path to the Relax-NG schemas
                   2345:  * @node:  a node
                   2346:  * @node2:  unused
                   2347:  *
                   2348:  * Implements the XML shell function "relaxng"
                   2349:  * validating the instance against a Relax-NG schemas
                   2350:  *
                   2351:  * Returns 0
                   2352:  */
                   2353: static int
                   2354: xmlShellRNGValidate(xmlShellCtxtPtr sctxt, char *schemas,
                   2355:             xmlNodePtr node ATTRIBUTE_UNUSED,
                   2356:            xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2357: {
                   2358:     xmlRelaxNGPtr relaxngschemas;
                   2359:     xmlRelaxNGParserCtxtPtr ctxt;
                   2360:     xmlRelaxNGValidCtxtPtr vctxt;
                   2361:     int ret;
                   2362: 
                   2363:     ctxt = xmlRelaxNGNewParserCtxt(schemas);
                   2364:     xmlRelaxNGSetParserErrors(ctxt,
                   2365:            (xmlRelaxNGValidityErrorFunc) fprintf,
                   2366:            (xmlRelaxNGValidityWarningFunc) fprintf,
                   2367:            stderr);
                   2368:     relaxngschemas = xmlRelaxNGParse(ctxt);
                   2369:     xmlRelaxNGFreeParserCtxt(ctxt);
                   2370:     if (relaxngschemas == NULL) {
                   2371:        xmlGenericError(xmlGenericErrorContext,
                   2372:                "Relax-NG schema %s failed to compile\n", schemas);
                   2373:        return(-1);
                   2374:     }
                   2375:     vctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
                   2376:     xmlRelaxNGSetValidErrors(vctxt,
                   2377:            (xmlRelaxNGValidityErrorFunc) fprintf,
                   2378:            (xmlRelaxNGValidityWarningFunc) fprintf,
                   2379:            stderr);
                   2380:     ret = xmlRelaxNGValidateDoc(vctxt, sctxt->doc);
                   2381:     if (ret == 0) {
                   2382:        fprintf(stderr, "%s validates\n", sctxt->filename);
                   2383:     } else if (ret > 0) {
                   2384:        fprintf(stderr, "%s fails to validate\n", sctxt->filename);
                   2385:     } else {
                   2386:        fprintf(stderr, "%s validation generated an internal error\n",
                   2387:               sctxt->filename);
                   2388:     }
                   2389:     xmlRelaxNGFreeValidCtxt(vctxt);
                   2390:     if (relaxngschemas != NULL)
                   2391:        xmlRelaxNGFree(relaxngschemas);
                   2392:     return(0);
                   2393: }
                   2394: #endif
                   2395: 
                   2396: #ifdef LIBXML_OUTPUT_ENABLED
                   2397: /**
                   2398:  * xmlShellCat:
                   2399:  * @ctxt:  the shell context
                   2400:  * @arg:  unused
                   2401:  * @node:  a node
                   2402:  * @node2:  unused
                   2403:  *
                   2404:  * Implements the XML shell function "cat"
                   2405:  * dumps the serialization node content (XML or HTML).
                   2406:  *
                   2407:  * Returns 0
                   2408:  */
                   2409: int
                   2410: xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
                   2411:             xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2412: {
                   2413:     if (!ctxt)
                   2414:         return (0);
                   2415:     if (node == NULL) {
                   2416:        fprintf(ctxt->output, "NULL\n");
                   2417:        return (0);
                   2418:     }    
                   2419:     if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
                   2420: #ifdef LIBXML_HTML_ENABLED
                   2421:         if (node->type == XML_HTML_DOCUMENT_NODE)
                   2422:             htmlDocDump(ctxt->output, (htmlDocPtr) node);
                   2423:         else
                   2424:             htmlNodeDumpFile(ctxt->output, ctxt->doc, node);
                   2425: #else
                   2426:         if (node->type == XML_DOCUMENT_NODE)
                   2427:             xmlDocDump(ctxt->output, (xmlDocPtr) node);
                   2428:         else
                   2429:             xmlElemDump(ctxt->output, ctxt->doc, node);
                   2430: #endif /* LIBXML_HTML_ENABLED */
                   2431:     } else {
                   2432:         if (node->type == XML_DOCUMENT_NODE)
                   2433:             xmlDocDump(ctxt->output, (xmlDocPtr) node);
                   2434:         else
                   2435:             xmlElemDump(ctxt->output, ctxt->doc, node);
                   2436:     }
                   2437:     fprintf(ctxt->output, "\n");
                   2438:     return (0);
                   2439: }
                   2440: #endif /* LIBXML_OUTPUT_ENABLED */
                   2441: 
                   2442: /**
                   2443:  * xmlShellLoad:
                   2444:  * @ctxt:  the shell context
                   2445:  * @filename:  the file name
                   2446:  * @node:  unused
                   2447:  * @node2:  unused
                   2448:  *
                   2449:  * Implements the XML shell function "load"
                   2450:  * loads a new document specified by the filename
                   2451:  *
                   2452:  * Returns 0 or -1 if loading failed
                   2453:  */
                   2454: int
                   2455: xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
                   2456:              xmlNodePtr node ATTRIBUTE_UNUSED,
                   2457:              xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2458: {
                   2459:     xmlDocPtr doc;
                   2460:     int html = 0;
                   2461: 
                   2462:     if ((ctxt == NULL) || (filename == NULL)) return(-1);
                   2463:     if (ctxt->doc != NULL)
                   2464:         html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
                   2465: 
                   2466:     if (html) {
                   2467: #ifdef LIBXML_HTML_ENABLED
                   2468:         doc = htmlParseFile(filename, NULL);
                   2469: #else
                   2470:         fprintf(ctxt->output, "HTML support not compiled in\n");
                   2471:         doc = NULL;
                   2472: #endif /* LIBXML_HTML_ENABLED */
                   2473:     } else {
                   2474:         doc = xmlReadFile(filename,NULL,0);
                   2475:     }
                   2476:     if (doc != NULL) {
                   2477:         if (ctxt->loaded == 1) {
                   2478:             xmlFreeDoc(ctxt->doc);
                   2479:         }
                   2480:         ctxt->loaded = 1;
                   2481: #ifdef LIBXML_XPATH_ENABLED
                   2482:         xmlXPathFreeContext(ctxt->pctxt);
                   2483: #endif /* LIBXML_XPATH_ENABLED */
                   2484:         xmlFree(ctxt->filename);
                   2485:         ctxt->doc = doc;
                   2486:         ctxt->node = (xmlNodePtr) doc;
                   2487: #ifdef LIBXML_XPATH_ENABLED
                   2488:         ctxt->pctxt = xmlXPathNewContext(doc);
                   2489: #endif /* LIBXML_XPATH_ENABLED */
                   2490:         ctxt->filename = (char *) xmlCanonicPath((xmlChar *) filename);
                   2491:     } else
                   2492:         return (-1);
                   2493:     return (0);
                   2494: }
                   2495: 
                   2496: #ifdef LIBXML_OUTPUT_ENABLED
                   2497: /**
                   2498:  * xmlShellWrite:
                   2499:  * @ctxt:  the shell context
                   2500:  * @filename:  the file name
                   2501:  * @node:  a node in the tree
                   2502:  * @node2:  unused
                   2503:  *
                   2504:  * Implements the XML shell function "write"
                   2505:  * Write the current node to the filename, it saves the serialization
                   2506:  * of the subtree under the @node specified
                   2507:  *
                   2508:  * Returns 0 or -1 in case of error
                   2509:  */
                   2510: int
                   2511: xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
                   2512:               xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2513: {
                   2514:     if (node == NULL)
                   2515:         return (-1);
                   2516:     if ((filename == NULL) || (filename[0] == 0)) {
                   2517:         return (-1);
                   2518:     }
                   2519: #ifdef W_OK
                   2520:     if (access((char *) filename, W_OK)) {
                   2521:         xmlGenericError(xmlGenericErrorContext,
                   2522:                         "Cannot write to %s\n", filename);
                   2523:         return (-1);
                   2524:     }
                   2525: #endif
                   2526:     switch (node->type) {
                   2527:         case XML_DOCUMENT_NODE:
                   2528:             if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
                   2529:                 xmlGenericError(xmlGenericErrorContext,
                   2530:                                 "Failed to write to %s\n", filename);
                   2531:                 return (-1);
                   2532:             }
                   2533:             break;
                   2534:         case XML_HTML_DOCUMENT_NODE:
                   2535: #ifdef LIBXML_HTML_ENABLED
                   2536:             if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
                   2537:                 xmlGenericError(xmlGenericErrorContext,
                   2538:                                 "Failed to write to %s\n", filename);
                   2539:                 return (-1);
                   2540:             }
                   2541: #else
                   2542:             if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
                   2543:                 xmlGenericError(xmlGenericErrorContext,
                   2544:                                 "Failed to write to %s\n", filename);
                   2545:                 return (-1);
                   2546:             }
                   2547: #endif /* LIBXML_HTML_ENABLED */
                   2548:             break;
                   2549:         default:{
                   2550:                 FILE *f;
                   2551: 
                   2552:                 f = fopen((char *) filename, "w");
                   2553:                 if (f == NULL) {
                   2554:                     xmlGenericError(xmlGenericErrorContext,
                   2555:                                     "Failed to write to %s\n", filename);
                   2556:                     return (-1);
                   2557:                 }
                   2558:                 xmlElemDump(f, ctxt->doc, node);
                   2559:                 fclose(f);
                   2560:             }
                   2561:     }
                   2562:     return (0);
                   2563: }
                   2564: 
                   2565: /**
                   2566:  * xmlShellSave:
                   2567:  * @ctxt:  the shell context
                   2568:  * @filename:  the file name (optional)
                   2569:  * @node:  unused
                   2570:  * @node2:  unused
                   2571:  *
                   2572:  * Implements the XML shell function "save"
                   2573:  * Write the current document to the filename, or it's original name
                   2574:  *
                   2575:  * Returns 0 or -1 in case of error
                   2576:  */
                   2577: int
                   2578: xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
                   2579:              xmlNodePtr node ATTRIBUTE_UNUSED,
                   2580:              xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2581: {
                   2582:     if ((ctxt == NULL) || (ctxt->doc == NULL))
                   2583:         return (-1);
                   2584:     if ((filename == NULL) || (filename[0] == 0))
                   2585:         filename = ctxt->filename;
                   2586:     if (filename == NULL)
                   2587:         return (-1);
                   2588: #ifdef W_OK
                   2589:     if (access((char *) filename, W_OK)) {
                   2590:         xmlGenericError(xmlGenericErrorContext,
                   2591:                         "Cannot save to %s\n", filename);
                   2592:         return (-1);
                   2593:     }
                   2594: #endif
                   2595:     switch (ctxt->doc->type) {
                   2596:         case XML_DOCUMENT_NODE:
                   2597:             if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
                   2598:                 xmlGenericError(xmlGenericErrorContext,
                   2599:                                 "Failed to save to %s\n", filename);
                   2600:             }
                   2601:             break;
                   2602:         case XML_HTML_DOCUMENT_NODE:
                   2603: #ifdef LIBXML_HTML_ENABLED
                   2604:             if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
                   2605:                 xmlGenericError(xmlGenericErrorContext,
                   2606:                                 "Failed to save to %s\n", filename);
                   2607:             }
                   2608: #else
                   2609:             if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
                   2610:                 xmlGenericError(xmlGenericErrorContext,
                   2611:                                 "Failed to save to %s\n", filename);
                   2612:             }
                   2613: #endif /* LIBXML_HTML_ENABLED */
                   2614:             break;
                   2615:         default:
                   2616:             xmlGenericError(xmlGenericErrorContext,
                   2617:            "To save to subparts of a document use the 'write' command\n");
                   2618:             return (-1);
                   2619: 
                   2620:     }
                   2621:     return (0);
                   2622: }
                   2623: #endif /* LIBXML_OUTPUT_ENABLED */
                   2624: 
                   2625: #ifdef LIBXML_VALID_ENABLED
                   2626: /**
                   2627:  * xmlShellValidate:
                   2628:  * @ctxt:  the shell context
                   2629:  * @dtd:  the DTD URI (optional)
                   2630:  * @node:  unused
                   2631:  * @node2:  unused
                   2632:  *
                   2633:  * Implements the XML shell function "validate"
                   2634:  * Validate the document, if a DTD path is provided, then the validation
                   2635:  * is done against the given DTD.
                   2636:  *
                   2637:  * Returns 0 or -1 in case of error
                   2638:  */
                   2639: int
                   2640: xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
                   2641:                  xmlNodePtr node ATTRIBUTE_UNUSED,
                   2642:                  xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2643: {
                   2644:     xmlValidCtxt vctxt;
                   2645:     int res = -1;
                   2646: 
                   2647:     if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1);
                   2648:     vctxt.userData = stderr;
                   2649:     vctxt.error = (xmlValidityErrorFunc) fprintf;
                   2650:     vctxt.warning = (xmlValidityWarningFunc) fprintf;
                   2651: 
                   2652:     if ((dtd == NULL) || (dtd[0] == 0)) {
                   2653:         res = xmlValidateDocument(&vctxt, ctxt->doc);
                   2654:     } else {
                   2655:         xmlDtdPtr subset;
                   2656: 
                   2657:         subset = xmlParseDTD(NULL, (xmlChar *) dtd);
                   2658:         if (subset != NULL) {
                   2659:             res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
                   2660: 
                   2661:             xmlFreeDtd(subset);
                   2662:         }
                   2663:     }
                   2664:     return (res);
                   2665: }
                   2666: #endif /* LIBXML_VALID_ENABLED */
                   2667: 
                   2668: /**
                   2669:  * xmlShellDu:
                   2670:  * @ctxt:  the shell context
                   2671:  * @arg:  unused
                   2672:  * @tree:  a node defining a subtree
                   2673:  * @node2:  unused
                   2674:  *
                   2675:  * Implements the XML shell function "du"
                   2676:  * show the structure of the subtree under node @tree
                   2677:  * If @tree is null, the command works on the current node.
                   2678:  *
                   2679:  * Returns 0 or -1 in case of error
                   2680:  */
                   2681: int
                   2682: xmlShellDu(xmlShellCtxtPtr ctxt,
                   2683:            char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
                   2684:            xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2685: {
                   2686:     xmlNodePtr node;
                   2687:     int indent = 0, i;
                   2688: 
                   2689:     if (!ctxt)
                   2690:        return (-1);
                   2691: 
                   2692:     if (tree == NULL)
                   2693:         return (-1);
                   2694:     node = tree;
                   2695:     while (node != NULL) {
                   2696:         if ((node->type == XML_DOCUMENT_NODE) ||
                   2697:             (node->type == XML_HTML_DOCUMENT_NODE)) {
                   2698:             fprintf(ctxt->output, "/\n");
                   2699:         } else if (node->type == XML_ELEMENT_NODE) {
                   2700:             for (i = 0; i < indent; i++)
                   2701:                 fprintf(ctxt->output, "  ");
1.1.1.2 ! misho    2702:             if ((node->ns) && (node->ns->prefix))
        !          2703:                 fprintf(ctxt->output, "%s:", node->ns->prefix);
1.1       misho    2704:             fprintf(ctxt->output, "%s\n", node->name);
                   2705:         } else {
                   2706:         }
                   2707: 
                   2708:         /*
                   2709:          * Browse the full subtree, deep first
                   2710:          */
                   2711: 
                   2712:         if ((node->type == XML_DOCUMENT_NODE) ||
                   2713:             (node->type == XML_HTML_DOCUMENT_NODE)) {
                   2714:             node = ((xmlDocPtr) node)->children;
                   2715:         } else if ((node->children != NULL)
                   2716:                    && (node->type != XML_ENTITY_REF_NODE)) {
                   2717:             /* deep first */
                   2718:             node = node->children;
                   2719:             indent++;
                   2720:         } else if ((node != tree) && (node->next != NULL)) {
                   2721:             /* then siblings */
                   2722:             node = node->next;
                   2723:         } else if (node != tree) {
                   2724:             /* go up to parents->next if needed */
                   2725:             while (node != tree) {
                   2726:                 if (node->parent != NULL) {
                   2727:                     node = node->parent;
                   2728:                     indent--;
                   2729:                 }
                   2730:                 if ((node != tree) && (node->next != NULL)) {
                   2731:                     node = node->next;
                   2732:                     break;
                   2733:                 }
                   2734:                 if (node->parent == NULL) {
                   2735:                     node = NULL;
                   2736:                     break;
                   2737:                 }
                   2738:                 if (node == tree) {
                   2739:                     node = NULL;
                   2740:                     break;
                   2741:                 }
                   2742:             }
                   2743:             /* exit condition */
                   2744:             if (node == tree)
                   2745:                 node = NULL;
                   2746:         } else
                   2747:             node = NULL;
                   2748:     }
                   2749:     return (0);
                   2750: }
                   2751: 
                   2752: /**
                   2753:  * xmlShellPwd:
                   2754:  * @ctxt:  the shell context
                   2755:  * @buffer:  the output buffer
                   2756:  * @node:  a node 
                   2757:  * @node2:  unused
                   2758:  *
                   2759:  * Implements the XML shell function "pwd"
                   2760:  * Show the full path from the root to the node, if needed building
                   2761:  * thumblers when similar elements exists at a given ancestor level.
                   2762:  * The output is compatible with XPath commands.
                   2763:  *
                   2764:  * Returns 0 or -1 in case of error
                   2765:  */
                   2766: int
                   2767: xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
                   2768:             xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
                   2769: {
                   2770:     xmlChar *path;
                   2771: 
                   2772:     if ((node == NULL) || (buffer == NULL))
                   2773:         return (-1);
                   2774: 
                   2775:     path = xmlGetNodePath(node);
                   2776:     if (path == NULL)
                   2777:        return (-1);
                   2778: 
                   2779:     /*
                   2780:      * This test prevents buffer overflow, because this routine
                   2781:      * is only called by xmlShell, in which the second argument is
                   2782:      * 500 chars long.
                   2783:      * It is a dirty hack before a cleaner solution is found.
                   2784:      * Documentation should mention that the second argument must
                   2785:      * be at least 500 chars long, and could be stripped if too long.
                   2786:      */
                   2787:     snprintf(buffer, 499, "%s", path);
                   2788:     buffer[499] = '0';
                   2789:     xmlFree(path);
                   2790: 
                   2791:     return (0);
                   2792: }
                   2793: 
                   2794: /**
                   2795:  * xmlShell:
                   2796:  * @doc:  the initial document
                   2797:  * @filename:  the output buffer
                   2798:  * @input:  the line reading function
                   2799:  * @output:  the output FILE*, defaults to stdout if NULL
                   2800:  *
                   2801:  * Implements the XML shell 
                   2802:  * This allow to load, validate, view, modify and save a document
                   2803:  * using a environment similar to a UNIX commandline.
                   2804:  */
                   2805: void
                   2806: xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
                   2807:          FILE * output)
                   2808: {
                   2809:     char prompt[500] = "/ > ";
                   2810:     char *cmdline = NULL, *cur;
                   2811:     char command[100];
                   2812:     char arg[400];
                   2813:     int i;
                   2814:     xmlShellCtxtPtr ctxt;
                   2815:     xmlXPathObjectPtr list;
                   2816: 
                   2817:     if (doc == NULL)
                   2818:         return;
                   2819:     if (filename == NULL)
                   2820:         return;
                   2821:     if (input == NULL)
                   2822:         return;
                   2823:     if (output == NULL)
                   2824:         output = stdout;
                   2825:     ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
                   2826:     if (ctxt == NULL)
                   2827:         return;
                   2828:     ctxt->loaded = 0;
                   2829:     ctxt->doc = doc;
                   2830:     ctxt->input = input;
                   2831:     ctxt->output = output;
                   2832:     ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
                   2833:     ctxt->node = (xmlNodePtr) ctxt->doc;
                   2834: 
                   2835: #ifdef LIBXML_XPATH_ENABLED
                   2836:     ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
                   2837:     if (ctxt->pctxt == NULL) {
                   2838:         xmlFree(ctxt);
                   2839:         return;
                   2840:     }
                   2841: #endif /* LIBXML_XPATH_ENABLED */
                   2842:     while (1) {
                   2843:         if (ctxt->node == (xmlNodePtr) ctxt->doc)
                   2844:             snprintf(prompt, sizeof(prompt), "%s > ", "/");
1.1.1.2 ! misho    2845:         else if ((ctxt->node != NULL) && (ctxt->node->name) &&
        !          2846:                  (ctxt->node->ns) && (ctxt->node->ns->prefix))
        !          2847:             snprintf(prompt, sizeof(prompt), "%s:%s > ",
        !          2848:                      (ctxt->node->ns->prefix), ctxt->node->name);
1.1       misho    2849:         else if ((ctxt->node != NULL) && (ctxt->node->name))
                   2850:             snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
                   2851:         else
                   2852:             snprintf(prompt, sizeof(prompt), "? > ");
                   2853:         prompt[sizeof(prompt) - 1] = 0;
                   2854: 
                   2855:         /*
                   2856:          * Get a new command line
                   2857:          */
                   2858:         cmdline = ctxt->input(prompt);
                   2859:         if (cmdline == NULL)
                   2860:             break;
                   2861: 
                   2862:         /*
                   2863:          * Parse the command itself
                   2864:          */
                   2865:         cur = cmdline;
                   2866:         while ((*cur == ' ') || (*cur == '\t'))
                   2867:             cur++;
                   2868:         i = 0;
                   2869:         while ((*cur != ' ') && (*cur != '\t') &&
                   2870:                (*cur != '\n') && (*cur != '\r')) {
                   2871:             if (*cur == 0)
                   2872:                 break;
                   2873:             command[i++] = *cur++;
                   2874:         }
                   2875:         command[i] = 0;
                   2876:         if (i == 0)
                   2877:             continue;
                   2878: 
                   2879:         /*
                   2880:          * Parse the argument
                   2881:          */
                   2882:         while ((*cur == ' ') || (*cur == '\t'))
                   2883:             cur++;
                   2884:         i = 0;
                   2885:         while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
                   2886:             if (*cur == 0)
                   2887:                 break;
                   2888:             arg[i++] = *cur++;
                   2889:         }
                   2890:         arg[i] = 0;
                   2891: 
                   2892:         /*
                   2893:          * start interpreting the command
                   2894:          */
                   2895:         if (!strcmp(command, "exit"))
                   2896:             break;
                   2897:         if (!strcmp(command, "quit"))
                   2898:             break;
                   2899:         if (!strcmp(command, "bye"))
                   2900:             break;
                   2901:                if (!strcmp(command, "help")) {
                   2902:                  fprintf(ctxt->output, "\tbase         display XML base of the node\n");
                   2903:                  fprintf(ctxt->output, "\tsetbase URI  change the XML base of the node\n");
                   2904:                  fprintf(ctxt->output, "\tbye          leave shell\n");
                   2905:                  fprintf(ctxt->output, "\tcat [node]   display node or current node\n");
                   2906:                  fprintf(ctxt->output, "\tcd [path]    change directory to path or to root\n");
                   2907:                  fprintf(ctxt->output, "\tdir [path]   dumps informations about the node (namespace, attributes, content)\n");
                   2908:                  fprintf(ctxt->output, "\tdu [path]    show the structure of the subtree under path or the current node\n");
                   2909:                  fprintf(ctxt->output, "\texit         leave shell\n");
                   2910:                  fprintf(ctxt->output, "\thelp         display this help\n");
                   2911:                  fprintf(ctxt->output, "\tfree         display memory usage\n");
                   2912:                  fprintf(ctxt->output, "\tload [name]  load a new document with name\n");
                   2913:                  fprintf(ctxt->output, "\tls [path]    list contents of path or the current directory\n");
                   2914:                  fprintf(ctxt->output, "\tset xml_fragment replace the current node content with the fragment parsed in context\n");
                   2915: #ifdef LIBXML_XPATH_ENABLED
                   2916:                  fprintf(ctxt->output, "\txpath expr   evaluate the XPath expression in that context and print the result\n");
                   2917:                  fprintf(ctxt->output, "\tsetns nsreg  register a namespace to a prefix in the XPath evaluation context\n");
                   2918:                  fprintf(ctxt->output, "\t             format for nsreg is: prefix=[nsuri] (i.e. prefix= unsets a prefix)\n");
                   2919:                  fprintf(ctxt->output, "\tsetrootns    register all namespace found on the root element\n");
                   2920:                  fprintf(ctxt->output, "\t             the default namespace if any uses 'defaultns' prefix\n");
                   2921: #endif /* LIBXML_XPATH_ENABLED */
                   2922:                  fprintf(ctxt->output, "\tpwd          display current working directory\n");
1.1.1.2 ! misho    2923:                  fprintf(ctxt->output, "\twhereis      display absolute path of [path] or current working directory\n");
1.1       misho    2924:                  fprintf(ctxt->output, "\tquit         leave shell\n");
                   2925: #ifdef LIBXML_OUTPUT_ENABLED
                   2926:                  fprintf(ctxt->output, "\tsave [name]  save this document to name or the original name\n");
                   2927:                  fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n");
                   2928: #endif /* LIBXML_OUTPUT_ENABLED */
                   2929: #ifdef LIBXML_VALID_ENABLED
                   2930:                  fprintf(ctxt->output, "\tvalidate     check the document for errors\n");
                   2931: #endif /* LIBXML_VALID_ENABLED */
                   2932: #ifdef LIBXML_SCHEMAS_ENABLED
                   2933:                  fprintf(ctxt->output, "\trelaxng rng  validate the document agaisnt the Relax-NG schemas\n");
                   2934: #endif
                   2935:                  fprintf(ctxt->output, "\tgrep string  search for a string in the subtree\n");
                   2936: #ifdef LIBXML_VALID_ENABLED
                   2937:         } else if (!strcmp(command, "validate")) {
                   2938:             xmlShellValidate(ctxt, arg, NULL, NULL);
                   2939: #endif /* LIBXML_VALID_ENABLED */
                   2940:         } else if (!strcmp(command, "load")) {
                   2941:             xmlShellLoad(ctxt, arg, NULL, NULL);
                   2942: #ifdef LIBXML_SCHEMAS_ENABLED
                   2943:         } else if (!strcmp(command, "relaxng")) {
                   2944:             xmlShellRNGValidate(ctxt, arg, NULL, NULL);
                   2945: #endif
                   2946: #ifdef LIBXML_OUTPUT_ENABLED
                   2947:         } else if (!strcmp(command, "save")) {
                   2948:             xmlShellSave(ctxt, arg, NULL, NULL);
                   2949:         } else if (!strcmp(command, "write")) {
                   2950:            if ((arg == NULL) || (arg[0] == 0))
                   2951:                xmlGenericError(xmlGenericErrorContext,
                   2952:                         "Write command requires a filename argument\n");
                   2953:            else
                   2954:                xmlShellWrite(ctxt, arg, ctxt->node, NULL);
                   2955: #endif /* LIBXML_OUTPUT_ENABLED */
                   2956:         } else if (!strcmp(command, "grep")) {
                   2957:             xmlShellGrep(ctxt, arg, ctxt->node, NULL);
                   2958:         } else if (!strcmp(command, "free")) {
                   2959:             if (arg[0] == 0) {
                   2960:                 xmlMemShow(ctxt->output, 0);
                   2961:             } else {
                   2962:                 int len = 0;
                   2963: 
                   2964:                 sscanf(arg, "%d", &len);
                   2965:                 xmlMemShow(ctxt->output, len);
                   2966:             }
                   2967:         } else if (!strcmp(command, "pwd")) {
                   2968:             char dir[500];
                   2969: 
                   2970:             if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
                   2971:                 fprintf(ctxt->output, "%s\n", dir);
                   2972:         } else if (!strcmp(command, "du")) {
1.1.1.2 ! misho    2973:             if (arg[0] == 0) {
        !          2974:                 xmlShellDu(ctxt, NULL, ctxt->node, NULL);
        !          2975:             } else {
        !          2976:                 ctxt->pctxt->node = ctxt->node;
        !          2977: #ifdef LIBXML_XPATH_ENABLED
        !          2978:                 ctxt->pctxt->node = ctxt->node;
        !          2979:                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
        !          2980: #else
        !          2981:                 list = NULL;
        !          2982: #endif /* LIBXML_XPATH_ENABLED */
        !          2983:                 if (list != NULL) {
        !          2984:                     switch (list->type) {
        !          2985:                         case XPATH_UNDEFINED:
        !          2986:                             xmlGenericError(xmlGenericErrorContext,
        !          2987:                                             "%s: no such node\n", arg);
        !          2988:                             break;
        !          2989:                         case XPATH_NODESET:{
        !          2990:                             int indx;
        !          2991: 
        !          2992:                             if (list->nodesetval == NULL)
        !          2993:                                 break;
        !          2994: 
        !          2995:                             for (indx = 0;
        !          2996:                                  indx < list->nodesetval->nodeNr;
        !          2997:                                  indx++)
        !          2998:                                 xmlShellDu(ctxt, NULL,
        !          2999:                                            list->nodesetval->
        !          3000:                                            nodeTab[indx], NULL);
        !          3001:                             break;
        !          3002:                         }
        !          3003:                         case XPATH_BOOLEAN:
        !          3004:                             xmlGenericError(xmlGenericErrorContext,
        !          3005:                                             "%s is a Boolean\n", arg);
        !          3006:                             break;
        !          3007:                         case XPATH_NUMBER:
        !          3008:                             xmlGenericError(xmlGenericErrorContext,
        !          3009:                                             "%s is a number\n", arg);
        !          3010:                             break;
        !          3011:                         case XPATH_STRING:
        !          3012:                             xmlGenericError(xmlGenericErrorContext,
        !          3013:                                             "%s is a string\n", arg);
        !          3014:                             break;
        !          3015:                         case XPATH_POINT:
        !          3016:                             xmlGenericError(xmlGenericErrorContext,
        !          3017:                                             "%s is a point\n", arg);
        !          3018:                             break;
        !          3019:                         case XPATH_RANGE:
        !          3020:                             xmlGenericError(xmlGenericErrorContext,
        !          3021:                                             "%s is a range\n", arg);
        !          3022:                             break;
        !          3023:                         case XPATH_LOCATIONSET:
        !          3024:                             xmlGenericError(xmlGenericErrorContext,
        !          3025:                                             "%s is a range\n", arg);
        !          3026:                             break;
        !          3027:                         case XPATH_USERS:
        !          3028:                             xmlGenericError(xmlGenericErrorContext,
        !          3029:                                             "%s is user-defined\n", arg);
        !          3030:                             break;
        !          3031:                         case XPATH_XSLT_TREE:
        !          3032:                             xmlGenericError(xmlGenericErrorContext,
        !          3033:                                             "%s is an XSLT value tree\n",
        !          3034:                                             arg);
        !          3035:                             break;
        !          3036:                     }
        !          3037: #ifdef LIBXML_XPATH_ENABLED
        !          3038:                     xmlXPathFreeObject(list);
        !          3039: #endif
        !          3040:                 } else {
        !          3041:                     xmlGenericError(xmlGenericErrorContext,
        !          3042:                                     "%s: no such node\n", arg);
        !          3043:                 }
        !          3044:                 ctxt->pctxt->node = NULL;
        !          3045:             }
1.1       misho    3046:         } else if (!strcmp(command, "base")) {
                   3047:             xmlShellBase(ctxt, NULL, ctxt->node, NULL);
                   3048:         } else if (!strcmp(command, "set")) {
                   3049:            xmlShellSetContent(ctxt, arg, ctxt->node, NULL);
                   3050: #ifdef LIBXML_XPATH_ENABLED
                   3051:         } else if (!strcmp(command, "setns")) {
                   3052:             if (arg[0] == 0) {
                   3053:                xmlGenericError(xmlGenericErrorContext,
                   3054:                                "setns: prefix=[nsuri] required\n");
                   3055:             } else {
                   3056:                 xmlShellRegisterNamespace(ctxt, arg, NULL, NULL);
                   3057:             }
                   3058:         } else if (!strcmp(command, "setrootns")) {
                   3059:            xmlNodePtr root;
                   3060: 
                   3061:            root = xmlDocGetRootElement(ctxt->doc);
                   3062:            xmlShellRegisterRootNamespaces(ctxt, NULL, root, NULL);
                   3063:         } else if (!strcmp(command, "xpath")) {
                   3064:             if (arg[0] == 0) {
                   3065:                xmlGenericError(xmlGenericErrorContext,
                   3066:                                "xpath: expression required\n");
                   3067:            } else {
                   3068:                 ctxt->pctxt->node = ctxt->node;
                   3069:                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
                   3070:                xmlXPathDebugDumpObject(ctxt->output, list, 0);
                   3071:                xmlXPathFreeObject(list);
                   3072:            }
                   3073: #endif /* LIBXML_XPATH_ENABLED */
                   3074: #ifdef LIBXML_TREE_ENABLED
                   3075:         } else if (!strcmp(command, "setbase")) {
                   3076:             xmlShellSetBase(ctxt, arg, ctxt->node, NULL);
                   3077: #endif
                   3078:         } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
                   3079:             int dir = (!strcmp(command, "dir"));
                   3080: 
                   3081:             if (arg[0] == 0) {
                   3082:                 if (dir)
                   3083:                     xmlShellDir(ctxt, NULL, ctxt->node, NULL);
                   3084:                 else
                   3085:                     xmlShellList(ctxt, NULL, ctxt->node, NULL);
                   3086:             } else {
                   3087:                 ctxt->pctxt->node = ctxt->node;
                   3088: #ifdef LIBXML_XPATH_ENABLED
                   3089:                 ctxt->pctxt->node = ctxt->node;
                   3090:                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
                   3091: #else
                   3092:                 list = NULL;
                   3093: #endif /* LIBXML_XPATH_ENABLED */
                   3094:                 if (list != NULL) {
                   3095:                     switch (list->type) {
                   3096:                         case XPATH_UNDEFINED:
                   3097:                             xmlGenericError(xmlGenericErrorContext,
                   3098:                                             "%s: no such node\n", arg);
                   3099:                             break;
                   3100:                         case XPATH_NODESET:{
                   3101:                                 int indx;
                   3102: 
                   3103:                                if (list->nodesetval == NULL)
                   3104:                                    break;
                   3105: 
                   3106:                                 for (indx = 0;
                   3107:                                      indx < list->nodesetval->nodeNr;
                   3108:                                      indx++) {
                   3109:                                     if (dir)
                   3110:                                         xmlShellDir(ctxt, NULL,
                   3111:                                                     list->nodesetval->
                   3112:                                                     nodeTab[indx], NULL);
                   3113:                                     else
                   3114:                                         xmlShellList(ctxt, NULL,
                   3115:                                                      list->nodesetval->
                   3116:                                                      nodeTab[indx], NULL);
                   3117:                                 }
                   3118:                                 break;
                   3119:                             }
                   3120:                         case XPATH_BOOLEAN:
                   3121:                             xmlGenericError(xmlGenericErrorContext,
                   3122:                                             "%s is a Boolean\n", arg);
                   3123:                             break;
                   3124:                         case XPATH_NUMBER:
                   3125:                             xmlGenericError(xmlGenericErrorContext,
                   3126:                                             "%s is a number\n", arg);
                   3127:                             break;
                   3128:                         case XPATH_STRING:
                   3129:                             xmlGenericError(xmlGenericErrorContext,
                   3130:                                             "%s is a string\n", arg);
                   3131:                             break;
                   3132:                         case XPATH_POINT:
                   3133:                             xmlGenericError(xmlGenericErrorContext,
                   3134:                                             "%s is a point\n", arg);
                   3135:                             break;
                   3136:                         case XPATH_RANGE:
                   3137:                             xmlGenericError(xmlGenericErrorContext,
                   3138:                                             "%s is a range\n", arg);
                   3139:                             break;
                   3140:                         case XPATH_LOCATIONSET:
                   3141:                             xmlGenericError(xmlGenericErrorContext,
                   3142:                                             "%s is a range\n", arg);
                   3143:                             break;
                   3144:                         case XPATH_USERS:
                   3145:                             xmlGenericError(xmlGenericErrorContext,
                   3146:                                             "%s is user-defined\n", arg);
                   3147:                             break;
                   3148:                         case XPATH_XSLT_TREE:
                   3149:                             xmlGenericError(xmlGenericErrorContext,
                   3150:                                             "%s is an XSLT value tree\n",
                   3151:                                             arg);
                   3152:                             break;
                   3153:                     }
                   3154: #ifdef LIBXML_XPATH_ENABLED
                   3155:                     xmlXPathFreeObject(list);
                   3156: #endif
                   3157:                 } else {
                   3158:                     xmlGenericError(xmlGenericErrorContext,
                   3159:                                     "%s: no such node\n", arg);
                   3160:                 }
                   3161:                 ctxt->pctxt->node = NULL;
                   3162:             }
1.1.1.2 ! misho    3163:         } else if (!strcmp(command, "whereis")) {
        !          3164:             char dir[500];
        !          3165: 
        !          3166:             if (arg[0] == 0) {
        !          3167:                 if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
        !          3168:                     fprintf(ctxt->output, "%s\n", dir);
        !          3169:             } else {
        !          3170:                 ctxt->pctxt->node = ctxt->node;
        !          3171: #ifdef LIBXML_XPATH_ENABLED
        !          3172:                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
        !          3173: #else
        !          3174:                 list = NULL;
        !          3175: #endif /* LIBXML_XPATH_ENABLED */
        !          3176:                 if (list != NULL) {
        !          3177:                     switch (list->type) {
        !          3178:                         case XPATH_UNDEFINED:
        !          3179:                             xmlGenericError(xmlGenericErrorContext,
        !          3180:                                             "%s: no such node\n", arg);
        !          3181:                             break;
        !          3182:                         case XPATH_NODESET:{
        !          3183:                                 int indx;
        !          3184: 
        !          3185:                                if (list->nodesetval == NULL)
        !          3186:                                    break;
        !          3187: 
        !          3188:                                 for (indx = 0;
        !          3189:                                      indx < list->nodesetval->nodeNr;
        !          3190:                                      indx++) {
        !          3191:                                     if (!xmlShellPwd(ctxt, dir, list->nodesetval->
        !          3192:                                                      nodeTab[indx], NULL))
        !          3193:                                         fprintf(ctxt->output, "%s\n", dir);
        !          3194:                                 }
        !          3195:                                 break;
        !          3196:                             }
        !          3197:                         case XPATH_BOOLEAN:
        !          3198:                             xmlGenericError(xmlGenericErrorContext,
        !          3199:                                             "%s is a Boolean\n", arg);
        !          3200:                             break;
        !          3201:                         case XPATH_NUMBER:
        !          3202:                             xmlGenericError(xmlGenericErrorContext,
        !          3203:                                             "%s is a number\n", arg);
        !          3204:                             break;
        !          3205:                         case XPATH_STRING:
        !          3206:                             xmlGenericError(xmlGenericErrorContext,
        !          3207:                                             "%s is a string\n", arg);
        !          3208:                             break;
        !          3209:                         case XPATH_POINT:
        !          3210:                             xmlGenericError(xmlGenericErrorContext,
        !          3211:                                             "%s is a point\n", arg);
        !          3212:                             break;
        !          3213:                         case XPATH_RANGE:
        !          3214:                             xmlGenericError(xmlGenericErrorContext,
        !          3215:                                             "%s is a range\n", arg);
        !          3216:                             break;
        !          3217:                         case XPATH_LOCATIONSET:
        !          3218:                             xmlGenericError(xmlGenericErrorContext,
        !          3219:                                             "%s is a range\n", arg);
        !          3220:                             break;
        !          3221:                         case XPATH_USERS:
        !          3222:                             xmlGenericError(xmlGenericErrorContext,
        !          3223:                                             "%s is user-defined\n", arg);
        !          3224:                             break;
        !          3225:                         case XPATH_XSLT_TREE:
        !          3226:                             xmlGenericError(xmlGenericErrorContext,
        !          3227:                                             "%s is an XSLT value tree\n",
        !          3228:                                             arg);
        !          3229:                             break;
        !          3230:                     }
        !          3231: #ifdef LIBXML_XPATH_ENABLED
        !          3232:                     xmlXPathFreeObject(list);
        !          3233: #endif
        !          3234:                 } else {
        !          3235:                     xmlGenericError(xmlGenericErrorContext,
        !          3236:                                     "%s: no such node\n", arg);
        !          3237:                 }
        !          3238:                 ctxt->pctxt->node = NULL;
        !          3239:             }
1.1       misho    3240:         } else if (!strcmp(command, "cd")) {
                   3241:             if (arg[0] == 0) {
                   3242:                 ctxt->node = (xmlNodePtr) ctxt->doc;
                   3243:             } else {
                   3244: #ifdef LIBXML_XPATH_ENABLED
                   3245:                 ctxt->pctxt->node = ctxt->node;
                   3246:                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
                   3247: #else
                   3248:                 list = NULL;
                   3249: #endif /* LIBXML_XPATH_ENABLED */
                   3250:                 if (list != NULL) {
                   3251:                     switch (list->type) {
                   3252:                         case XPATH_UNDEFINED:
                   3253:                             xmlGenericError(xmlGenericErrorContext,
                   3254:                                             "%s: no such node\n", arg);
                   3255:                             break;
                   3256:                         case XPATH_NODESET:
                   3257:                             if (list->nodesetval != NULL) {
                   3258:                                if (list->nodesetval->nodeNr == 1) {
                   3259:                                    ctxt->node = list->nodesetval->nodeTab[0];
                   3260:                                    if ((ctxt->node != NULL) &&
                   3261:                                        (ctxt->node->type ==
                   3262:                                         XML_NAMESPACE_DECL)) {
                   3263:                                        xmlGenericError(xmlGenericErrorContext,
                   3264:                                                    "cannot cd to namespace\n");
                   3265:                                        ctxt->node = NULL;
                   3266:                                    }
                   3267:                                } else
                   3268:                                    xmlGenericError(xmlGenericErrorContext,
                   3269:                                                    "%s is a %d Node Set\n",
                   3270:                                                    arg,
                   3271:                                                    list->nodesetval->nodeNr);
                   3272:                             } else
                   3273:                                 xmlGenericError(xmlGenericErrorContext,
                   3274:                                                 "%s is an empty Node Set\n",
                   3275:                                                 arg);
                   3276:                             break;
                   3277:                         case XPATH_BOOLEAN:
                   3278:                             xmlGenericError(xmlGenericErrorContext,
                   3279:                                             "%s is a Boolean\n", arg);
                   3280:                             break;
                   3281:                         case XPATH_NUMBER:
                   3282:                             xmlGenericError(xmlGenericErrorContext,
                   3283:                                             "%s is a number\n", arg);
                   3284:                             break;
                   3285:                         case XPATH_STRING:
                   3286:                             xmlGenericError(xmlGenericErrorContext,
                   3287:                                             "%s is a string\n", arg);
                   3288:                             break;
                   3289:                         case XPATH_POINT:
                   3290:                             xmlGenericError(xmlGenericErrorContext,
                   3291:                                             "%s is a point\n", arg);
                   3292:                             break;
                   3293:                         case XPATH_RANGE:
                   3294:                             xmlGenericError(xmlGenericErrorContext,
                   3295:                                             "%s is a range\n", arg);
                   3296:                             break;
                   3297:                         case XPATH_LOCATIONSET:
                   3298:                             xmlGenericError(xmlGenericErrorContext,
                   3299:                                             "%s is a range\n", arg);
                   3300:                             break;
                   3301:                         case XPATH_USERS:
                   3302:                             xmlGenericError(xmlGenericErrorContext,
                   3303:                                             "%s is user-defined\n", arg);
                   3304:                             break;
                   3305:                         case XPATH_XSLT_TREE:
                   3306:                             xmlGenericError(xmlGenericErrorContext,
                   3307:                                             "%s is an XSLT value tree\n",
                   3308:                                             arg);
                   3309:                             break;
                   3310:                     }
                   3311: #ifdef LIBXML_XPATH_ENABLED
                   3312:                     xmlXPathFreeObject(list);
                   3313: #endif
                   3314:                 } else {
                   3315:                     xmlGenericError(xmlGenericErrorContext,
                   3316:                                     "%s: no such node\n", arg);
                   3317:                 }
                   3318:                 ctxt->pctxt->node = NULL;
                   3319:             }
                   3320: #ifdef LIBXML_OUTPUT_ENABLED
                   3321:         } else if (!strcmp(command, "cat")) {
                   3322:             if (arg[0] == 0) {
                   3323:                 xmlShellCat(ctxt, NULL, ctxt->node, NULL);
                   3324:             } else {
                   3325:                 ctxt->pctxt->node = ctxt->node;
                   3326: #ifdef LIBXML_XPATH_ENABLED
                   3327:                 ctxt->pctxt->node = ctxt->node;
                   3328:                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
                   3329: #else
                   3330:                 list = NULL;
                   3331: #endif /* LIBXML_XPATH_ENABLED */
                   3332:                 if (list != NULL) {
                   3333:                     switch (list->type) {
                   3334:                         case XPATH_UNDEFINED:
                   3335:                             xmlGenericError(xmlGenericErrorContext,
                   3336:                                             "%s: no such node\n", arg);
                   3337:                             break;
                   3338:                         case XPATH_NODESET:{
                   3339:                                 int indx;
                   3340: 
                   3341:                                if (list->nodesetval == NULL)
                   3342:                                    break;
                   3343: 
                   3344:                                 for (indx = 0;
                   3345:                                      indx < list->nodesetval->nodeNr;
                   3346:                                      indx++) {
                   3347:                                     if (i > 0)
                   3348:                                         fprintf(ctxt->output, " -------\n");
                   3349:                                     xmlShellCat(ctxt, NULL,
                   3350:                                                 list->nodesetval->
                   3351:                                                 nodeTab[indx], NULL);
                   3352:                                 }
                   3353:                                 break;
                   3354:                             }
                   3355:                         case XPATH_BOOLEAN:
                   3356:                             xmlGenericError(xmlGenericErrorContext,
                   3357:                                             "%s is a Boolean\n", arg);
                   3358:                             break;
                   3359:                         case XPATH_NUMBER:
                   3360:                             xmlGenericError(xmlGenericErrorContext,
                   3361:                                             "%s is a number\n", arg);
                   3362:                             break;
                   3363:                         case XPATH_STRING:
                   3364:                             xmlGenericError(xmlGenericErrorContext,
                   3365:                                             "%s is a string\n", arg);
                   3366:                             break;
                   3367:                         case XPATH_POINT:
                   3368:                             xmlGenericError(xmlGenericErrorContext,
                   3369:                                             "%s is a point\n", arg);
                   3370:                             break;
                   3371:                         case XPATH_RANGE:
                   3372:                             xmlGenericError(xmlGenericErrorContext,
                   3373:                                             "%s is a range\n", arg);
                   3374:                             break;
                   3375:                         case XPATH_LOCATIONSET:
                   3376:                             xmlGenericError(xmlGenericErrorContext,
                   3377:                                             "%s is a range\n", arg);
                   3378:                             break;
                   3379:                         case XPATH_USERS:
                   3380:                             xmlGenericError(xmlGenericErrorContext,
                   3381:                                             "%s is user-defined\n", arg);
                   3382:                             break;
                   3383:                         case XPATH_XSLT_TREE:
                   3384:                             xmlGenericError(xmlGenericErrorContext,
                   3385:                                             "%s is an XSLT value tree\n",
                   3386:                                             arg);
                   3387:                             break;
                   3388:                     }
                   3389: #ifdef LIBXML_XPATH_ENABLED
                   3390:                     xmlXPathFreeObject(list);
                   3391: #endif
                   3392:                 } else {
                   3393:                     xmlGenericError(xmlGenericErrorContext,
                   3394:                                     "%s: no such node\n", arg);
                   3395:                 }
                   3396:                 ctxt->pctxt->node = NULL;
                   3397:             }
                   3398: #endif /* LIBXML_OUTPUT_ENABLED */
                   3399:         } else {
                   3400:             xmlGenericError(xmlGenericErrorContext,
                   3401:                             "Unknown command %s\n", command);
                   3402:         }
                   3403:         free(cmdline);          /* not xmlFree here ! */
                   3404:        cmdline = NULL;
                   3405:     }
                   3406: #ifdef LIBXML_XPATH_ENABLED
                   3407:     xmlXPathFreeContext(ctxt->pctxt);
                   3408: #endif /* LIBXML_XPATH_ENABLED */
                   3409:     if (ctxt->loaded) {
                   3410:         xmlFreeDoc(ctxt->doc);
                   3411:     }
                   3412:     if (ctxt->filename != NULL)
                   3413:         xmlFree(ctxt->filename);
                   3414:     xmlFree(ctxt);
                   3415:     if (cmdline != NULL)
                   3416:         free(cmdline);          /* not xmlFree here ! */
                   3417: }
                   3418: 
                   3419: #endif /* LIBXML_XPATH_ENABLED */
                   3420: #define bottom_debugXML
                   3421: #include "elfgcchack.h"
                   3422: #endif /* LIBXML_DEBUG_ENABLED */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>