testHTML.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

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