Annotation of XML/testHTML.c, revision 1.21

1.1       daniel      1: /*
                      2:  * testHTML.c : a small tester program for HTML input.
                      3:  *
                      4:  * See Copyright for the status of this software.
                      5:  *
                      6:  * Daniel.Veillard@w3.org
                      7:  */
                      8: 
                      9: #ifdef WIN32
1.9       daniel     10: #include "win32config.h"
1.1       daniel     11: #else
1.4       daniel     12: #include "config.h"
1.1       daniel     13: #endif
1.3       daniel     14: 
1.21    ! veillard   15: #include <libxml/xmlversion.h>
1.12      daniel     16: #ifdef LIBXML_HTML_ENABLED
                     17: 
1.3       daniel     18: #include <stdio.h>
                     19: #include <string.h>
1.7       daniel     20: #include <stdarg.h>
                     21: 
1.3       daniel     22: 
                     23: #ifdef HAVE_SYS_TYPES_H
1.1       daniel     24: #include <sys/types.h>
1.3       daniel     25: #endif
1.1       daniel     26: #ifdef HAVE_SYS_STAT_H
                     27: #include <sys/stat.h>
                     28: #endif
                     29: #ifdef HAVE_FCNTL_H
                     30: #include <fcntl.h>
                     31: #endif
                     32: #ifdef HAVE_UNISTD_H
                     33: #include <unistd.h>
                     34: #endif
1.3       daniel     35: #ifdef HAVE_STDLIB_H
1.1       daniel     36: #include <stdlib.h>
1.3       daniel     37: #endif
1.1       daniel     38: 
1.12      daniel     39: #include <libxml/xmlmemory.h>
                     40: #include <libxml/HTMLparser.h>
                     41: #include <libxml/HTMLtree.h>
                     42: #include <libxml/debugXML.h>
1.1       daniel     43: 
1.12      daniel     44: #ifdef LIBXML_DEBUG_ENABLED
1.1       daniel     45: static int debug = 0;
1.12      daniel     46: #endif
1.1       daniel     47: static int copy = 0;
1.7       daniel     48: static int sax = 0;
                     49: static int repeat = 0;
                     50: static int noout = 0;
