📄 sgml-parser.c
字号:
/* Tool for testing the SGML parser */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "elinks.h"#include "dom/node.h"#include "dom/sgml/parser.h"#include "dom/stack.h"/* Print the string in a compressed form: a single line with newlines etc. * replaced with "\\n" sequence. */static voidprint_compressed_string(struct dom_string *string){ unsigned char escape[3] = { '\\', '?', 0 }; size_t pos; for (pos = 0; pos < string->length; pos++) { unsigned char data = string->string[pos]; switch (data) { case '\n': escape[1] = 'n'; break; case '\r': escape[1] = 'r'; break; case '\t': escape[1] = 't'; break; default: putchar(data); continue; } printf("%s", escape); }}/* Set @string to the value of the given @node, however, with strings * compressed and entity references 'expanded'. */static voidprint_dom_node_value(struct dom_node *node){ struct dom_string *value; assert(node); switch (node->type) { case DOM_NODE_ENTITY_REFERENCE: /* FIXME: Set to the entity value. */ printf("%.*s", node->string.length, node->string.string); break; default: value = get_dom_node_value(node); if (!value) { printf("(no value)"); return; } print_compressed_string(value); }}static unsigned char indent_string[] = " ";#define get_indent_offset(stack) \ (((stack)->depth < sizeof(indent_string)/2 ? (stack)->depth * 2 : sizeof(indent_string)) - 2)static voidsgml_parser_test_tree(struct dom_stack *stack, struct dom_node *node, void *data){ struct dom_string *value = &node->string; struct dom_string *name = get_dom_node_name(node); printf("%.*s%.*s: %.*s\n", get_indent_offset(stack), indent_string, name->length, name->string, value->length, value->string);}static voidsgml_parser_test_id_leaf(struct dom_stack *stack, struct dom_node *node, void *data){ struct dom_string *name; struct dom_string *id; assert(node); name = get_dom_node_name(node); id = get_dom_node_type_name(node->type); printf("%.*s%.*s: %.*s -> ", get_indent_offset(stack), indent_string, id->length, id->string, name->length, name->string); print_dom_node_value(node); printf("\n");}static voidsgml_parser_test_leaf(struct dom_stack *stack, struct dom_node *node, void *data){ struct dom_string *name; assert(node); name = get_dom_node_name(node); printf("%.*s%.*s: ", get_indent_offset(stack), indent_string, name->length, name->string); print_dom_node_value(node); printf("\n");}static voidsgml_parser_test_branch(struct dom_stack *stack, struct dom_node *node, void *data){ struct dom_string *name; struct dom_string *id; assert(node); name = get_dom_node_name(node); id = get_dom_node_type_name(node->type); printf("%.*s%.*s: %.*s\n", get_indent_offset(stack), indent_string, id->length, id->string, name->length, name->string);}struct dom_stack_context_info sgml_parser_test_context_info = { /* Object size: */ 0, /* Push: */ { /* */ NULL, /* DOM_NODE_ELEMENT */ sgml_parser_test_branch, /* DOM_NODE_ATTRIBUTE */ sgml_parser_test_id_leaf, /* DOM_NODE_TEXT */ sgml_parser_test_leaf, /* DOM_NODE_CDATA_SECTION */ sgml_parser_test_leaf, /* DOM_NODE_ENTITY_REFERENCE */ sgml_parser_test_branch, /* DOM_NODE_ENTITY */ sgml_parser_test_id_leaf, /* DOM_NODE_PROC_INSTRUCTION */ sgml_parser_test_id_leaf, /* DOM_NODE_COMMENT */ sgml_parser_test_leaf, /* DOM_NODE_DOCUMENT */ sgml_parser_test_tree, /* DOM_NODE_DOCUMENT_TYPE */ sgml_parser_test_id_leaf, /* DOM_NODE_DOCUMENT_FRAGMENT */ sgml_parser_test_id_leaf, /* DOM_NODE_NOTATION */ sgml_parser_test_id_leaf, }, /* Pop: */ { /* */ NULL, /* DOM_NODE_ELEMENT */ NULL, /* DOM_NODE_ATTRIBUTE */ NULL, /* DOM_NODE_TEXT */ NULL, /* DOM_NODE_CDATA_SECTION */ NULL, /* DOM_NODE_ENTITY_REFERENCE */ NULL, /* DOM_NODE_ENTITY */ NULL, /* DOM_NODE_PROC_INSTRUCTION */ NULL, /* DOM_NODE_COMMENT */ NULL, /* DOM_NODE_DOCUMENT */ NULL, /* DOM_NODE_DOCUMENT_TYPE */ NULL, /* DOM_NODE_DOCUMENT_FRAGMENT */ NULL, /* DOM_NODE_NOTATION */ NULL, }};void die(const char *msg, ...){ va_list args; if (msg) { va_start(args, msg); vfprintf(stderr, msg, args); fputs("\n", stderr); va_end(args); } exit(!!NULL);}intmain(int argc, char *argv[]){ struct dom_node *root; struct sgml_parser *parser; enum sgml_document_type doctype = SGML_DOCTYPE_HTML; struct dom_string uri = INIT_DOM_STRING("dom://test", -1); struct dom_string source = INIT_DOM_STRING("(no source)", -1); int i; for (i = 1; i < argc; i++) { char *arg = argv[i]; if (strncmp(arg, "--", 2)) break; arg += 2; if (!strncmp(arg, "uri", 3)) { arg += 3; if (*arg == '=') { arg++; set_dom_string(&uri, arg, strlen(arg)); } else { i++; if (i >= argc) die("--uri expects a URI"); set_dom_string(&uri, argv[i], strlen(argv[i])); } } else if (!strncmp(arg, "src", 3)) { arg += 3; if (*arg == '=') { arg++; set_dom_string(&source, arg, strlen(arg)); } else { i++; if (i >= argc) die("--src expects a string"); set_dom_string(&source, argv[i], strlen(argv[i])); } } else if (!strcmp(arg, "help")) { die(NULL); } else { die("Unknown argument '%s'", arg - 2); } } parser = init_sgml_parser(SGML_PARSER_STREAM, doctype, &uri); if (!parser) return 1; add_dom_stack_context(&parser->stack, NULL, &sgml_parser_test_context_info); root = parse_sgml(parser, &source); if (root) { assert(parser->stack.depth == 1); get_dom_stack_top(&parser->stack)->immutable = 0; /* For SGML_PARSER_STREAM this will free the DOM * root node. */ pop_dom_node(&parser->stack); } done_sgml_parser(parser); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -