Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <inttypes.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #include <hubbub/hubbub.h>
  6.  
  7. #include <hubbub/parser.h>
  8.  
  9. #include "utils/utils.h"
  10.  
  11. #include "testutils.h"
  12.  
  13. static hubbub_error token_handler(const hubbub_token *token, void *pw);
  14.  
  15. static void *myrealloc(void *ptr, size_t len, void *pw)
  16. {
  17.         UNUSED(pw);
  18.  
  19.         return realloc(ptr, len);
  20. }
  21.  
  22. static int run_test(int argc, char **argv, unsigned int CHUNK_SIZE)
  23. {
  24.         hubbub_parser *parser;
  25.         hubbub_parser_optparams params;
  26.         FILE *fp;
  27.         size_t len, origlen;
  28.         uint8_t *buf = alloca(CHUNK_SIZE);
  29.         const char *charset;
  30.         hubbub_charset_source cssource;
  31.  
  32.         UNUSED(argc);
  33.  
  34.         assert(hubbub_parser_create("UTF-8", false, myrealloc, NULL, &parser) ==
  35.                         HUBBUB_OK);
  36.  
  37.         params.token_handler.handler = token_handler;
  38.         params.token_handler.pw = NULL;
  39.         assert(hubbub_parser_setopt(parser, HUBBUB_PARSER_TOKEN_HANDLER,
  40.                         &params) == HUBBUB_OK);
  41.  
  42.         fp = fopen(argv[1], "rb");
  43.         if (fp == NULL) {
  44.                 printf("Failed opening %s\n", argv[1]);
  45.                 return 1;
  46.         }
  47.  
  48.         fseek(fp, 0, SEEK_END);
  49.         origlen = len = ftell(fp);
  50.         fseek(fp, 0, SEEK_SET);
  51.  
  52.         while (len > 0) {
  53.                 ssize_t bytes_read = fread(buf, 1, CHUNK_SIZE, fp);
  54.                
  55.                 if (bytes_read < 1)
  56.                         break;
  57.                
  58.                 assert(hubbub_parser_parse_chunk(parser,
  59.                                 buf, bytes_read) == HUBBUB_OK);
  60.  
  61.                 len -= bytes_read;
  62.         }
  63.        
  64.         assert(len == 0);
  65.  
  66.         fclose(fp);
  67.  
  68.         charset = hubbub_parser_read_charset(parser, &cssource);
  69.  
  70.         printf("Charset: %s (from %d)\n", charset, cssource);
  71.  
  72.         hubbub_parser_destroy(parser);
  73.  
  74.         printf("PASS\n");
  75.  
  76.         return 0;
  77. }
  78.  
  79. int main(int argc, char **argv)
  80. {
  81.         int ret;
  82.         int shift;
  83.         int offset;
  84.         if (argc != 2) {
  85.                 printf("Usage: %s <filename>\n", argv[0]);
  86.                 return 1;
  87.         }
  88. #define DO_TEST(n) if ((ret = run_test(argc, argv, (n))) != 0) return ret
  89.         for (shift = 0; (1 << shift) != 16384; shift++)
  90.                 for (offset = 0; offset < 10; offset += 3)
  91.                         DO_TEST((1 << shift) + offset);
  92.         return 0;
  93. #undef DO_TEST
  94. }
  95.  
  96. hubbub_error token_handler(const hubbub_token *token, void *pw)
  97. {
  98.         static const char *token_names[] = {
  99.                 "DOCTYPE", "START TAG", "END TAG",
  100.                 "COMMENT", "CHARACTERS", "EOF"
  101.         };
  102.         size_t i;
  103.  
  104.         UNUSED(pw);
  105.  
  106.         printf("%s: ", token_names[token->type]);
  107.  
  108.         switch (token->type) {
  109.         case HUBBUB_TOKEN_DOCTYPE:
  110.                 printf("'%.*s' %sids:\n",
  111.                                 (int) token->data.doctype.name.len,
  112.                                 token->data.doctype.name.ptr,
  113.                                 token->data.doctype.force_quirks ?
  114.                                                 "(force-quirks) " : "");
  115.  
  116.                 if (token->data.doctype.public_missing)
  117.                         printf("\tpublic: missing\n");
  118.                 else
  119.                         printf("\tpublic: '%.*s'\n",
  120.                                 (int) token->data.doctype.public_id.len,
  121.                                 token->data.doctype.public_id.ptr);
  122.  
  123.                 if (token->data.doctype.system_missing)
  124.                         printf("\tsystem: missing\n");
  125.                 else
  126.                         printf("\tsystem: '%.*s'\n",
  127.                                 (int) token->data.doctype.system_id.len,
  128.                                 token->data.doctype.system_id.ptr);
  129.  
  130.                 break;
  131.         case HUBBUB_TOKEN_START_TAG:
  132.                 printf("'%.*s' %s%s\n",
  133.                                 (int) token->data.tag.name.len,
  134.                                 token->data.tag.name.ptr,
  135.                                 (token->data.tag.self_closing) ?
  136.                                                 "(self-closing) " : "",
  137.                                 (token->data.tag.n_attributes > 0) ?
  138.                                                 "attributes:" : "");
  139.                 for (i = 0; i < token->data.tag.n_attributes; i++) {
  140.                         printf("\t'%.*s' = '%.*s'\n",
  141.                                         (int) token->data.tag.attributes[i].name.len,
  142.                                         token->data.tag.attributes[i].name.ptr,
  143.                                         (int) token->data.tag.attributes[i].value.len,
  144.                                         token->data.tag.attributes[i].value.ptr);
  145.                 }
  146.                 break;
  147.         case HUBBUB_TOKEN_END_TAG:
  148.                 printf("'%.*s' %s%s\n",
  149.                                 (int) token->data.tag.name.len,
  150.                                 token->data.tag.name.ptr,
  151.                                 (token->data.tag.self_closing) ?
  152.                                                 "(self-closing) " : "",
  153.                                 (token->data.tag.n_attributes > 0) ?
  154.                                                 "attributes:" : "");
  155.                 for (i = 0; i < token->data.tag.n_attributes; i++) {
  156.                         printf("\t'%.*s' = '%.*s'\n",
  157.                                         (int) token->data.tag.attributes[i].name.len,
  158.                                         token->data.tag.attributes[i].name.ptr,
  159.                                         (int) token->data.tag.attributes[i].value.len,
  160.                                         token->data.tag.attributes[i].value.ptr);
  161.                 }
  162.                 break;
  163.         case HUBBUB_TOKEN_COMMENT:
  164.                 printf("'%.*s'\n", (int) token->data.comment.len,
  165.                                 token->data.comment.ptr);
  166.                 break;
  167.         case HUBBUB_TOKEN_CHARACTER:
  168.                 printf("'%.*s'\n", (int) token->data.character.len,
  169.                                 token->data.character.ptr);
  170.                 break;
  171.         case HUBBUB_TOKEN_EOF:
  172.                 printf("\n");
  173.                 break;
  174.         }
  175.  
  176.         return HUBBUB_OK;
  177. }
  178.