1.10      daniel     51: static int push = 0;
1.13      veillard   52: static char *encoding = NULL;
1.1       daniel     53: 
1.7       daniel     54: xmlSAXHandler emptySAXHandlerStruct = {
                     55:     NULL, /* internalSubset */
                     56:     NULL, /* isStandalone */
                     57:     NULL, /* hasInternalSubset */
                     58:     NULL, /* hasExternalSubset */
                     59:     NULL, /* resolveEntity */
                     60:     NULL, /* getEntity */
                     61:     NULL, /* entityDecl */
                     62:     NULL, /* notationDecl */
                     63:     NULL, /* attributeDecl */
                     64:     NULL, /* elementDecl */
                     65:     NULL, /* unparsedEntityDecl */
                     66:     NULL, /* setDocumentLocator */
                     67:     NULL, /* startDocument */
                     68:     NULL, /* endDocument */
                     69:     NULL, /* startElement */
                     70:     NULL, /* endElement */
                     71:     NULL, /* reference */
                     72:     NULL, /* characters */
                     73:     NULL, /* ignorableWhitespace */
                     74:     NULL, /* processingInstruction */
                     75:     NULL, /* comment */
                     76:     NULL, /* xmlParserWarning */
                     77:     NULL, /* xmlParserError */
                     78:     NULL, /* xmlParserError */
                     79:     NULL, /* getParameterEntity */
                     80: };
                     81: 
                     82: xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
                     83: extern xmlSAXHandlerPtr debugSAXHandler;
                     84: 
                     85: /************************************************************************
                     86:  *                                                                     *
                     87:  *                             Debug Handlers                          *
                     88:  *                                                                     *
                     89:  ************************************************************************/
                     90: 
                     91: /**
                     92:  * isStandaloneDebug:
                     93:  * @ctxt:  An XML parser context
                     94:  *
                     95:  * Is this document tagged standalone ?
                     96:  *
                     97:  * Returns 1 if true
                     98:  */
                     99: int
                    100: isStandaloneDebug(void *ctx)
                    101: {
                    102:     fprintf(stdout, "SAX.isStandalone()\n");
                    103:     return(0);
                    104: }
                    105: 
                    106: /**
                    107:  * hasInternalSubsetDebug:
                    108:  * @ctxt:  An XML parser context
                    109:  *
                    110:  * Does this document has an internal subset
                    111:  *
                    112:  * Returns 1 if true
                    113:  */
                    114: int
                    115: hasInternalSubsetDebug(void *ctx)
                    116: {
                    117:     fprintf(stdout, "SAX.hasInternalSubset()\n");
                    118:     return(0);
                    119: }
                    120: 
                    121: /**
                    122:  * hasExternalSubsetDebug:
                    123:  * @ctxt:  An XML parser context
                    124:  *
                    125:  * Does this document has an external subset
                    126:  *
                    127:  * Returns 1 if true
                    128:  */
                    129: int
                    130: hasExternalSubsetDebug(void *ctx)
                    131: {
                    132:     fprintf(stdout, "SAX.hasExternalSubset()\n");
                    133:     return(0);
                    134: }
                    135: 
                    136: /**
                    137:  * hasInternalSubsetDebug:
                    138:  * @ctxt:  An XML parser context
                    139:  *
                    140:  * Does this document has an internal subset
                    141:  */
                    142: void
                    143: internalSubsetDebug(void *ctx, const xmlChar *name,
                    144:               const xmlChar *ExternalID, const xmlChar *SystemID)
                    145: {
1.17      veillard  146:     fprintf(stdout, "SAX.internalSubset(%s,", name);
                    147:     if (ExternalID == NULL)
                    148:        fprintf(stdout, " ,");
                    149:     else
                    150:        fprintf(stdout, " %s,", ExternalID);
                    151:     if (SystemID == NULL)
                    152:        fprintf(stdout, " )\n");
                    153:     else
                    154:        fprintf(stdout, " %s)\n", SystemID);
1.7       daniel    155: }
                    156: 
                    157: /**
                    158:  * resolveEntityDebug:
                    159:  * @ctxt:  An XML parser context
                    160:  * @publicId: The public ID of the entity
                    161:  * @systemId: The system ID of the entity
                    162:  *
                    163:  * Special entity resolver, better left to the parser, it has
                    164:  * more context than the application layer.
                    165:  * The default behaviour is to NOT resolve the entities, in that case
                    166:  * the ENTITY_REF nodes are built in the structure (and the parameter
                    167:  * values).
                    168:  *
                    169:  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
                    170:  */
                    171: xmlParserInputPtr
                    172: resolveEntityDebug(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
                    173: {
                    174:     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
                    175: 
                    176:     
                    177:     fprintf(stdout, "SAX.resolveEntity(");
                    178:     if (publicId != NULL)
                    179:        fprintf(stdout, "%s", (char *)publicId);
                    180:     else
                    181:        fprintf(stdout, " ");
                    182:     if (systemId != NULL)
                    183:        fprintf(stdout, ", %s)\n", (char *)systemId);
                    184:     else
                    185:        fprintf(stdout, ", )\n");
                    186: /*********
                    187:     if (systemId != NULL) {
                    188:         return(xmlNewInputFromFile(ctxt, (char *) systemId));
                    189:     }
                    190:  *********/
                    191:     return(NULL);
                    192: }
                    193: 
                    194: /**
                    195:  * getEntityDebug:
                    196:  * @ctxt:  An XML parser context
                    197:  * @name: The entity name
                    198:  *
                    199:  * Get an entity by name
                    200:  *
                    201:  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
                    202:  */
                    203: xmlEntityPtr
                    204: getEntityDebug(void *ctx, const xmlChar *name)
                    205: {
                    206:     fprintf(stdout, "SAX.getEntity(%s)\n", name);
                    207:     return(NULL);
                    208: }
                    209: 
                    210: /**
                    211:  * getParameterEntityDebug:
                    212:  * @ctxt:  An XML parser context
                    213:  * @name: The entity name
                    214:  *
                    215:  * Get a parameter entity by name
                    216:  *
                    217:  * Returns the xmlParserInputPtr
                    218:  */
                    219: xmlEntityPtr
                    220: getParameterEntityDebug(void *ctx, const xmlChar *name)
                    221: {
                    222:     fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
                    223:     return(NULL);
                    224: }
                    225: 
                    226: 
                    227: /**
                    228:  * entityDeclDebug:
                    229:  * @ctxt:  An XML parser context
                    230:  * @name:  the entity name 
                    231:  * @type:  the entity type 
                    232:  * @publicId: The public ID of the entity
                    233:  * @systemId: The system ID of the entity
                    234:  * @content: the entity value (without processing).
                    235:  *
                    236:  * An entity definition has been parsed
                    237:  */
                    238: void
                    239: entityDeclDebug(void *ctx, const xmlChar *name, int type,
                    240:           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
                    241: {
                    242:     fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
                    243:             name, type, publicId, systemId, content);
                    244: }
                    245: 
                    246: /**
                    247:  * attributeDeclDebug:
                    248:  * @ctxt:  An XML parser context
                    249:  * @name:  the attribute name 
                    250:  * @type:  the attribute type 
                    251:  *
                    252:  * An attribute definition has been parsed
                    253:  */
                    254: void
                    255: attributeDeclDebug(void *ctx, const xmlChar *elem, const xmlChar *name,
                    256:               int type, int def, const xmlChar *defaultValue,
                    257:              xmlEnumerationPtr tree)
                    258: {
                    259:     fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
                    260:             elem, name, type, def, defaultValue);
                    261: }
                    262: 
                    263: /**
                    264:  * elementDeclDebug:
                    265:  * @ctxt:  An XML parser context
                    266:  * @name:  the element name 
                    267:  * @type:  the element type 
                    268:  * @content: the element value (without processing).
                    269:  *
                    270:  * An element definition has been parsed
                    271:  */
                    272: void
                    273: elementDeclDebug(void *ctx, const xmlChar *name, int type,
                    274:            xmlElementContentPtr content)
                    275: {
                    276:     fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
                    277:             name, type);
                    278: }
                    279: 
                    280: /**
                    281:  * notationDeclDebug:
                    282:  * @ctxt:  An XML parser context
                    283:  * @name: The name of the notation
                    284:  * @publicId: The public ID of the entity
                    285:  * @systemId: The system ID of the entity
                    286:  *
                    287:  * What to do when a notation declaration has been parsed.
                    288:  */
                    289: void
                    290: notationDeclDebug(void *ctx, const xmlChar *name,
                    291:             const xmlChar *publicId, const xmlChar *systemId)
                    292: {
                    293:     fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
                    294:             (char *) name, (char *) publicId, (char *) systemId);
                    295: }
                    296: 
                    297: /**
                    298:  * unparsedEntityDeclDebug:
                    299:  * @ctxt:  An XML parser context
                    300:  * @name: The name of the entity
                    301:  * @publicId: The public ID of the entity
                    302:  * @systemId: The system ID of the entity
                    303:  * @notationName: the name of the notation
                    304:  *
                    305:  * What to do when an unparsed entity declaration is parsed
                    306:  */
                    307: void
                    308: unparsedEntityDeclDebug(void *ctx, const xmlChar *name,
                    309:                   const xmlChar *publicId, const xmlChar *systemId,
                    310:                   const xmlChar *notationName)
                    311: {
                    312:     fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
                    313:             (char *) name, (char *) publicId, (char *) systemId,
                    314:            (char *) notationName);
                    315: }
                    316: 
                    317: /**
                    318:  * setDocumentLocatorDebug:
                    319:  * @ctxt:  An XML parser context
                    320:  * @loc: A SAX Locator
                    321:  *
                    322:  * Receive the document locator at startup, actually xmlDefaultSAXLocator
                    323:  * Everything is available on the context, so this is useless in our case.
                    324:  */
                    325: void
                    326: setDocumentLocatorDebug(void *ctx, xmlSAXLocatorPtr loc)
                    327: {
                    328:     fprintf(stdout, "SAX.setDocumentLocator()\n");
                    329: }
                    330: 
                    331: /**
                    332:  * startDocumentDebug:
                    333:  * @ctxt:  An XML parser context
                    334:  *
                    335:  * called when the document start being processed.
                    336:  */
                    337: void
                    338: startDocumentDebug(void *ctx)
                    339: {
                    340:     fprintf(stdout, "SAX.startDocument()\n");
                    341: }
                    342: 
                    343: /**
                    344:  * endDocumentDebug:
                    345:  * @ctxt:  An XML parser context
                    346:  *
                    347:  * called when the document end has been detected.
                    348:  */
                    349: void
                    350: endDocumentDebug(void *ctx)
                    351: {
                    352:     fprintf(stdout, "SAX.endDocument()\n");
                    353: }
                    354: 
                    355: /**
                    356:  * startElementDebug:
                    357:  * @ctxt:  An XML parser context
                    358:  * @name:  The element name
                    359:  *
                    360:  * called when an opening tag has been processed.
                    361:  */
                    362: void
                    363: startElementDebug(void *ctx, const xmlChar *name, const xmlChar **atts)
                    364: {
                    365:     int i;
                    366: 
                    367:     fprintf(stdout, "SAX.startElement(%s", (char *) name);
                    368:     if (atts != NULL) {
                    369:         for (i = 0;(atts[i] != NULL);i++) {
1.17      veillard  370:            fprintf(stdout, ", %s", atts[i++]);
1.19      veillard  371:            if (atts[i] != NULL) {
                    372:                unsigned char output[40];
                    373:                const unsigned char *att = atts[i];
                    374:                int outlen, attlen;
                    375:                fprintf(stdout, "='");
                    376:                while ((attlen = strlen((char*)att)) > 0) {
                    377:                    outlen = sizeof output - 1;
                    378:                    htmlEncodeEntities(output, &outlen, att, &attlen, '\'');
                    379:                    fprintf(stdout, "%.*s", outlen, output);
                    380:                    att += attlen;
                    381:                }
                    382:                fprintf(stdout, "'");
                    383:            }
1.7       daniel    384:        }
                    385:     }
                    386:     fprintf(stdout, ")\n");
                    387: }
                    388: 
                    389: /**
                    390:  * endElementDebug:
                    391:  * @ctxt:  An XML parser context
                    392:  * @name:  The element name
                    393:  *
                    394:  * called when the end of an element has been detected.
                    395:  */
                    396: void
                    397: endElementDebug(void *ctx, const xmlChar *name)
                    398: {
                    399:     fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
                    400: }
                    401: 
                    402: /**
                    403:  * charactersDebug:
                    404:  * @ctxt:  An XML parser context
                    405:  * @ch:  a xmlChar string
                    406:  * @len: the number of xmlChar
                    407:  *
                    408:  * receiving some chars from the parser.
                    409:  * Question: how much at a time ???
                    410:  */
                    411: void
                    412: charactersDebug(void *ctx, const xmlChar *ch, int len)
                    413: {
1.19      veillard  414:     unsigned char output[40];
1.20      veillard  415:     int inlen = len, outlen = 30;
1.7       daniel    416: 
1.20      veillard  417:     htmlEncodeEntities(output, &outlen, ch, &inlen, 0);
1.19      veillard  418:     output[outlen] = 0;
1.15      veillard  419: 
                    420:     fprintf(stdout, "SAX.characters(%s, %d)\n", output, len);
1.7       daniel    421: }
                    422: 
                    423: /**
                    424:  * referenceDebug:
                    425:  * @ctxt:  An XML parser context
                    426:  * @name:  The entity name
                    427:  *
                    428:  * called when an entity reference is detected. 
                    429:  */
                    430: void
                    431: referenceDebug(void *ctx, const xmlChar *name)
                    432: {
                    433:     fprintf(stdout, "SAX.reference(%s)\n", name);
                    434: }
                    435: 
                    436: /**
                    437:  * ignorableWhitespaceDebug:
                    438:  * @ctxt:  An XML parser context
                    439:  * @ch:  a xmlChar string
                    440:  * @start: the first char in the string
                    441:  * @len: the number of xmlChar
                    442:  *
                    443:  * receiving some ignorable whitespaces from the parser.
                    444:  * Question: how much at a time ???
                    445:  */
                    446: void
                    447: ignorableWhitespaceDebug(void *ctx, const xmlChar *ch, int len)
                    448: {
1.15      veillard  449:     char output[40];
                    450:     int i;
                    451: 
                    452:     for (i = 0;(i<len) && (i < 30);i++)
                    453:        output[i] = ch[i];
                    454:     output[i] = 0;
                    455: 
                    456:     fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", output, len);
1.7       daniel    457: }
                    458: 
                    459: /**
                    460:  * processingInstructionDebug:
                    461:  * @ctxt:  An XML parser context
                    462:  * @target:  the target name
                    463:  * @data: the PI data's
                    464:  * @len: the number of xmlChar
                    465:  *
                    466:  * A processing instruction has been parsed.
                    467:  */
                    468: void
                    469: processingInstructionDebug(void *ctx, const xmlChar *target,
                    470:                       const xmlChar *data)
                    471: {
                    472:     fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
                    473:             (char *) target, (char *) data);
                    474: }
                    475: 
                    476: /**
                    477:  * commentDebug:
                    478:  * @ctxt:  An XML parser context
                    479:  * @value:  the comment content
                    480:  *
                    481:  * A comment has been parsed.
                    482:  */
                    483: void
                    484: commentDebug(void *ctx, const xmlChar *value)
                    485: {
                    486:     fprintf(stdout, "SAX.comment(%s)\n", value);
                    487: }
                    488: 
                    489: /**
                    490:  * warningDebug:
                    491:  * @ctxt:  An XML parser context
                    492:  * @msg:  the message to display/transmit
                    493:  * @...:  extra parameters for the message display
                    494:  *
                    495:  * Display and format a warning messages, gives file, line, position and
                    496:  * extra parameters.
                    497:  */
                    498: void
                    499: warningDebug(void *ctx, const char *msg, ...)
                    500: {
                    501:     va_list args;
                    502: 
                    503:     va_start(args, msg);
                    504:     fprintf(stdout, "SAX.warning: ");
                    505:     vfprintf(stdout, msg, args);
                    506:     va_end(args);
                    507: }
                    508: 
                    509: /**
                    510:  * errorDebug:
                    511:  * @ctxt:  An XML parser context
                    512:  * @msg:  the message to display/transmit
                    513:  * @...:  extra parameters for the message display
                    514:  *
                    515:  * Display and format a error messages, gives file, line, position and
                    516:  * extra parameters.
                    517:  */
                    518: void
                    519: errorDebug(void *ctx, const char *msg, ...)
                    520: {
                    521:     va_list args;
                    522: 
                    523:     va_start(args, msg);
                    524:     fprintf(stdout, "SAX.error: ");
                    525:     vfprintf(stdout, msg, args);
                    526:     va_end(args);
                    527: }
                    528: 
                    529: /**
                    530:  * fatalErrorDebug:
                    531:  * @ctxt:  An XML parser context
                    532:  * @msg:  the message to display/transmit
                    533:  * @...:  extra parameters for the message display
                    534:  *
                    535:  * Display and format a fatalError messages, gives file, line, position and
                    536:  * extra parameters.
                    537:  */
                    538: void
                    539: fatalErrorDebug(void *ctx, const char *msg, ...)
                    540: {
                    541:     va_list args;
                    542: 
                    543:     va_start(args, msg);
                    544:     fprintf(stdout, "SAX.fatalError: ");
                    545:     vfprintf(stdout, msg, args);
                    546:     va_end(args);
                    547: }
                    548: 
                    549: xmlSAXHandler debugSAXHandlerStruct = {
                    550:     internalSubsetDebug,
                    551:     isStandaloneDebug,
                    552:     hasInternalSubsetDebug,
                    553:     hasExternalSubsetDebug,
                    554:     resolveEntityDebug,
                    555:     getEntityDebug,
                    556:     entityDeclDebug,
                    557:     notationDeclDebug,
                    558:     attributeDeclDebug,
                    559:     elementDeclDebug,
                    560:     unparsedEntityDeclDebug,
                    561:     setDocumentLocatorDebug,
                    562:     startDocumentDebug,
                    563:     endDocumentDebug,
                    564:     startElementDebug,
                    565:     endElementDebug,
                    566:     referenceDebug,
                    567:     charactersDebug,
                    568:     ignorableWhitespaceDebug,
                    569:     processingInstructionDebug,
                    570:     commentDebug,
                    571:     warningDebug,
                    572:     errorDebug,
                    573:     fatalErrorDebug,
                    574:     getParameterEntityDebug,
                    575: };
                    576: 
                    577: xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1.1       daniel    578: /************************************************************************
                    579:  *                                                                     *
                    580:  *                             Debug                                   *
                    581:  *                                                                     *
                    582:  ************************************************************************/
                    583: 
1.7       daniel    584: void parseSAXFile(char *filename) {
1.18      veillard  585:     htmlDocPtr doc = NULL;
                    586: 
1.7       daniel    587:     /*
                    588:      * Empty callbacks for checking
                    589:      */
1.15      veillard  590:     if (push) {
                    591:        FILE *f;
                    592: 
                    593:        f = fopen(filename, "r");
                    594:        if (f != NULL) {
                    595:            int res, size = 3;
                    596:            char chars[4096];
                    597:            htmlParserCtxtPtr ctxt;
1.7       daniel    598: 
1.15      veillard  599:            /* if (repeat) */
                    600:                size = 4096;
                    601:            res = fread(chars, 1, 4, f);
                    602:            if (res > 0) {
                    603:                ctxt = htmlCreatePushParserCtxt(emptySAXHandler, NULL,
                    604:                            chars, res, filename, 0);
                    605:                while ((res = fread(chars, 1, size, f)) > 0) {
                    606:                    htmlParseChunk(ctxt, chars, res, 0);
                    607:                }
                    608:                htmlParseChunk(ctxt, chars, 0, 1);
                    609:                doc = ctxt->myDoc;
                    610:                htmlFreeParserCtxt(ctxt);
                    611:            }
                    612:            if (doc != NULL) {
                    613:                fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
                    614:                xmlFreeDoc(doc);
                    615:            }
                    616:            fclose(f);
                    617:        }
                    618:        if (!noout) {
                    619:            f = fopen(filename, "r");
                    620:            if (f != NULL) {
                    621:                int res, size = 3;
                    622:                char chars[4096];
                    623:                htmlParserCtxtPtr ctxt;
                    624: 
                    625:                /* if (repeat) */
                    626:                    size = 4096;
                    627:                res = fread(chars, 1, 4, f);
                    628:                if (res > 0) {
                    629:                    ctxt = htmlCreatePushParserCtxt(debugSAXHandler, NULL,
                    630:                                chars, res, filename, 0);
                    631:                    while ((res = fread(chars, 1, size, f)) > 0) {
                    632:                        htmlParseChunk(ctxt, chars, res, 0);
                    633:                    }
                    634:                    htmlParseChunk(ctxt, chars, 0, 1);
                    635:                    doc = ctxt->myDoc;
                    636:                    htmlFreeParserCtxt(ctxt);
                    637:                }
                    638:                if (doc != NULL) {
                    639:                    fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
                    640:                    xmlFreeDoc(doc);
                    641:                }
                    642:                fclose(f);
                    643:            }
                    644:        }
                    645:     } else {   
                    646:        doc = htmlSAXParseFile(filename, NULL, emptySAXHandler, NULL);
1.7       daniel    647:        if (doc != NULL) {
                    648:            fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
                    649:            xmlFreeDoc(doc);
                    650:        }
1.15      veillard  651: 
                    652:        if (!noout) {
                    653:            /*
                    654:             * Debug callback
                    655:             */
                    656:            doc = htmlSAXParseFile(filename, NULL, debugSAXHandler, NULL);
                    657:            if (doc != NULL) {
                    658:                fprintf(stdout, "htmlSAXParseFile returned non-NULL\n");
                    659:                xmlFreeDoc(doc);
                    660:            }
                    661:        }
1.7       daniel    662:     }
                    663: }
                    664: 
1.1       daniel    665: void parseAndPrintFile(char *filename) {
1.11      daniel    666:     htmlDocPtr doc = NULL, tmp;
1.1       daniel    667: 
                    668:     /*
                    669:      * build an HTML tree from a string;
                    670:      */
1.10      daniel    671:     if (push) {
                    672:        FILE *f;
                    673: 
                    674:        f = fopen(filename, "r");
                    675:        if (f != NULL) {
                    676:            int res, size = 3;
1.14      veillard  677:            char chars[4096];
1.10      daniel    678:            htmlParserCtxtPtr ctxt;
                    679: 
1.14      veillard  680:            /* if (repeat) */
                    681:                size = 4096;
1.10      daniel    682:            res = fread(chars, 1, 4, f);
                    683:            if (res > 0) {
                    684:                ctxt = htmlCreatePushParserCtxt(NULL, NULL,
                    685:                            chars, res, filename, 0);
                    686:                while ((res = fread(chars, 1, size, f)) > 0) {
                    687:                    htmlParseChunk(ctxt, chars, res, 0);
                    688:                }
                    689:                htmlParseChunk(ctxt, chars, 0, 1);
                    690:                doc = ctxt->myDoc;
                    691:                htmlFreeParserCtxt(ctxt);
                    692:            }
1.15      veillard  693:            fclose(f);
1.10      daniel    694:        }
                    695:     } else {   
                    696:        doc = htmlParseFile(filename, NULL);
                    697:     }
                    698:     if (doc == NULL) {
                    699:         fprintf(stderr, "Could not parse %s\n", filename);
                    700:     }
1.1       daniel    701: 
                    702:     /*
                    703:      * test intermediate copy if needed.
                    704:      */
                    705:     if (copy) {
                    706:         tmp = doc;
                    707:        doc = xmlCopyDoc(doc, 1);
                    708:        xmlFreeDoc(tmp);
                    709:     }
                    710: 
                    711:     /*
                    712:      * print it.
                    713:      */
1.7       daniel    714:     if (!noout) { 
1.12      daniel    715: #ifdef LIBXML_DEBUG_ENABLED
1.13      veillard  716:        if (!debug) {
                    717:            if (encoding)
                    718:                htmlSaveFileEnc("-", doc, encoding);
                    719:            else
                    720:                htmlDocDump(stdout, doc);
                    721:        } else
1.7       daniel    722:            xmlDebugDumpDocument(stdout, doc);
1.12      daniel    723: #else
1.13      veillard  724:        if (encoding)
                    725:            htmlSaveFileEnc("-", doc, encoding);
                    726:        else
                    727:            htmlDocDump(stdout, doc);
1.12      daniel    728: #endif
1.7       daniel    729:     }  
1.1       daniel    730: 
                    731:     /*
                    732:      * free it.
                    733:      */
                    734:     xmlFreeDoc(doc);
                    735: }
                    736: 
                    737: int main(int argc, char **argv) {
1.7       daniel    738:     int i, count;
1.1       daniel    739:     int files = 0;
                    740: 
                    741:     for (i = 1; i < argc ; i++) {
1.12      daniel    742: #ifdef LIBXML_DEBUG_ENABLED
1.1       daniel    743:        if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
                    744:            debug++;
1.12      daniel    745:        else
                    746: #endif
                    747:            if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1.1       daniel    748:            copy++;
1.10      daniel    749:        else if ((!strcmp(argv[i], "-push")) || (!strcmp(argv[i], "--push")))
                    750:            push++;
1.7       daniel    751:        else if ((!strcmp(argv[i], "-sax")) || (!strcmp(argv[i], "--sax")))
                    752:            sax++;
                    753:        else if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout")))
                    754:            noout++;
                    755:        else if ((!strcmp(argv[i], "-repeat")) ||
                    756:                 (!strcmp(argv[i], "--repeat")))
                    757:            repeat++;
1.13      veillard  758:        else if ((!strcmp(argv[i], "-encode")) ||
                    759:                 (!strcmp(argv[i], "--encode"))) {
                    760:            i++;
                    761:            encoding = argv[i];
                    762:         }
1.1       daniel    763:     }
                    764:     for (i = 1; i < argc ; i++) {
1.13      veillard  765:        if ((!strcmp(argv[i], "-encode")) ||
                    766:                 (!strcmp(argv[i], "--encode"))) {
                    767:            i++;
                    768:            continue;
                    769:         }
1.1       daniel    770:        if (argv[i][0] != '-') {
1.7       daniel    771:            if (repeat) {
                    772:                for (count = 0;count < 100 * repeat;count++) {
                    773:                    if (sax)
                    774:                        parseSAXFile(argv[i]);
                    775:                    else   
                    776:                        parseAndPrintFile(argv[i]);
                    777:                }    
                    778:            } else {
                    779:                if (sax)
                    780:                    parseSAXFile(argv[i]);
                    781:                else   
                    782:                    parseAndPrintFile(argv[i]);
                    783:            }
1.1       daniel    784:            files ++;
                    785:        }
                    786:     }
                    787:     if (files == 0) {
1.7       daniel    788:        printf("Usage : %s [--debug] [--copy] [--copy] HTMLfiles ...\n",
1.1       daniel    789:               argv[0]);
                    790:        printf("\tParse the HTML files and output the result of the parsing\n");
1.12      daniel    791: #ifdef LIBXML_DEBUG_ENABLED
1.1       daniel    792:        printf("\t--debug : dump a debug tree of the in-memory document\n");
1.12      daniel    793: #endif
1.1       daniel    794:        printf("\t--copy : used to test the internal copy implementation\n");
1.7       daniel    795:        printf("\t--sax : debug the sequence of SAX callbacks\n");
1.10      daniel    796:        printf("\t--repeat : parse the file 100 times, for timing\n");
1.7       daniel    797:        printf("\t--noout : do not print the result\n");
1.10      daniel    798:        printf("\t--push : use the push mode parser\n");
1.13      veillard  799:        printf("\t--encode encoding : output in the given encoding\n");
1.1       daniel    800:     }
1.8       daniel    801:     xmlCleanupParser();
1.6       daniel    802:     xmlMemoryDump();
1.1       daniel    803: 
                    804:     return(0);
                    805: }
1.12      daniel    806: #else /* !LIBXML_HTML_ENABLED */
                    807: #include <stdio.h>
                    808: int main(int argc, char **argv) {
                    809:     printf("%s : HTML support not compiled in\n", argv[0]);
                    810:     return(0);
                    811: }
                    812: #endif

Webmaster