From 2361ad944c65ad9118b76cb3d223129fb34f21a9 Mon Sep 17 00:00:00 2001
From: Pablo Rodríguez
Date: Sun, 7 Sep 2014 19:29:32 +0200
Subject: typo replacing CommonMark corrected
---
js/stmd.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/stmd.js b/js/stmd.js
index 15d7345..4b3d83e 100755
--- a/js/stmd.js
+++ b/js/stmd.js
@@ -1,4 +1,4 @@
-// stmd.js - CommomMark in javascript
+// stmd.js - CommonMark in javascript
// Copyright (C) 2014 John MacFarlane
// License: BSD3.
--
cgit v1.2.3
From 78d53ae2866c9bb3e24d0b2d5c7f65cd2f8b4898 Mon Sep 17 00:00:00 2001
From: Gérald Barré
Date: Mon, 8 Sep 2014 11:05:24 +0200
Subject: Fix some compatibility issues
- Use `String.charAt(index)` instead of array like syntax for browser compatibility.
- Use `Array.slice(index, length)` instead of `Array.slice(index)` for browser compatibility.
---
js/stmd.js | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/js/stmd.js b/js/stmd.js
index 15d7345..1ee2206 100755
--- a/js/stmd.js
+++ b/js/stmd.js
@@ -139,7 +139,7 @@ var match = function(re) {
// Returns the character at the current subject position, or null if
// there are no more characters.
var peek = function() {
- return this.subject[this.pos] || null;
+ return this.subject.charAt(this.pos) || null;
};
// Parse zero or more space characters, including at most one newline
@@ -185,13 +185,13 @@ var parseBackticks = function(inlines) {
var parseEscaped = function(inlines) {
var subj = this.subject,
pos = this.pos;
- if (subj[pos] === '\\') {
- if (subj[pos + 1] === '\n') {
+ if (subj.charAt(pos) === '\\') {
+ if (subj.charAt(pos + 1) === '\n') {
inlines.push({ t: 'Hardbreak' });
this.pos = this.pos + 2;
return 2;
- } else if (reEscapable.test(subj[pos + 1])) {
- inlines.push({ t: 'Str', c: subj[pos + 1] });
+ } else if (reEscapable.test(subj.charAt(pos + 1))) {
+ inlines.push({ t: 'Str', c: subj.charAt(pos + 1) });
this.pos = this.pos + 2;
return 2;
} else {
@@ -245,7 +245,7 @@ var scanDelims = function(c) {
var startpos = this.pos;
char_before = this.pos === 0 ? '\n' :
- this.subject[this.pos - 1];
+ this.subject.charAt(this.pos - 1);
while (this.peek() === c) {
numdelims++;
@@ -309,7 +309,7 @@ var parseEmphasis = function(inlines) {
// into an Emph whose contents are the succeeding inlines
inlines[delimpos].t = 'Emph';
inlines[delimpos].c = inlines.slice(delimpos + 1);
- inlines.splice(delimpos + 1);
+ inlines.splice(delimpos + 1, inlines.length - delimpos - 1);
break;
} else {
if (this.parseInline(inlines) === 0) {
@@ -326,7 +326,7 @@ var parseEmphasis = function(inlines) {
this.pos += 2;
inlines[delimpos].t = 'Strong';
inlines[delimpos].c = inlines.slice(delimpos + 1);
- inlines.splice(delimpos + 1);
+ inlines.splice(delimpos + 1, inlines.length - delimpos - 1);
break;
} else {
if (this.parseInline(inlines) === 0) {
@@ -500,7 +500,7 @@ var parseLink = function(inlines) {
((dest = this.parseLinkDestination()) !== null) &&
this.spnl() &&
// make sure there's a space before the title:
- (/^\s/.test(this.subject[this.pos - 1]) &&
+ (/^\s/.test(this.subject.charAt(this.pos - 1)) &&
(title = this.parseLinkTitle() || '') || true) &&
this.spnl() &&
this.match(/^\)/)) {
@@ -857,7 +857,7 @@ var parseListMarker = function(ln, offset) {
if ((match = rest.match(/^[*+-]( +|$)/))) {
spaces_after_marker = match[1].length;
data.type = 'Bullet';
- data.bullet_char = match[0][0];
+ data.bullet_char = match[0].charAt(0);
} else if ((match = rest.match(/^(\d+)([.)])( +|$)/))) {
spaces_after_marker = match[3].length;
@@ -932,10 +932,10 @@ var incorporateLine = function(ln, line_number) {
switch (container.t) {
case 'BlockQuote':
- var matched = indent <= 3 && ln[first_nonspace] === '>';
+ var matched = indent <= 3 && ln.charAt(first_nonspace) === '>';
if (matched) {
offset = first_nonspace + 1;
- if (ln[offset] === ' ') {
+ if (ln.charAt(offset) === ' ') {
offset++;
}
} else {
@@ -975,7 +975,7 @@ var incorporateLine = function(ln, line_number) {
case 'FencedCode':
// skip optional spaces of fence offset
i = container.fence_offset;
- while (i > 0 && ln[offset] === ' ') {
+ while (i > 0 && ln.charAt(offset) === ' ') {
offset++;
i--;
}
@@ -1052,11 +1052,11 @@ var incorporateLine = function(ln, line_number) {
break;
}
- } else if (ln[first_nonspace] === '>') {
+ } else if (ln.charAt(first_nonspace) === '>') {
// blockquote
offset = first_nonspace + 1;
// optional following space
- if (ln[offset] === ' ') {
+ if (ln.charAt(offset) === ' ') {
offset++;
}
closeUnmatchedBlocks(this);
@@ -1079,7 +1079,7 @@ var incorporateLine = function(ln, line_number) {
closeUnmatchedBlocks(this);
container = this.addChild('FencedCode', line_number, first_nonspace);
container.fence_length = fence_length;
- container.fence_char = match[0][0];
+ container.fence_char = match[0].charAt(0);
container.fence_offset = first_nonspace - offset;
offset = first_nonspace + fence_length;
break;
@@ -1097,7 +1097,7 @@ var incorporateLine = function(ln, line_number) {
// setext header line
closeUnmatchedBlocks(this);
container.t = 'SetextHeader'; // convert Paragraph to SetextHeader
- container.level = match[0][0] === '=' ? 1 : 2;
+ container.level = match[0].charAt(0) === '=' ? 1 : 2;
offset = ln.length;
} else if (matchAt(reHrule, ln, first_nonspace) !== null) {
@@ -1189,7 +1189,7 @@ var incorporateLine = function(ln, line_number) {
case 'FencedCode':
// check for closing code fence:
match = (indent <= 3 &&
- ln[first_nonspace] == container.fence_char &&
+ ln.charAt(first_nonspace) == container.fence_char &&
ln.slice(first_nonspace).match(/^(?:`{3,}|~{3,})(?= *$)/));
if (match && match[0].length >= container.fence_length) {
// don't add closing fence to container; instead, close it:
@@ -1248,7 +1248,7 @@ var finalize = function(block, line_number) {
block.string_content = block.strings.join('\n').replace(/^ */m,'');
// try parsing the beginning as link reference definitions:
- while (block.string_content[0] === '[' &&
+ while (block.string_content.charAt(0) === '[' &&
(pos = this.inlineParser.parseReference(block.string_content,
this.refmap))) {
block.string_content = block.string_content.slice(pos);
--
cgit v1.2.3
From 80d01efafda1be0fd6a013eb590dde637f10616b Mon Sep 17 00:00:00 2001
From: Knagis
Date: Mon, 8 Sep 2014 23:34:35 +0300
Subject: Updated to support Perl on Windows
waitpid() is required because otherwise Perl on Windows might fail after 64 or 128 tests.
removing '\r' from both test output and generated output enables both spec.txt and the generated results to contain Windows newlines (\r\n).
---
runtests.pl | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/runtests.pl b/runtests.pl
index 2e2b795..d847140 100644
--- a/runtests.pl
+++ b/runtests.pl
@@ -69,15 +69,21 @@ sub dotest
# We use → to indicate tab and ␣ space in the spec
$markdown =~ s/→/\t/g;s/␣/ /g;
$html =~ s/→/\t/g;s/␣/ /g;
- open2(my $out, my $in, @PROG);
+ my $pid = open2(my $out, my $in, @PROG);
print $in $markdown;
close $in;
flush $out;
$actual = do { local $/; <$out>; };
close $out;
+ waitpid($pid, 0);
$html = &tidy($html);
$actual = &tidy($actual);
$actual =~ s/\'/'/;
+
+ # remove \r to allow mixing of linux/windows newlines
+ $actual =~ s/\r//g;
+ $html =~ s/\r//g;
+
if ($actual eq $html) {
print colored("✓", "green");
return 1;
--
cgit v1.2.3
From e216094e2192c05ddbd0988458eb8c0012e7baf8 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 2 Sep 2014 01:10:54 +0200
Subject: lol
---
Makefile | 19 +-
src/blocks.c | 1352 +++++++++++----------
src/bstrlib.c | 2979 ----------------------------------------------
src/bstrlib.h | 304 -----
src/buffer.c | 313 +++++
src/buffer.h | 119 ++
src/case_fold_switch.c | 2637 ----------------------------------------
src/case_fold_switch.inc | 2637 ++++++++++++++++++++++++++++++++++++++++
src/casefold.c | 2699 -----------------------------------------
src/detab.c | 48 -
src/getopt.c | 199 ----
src/inlines.c | 1711 +++++++++++++-------------
src/main.c | 2 +-
src/scanners.h | 28 +-
src/scanners.re | 54 +-
src/stmd.h | 76 +-
src/utf8.c | 221 ++--
17 files changed, 4889 insertions(+), 10509 deletions(-)
delete mode 100644 src/bstrlib.c
delete mode 100644 src/bstrlib.h
create mode 100644 src/buffer.c
create mode 100644 src/buffer.h
delete mode 100644 src/case_fold_switch.c
create mode 100644 src/case_fold_switch.inc
delete mode 100644 src/casefold.c
delete mode 100644 src/detab.c
delete mode 100644 src/getopt.c
diff --git a/Makefile b/Makefile
index 55b6645..cb5938d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-g -O3 -Wall -Werror
+CFLAGS=-ggdb3 -O0 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS=-ggdb3 -O0 -Wall -Werror
SRCDIR=src
DATADIR=data
@@ -41,13 +41,13 @@ testjs: spec.txt
benchjs:
node js/bench.js ${BENCHINP}
-$(PROG): $(SRCDIR)/main.c $(SRCDIR)/inlines.o $(SRCDIR)/blocks.o $(SRCDIR)/detab.o $(SRCDIR)/bstrlib.o $(SRCDIR)/scanners.o $(SRCDIR)/print.o $(SRCDIR)/html.o $(SRCDIR)/utf8.o
+$(PROG): $(SRCDIR)/main.c $(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/html.o $(SRCDIR)/utf8.o
$(CC) $(LDFLAGS) -o $@ $^
$(SRCDIR)/scanners.c: $(SRCDIR)/scanners.re
re2c --case-insensitive -bis $< > $@ || (rm $@ && false)
-$(SRCDIR)/case_fold_switch.c: $(DATADIR)/CaseFolding-3.2.0.txt
+$(SRCDIR)/case_fold_switch.inc $(DATADIR)/CaseFolding-3.2.0.txt
perl mkcasefold.pl < $< > $@
.PHONY: leakcheck clean fuzztest dingus upload
@@ -58,6 +58,9 @@ dingus:
leakcheck: $(PROG)
cat oldtests/*/*.markdown | valgrind --leak-check=full --dsymutil=yes $(PROG)
+operf: $(PROG)
+ operf $(PROG) /dev/null
+
fuzztest:
for i in `seq 1 10`; do \
time cat /dev/urandom | head -c 100000 | iconv -f latin1 -t utf-8 | $(PROG) >/dev/null; done
@@ -69,7 +72,7 @@ update-site: spec.html narrative.html
(cd _site ; git pull ; git commit -a -m "Updated site for latest spec, narrative, js" ; git push; cd ..)
clean:
- -rm test $(SRCDIR)/*.o $(SRCDIR)/scanners.c
- -rm -r *.dSYM
- -rm README.html
- -rm spec.md fuzz.txt spec.html
+ -rm -f test $(SRCDIR)/*.o $(SRCDIR)/scanners.c
+ -rm -rf *.dSYM
+ -rm -f README.html
+ -rm -f spec.md fuzz.txt spec.html
diff --git a/src/blocks.c b/src/blocks.c
index 2776231..eabac03 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -1,4 +1,5 @@
#include
+#include
#include
#include
#include
@@ -10,738 +11,767 @@
static block* make_block(int tag, int start_line, int start_column)
{
- block* e;
- e = (block*) malloc(sizeof(block));
- e->tag = tag;
- e->open = true;
- e->last_line_blank = false;
- e->start_line = start_line;
- e->start_column = start_column;
- e->end_line = start_line;
- e->children = NULL;
- e->last_child = NULL;
- e->parent = NULL;
- e->top = NULL;
- e->attributes.refmap = NULL;
- e->string_content = bfromcstr("");
- e->inline_content = NULL;
- e->next = NULL;
- e->prev = NULL;
- return e;
+ block* e;
+ e = (block*) malloc(sizeof(block));
+ e->tag = tag;
+ e->open = true;
+ e->last_line_blank = false;
+ e->start_line = start_line;
+ e->start_column = start_column;
+ e->end_line = start_line;
+ e->children = NULL;
+ e->last_child = NULL;
+ e->parent = NULL;
+ e->top = NULL;
+ e->attributes.refmap = NULL;
+ gh_buf_init(&e->string_content, 32);
+ e->string_pos = 0;
+ e->inline_content = NULL;
+ e->next = NULL;
+ e->prev = NULL;
+ return e;
}
// Create a root document block.
extern block* make_document()
{
- block * e = make_block(document, 1, 1);
- reference * map = NULL;
- reference ** refmap;
- refmap = (reference**) malloc(sizeof(reference*));
- *refmap = map;
- e->attributes.refmap = refmap;
- e->top = e;
- return e;
+ block * e = make_block(document, 1, 1);
+ reference * map = NULL;
+ reference ** refmap;
+ refmap = (reference**) malloc(sizeof(reference*));
+ *refmap = map;
+ e->attributes.refmap = refmap;
+ e->top = e;
+ return e;
}
// Returns true if line has only space characters, else false.
-bool is_blank(bstring s, int offset)
+bool is_blank(gh_buf *s, int offset)
{
- char c;
- while ((c = bchar(s, offset))) {
- if (c == '\n') {
- return true;
- } else if (c == ' ') {
- offset++;
- } else {
- return false;
- }
- }
- return true;
+ while (offset < s->size) {
+ switch (s->ptr[offset]) {
+ case '\n':
+ return true;
+ case ' ':
+ offset++;
+ default:
+ return false;
+ }
+ }
+
+ return true;
}
static inline bool can_contain(int parent_type, int child_type)
{
- return ( parent_type == document ||
- parent_type == block_quote ||
- parent_type == list_item ||
- (parent_type == list && child_type == list_item) );
+ return ( parent_type == document ||
+ parent_type == block_quote ||
+ parent_type == list_item ||
+ (parent_type == list && child_type == list_item) );
}
static inline bool accepts_lines(int block_type)
{
- return (block_type == paragraph ||
- block_type == atx_header ||
- block_type == indented_code ||
- block_type == fenced_code);
+ return (block_type == paragraph ||
+ block_type == atx_header ||
+ block_type == indented_code ||
+ block_type == fenced_code);
}
-static int add_line(block* block, bstring ln, int offset)
+static void add_line(block* block, gh_buf *ln, int offset)
{
- bstring s = bmidstr(ln, offset, blength(ln) - offset);
- check(block->open, "attempted to add line (%s) to closed container (%d)",
- ln->data, block->tag);
- check(bformata(block->string_content, "%s", s->data) == 0,
- "could not append line to string_content");
- bdestroy(s);
- return 0;
- error:
- return -1;
+ assert(block->open);
+ gh_buf_put(&block->string_content, ln->ptr + offset, ln->size - offset);
}
-static int remove_trailing_blank_lines(bstring ln)
+static void remove_trailing_blank_lines(gh_buf *ln)
{
- bstring tofind = bfromcstr(" \t\r\n");
- int pos;
- // find last nonspace:
- pos = bninchrr(ln, blength(ln) - 1, tofind);
- if (pos == BSTR_ERR) { // all spaces
- bassigncstr(ln, "");
- } else {
- // find next newline after it
- pos = bstrchrp(ln, '\n', pos);
- if (pos != BSTR_ERR) {
- check(bdelete(ln, pos, blength(ln) - pos) != BSTR_ERR,
- "failed to delete trailing blank lines");
- }
- }
- bdestroy(tofind);
- return 0;
- error:
- return -1;
+ int i;
+
+ for (i = ln->size - 1; i >= 0; --i) {
+ char c = ln->ptr[i];
+
+ if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
+ break;
+ }
+
+ if (i < 0) {
+ gh_buf_clear(ln);
+ return;
+ }
+
+ i = gh_buf_strchr(ln, '\n', i);
+ if (i >= 0)
+ gh_buf_truncate(ln, i + 1);
}
// Check to see if a block ends with a blank line, descending
// if needed into lists and sublists.
static bool ends_with_blank_line(block* block)
{
- if (block->last_line_blank) {
- return true;
- }
- if ((block->tag == list || block->tag == list_item) && block->last_child) {
- return ends_with_blank_line(block->last_child);
- } else {
- return false;
- }
+ if (block->last_line_blank) {
+ return true;
+ }
+ if ((block->tag == list || block->tag == list_item) && block->last_child) {
+ return ends_with_blank_line(block->last_child);
+ } else {
+ return false;
+ }
}
// Break out of all containing lists
static int break_out_of_lists(block ** bptr, int line_number)
{
- block * container = *bptr;
- block * b = container->top;
- // find first containing list:
- while (b && b->tag != list) {
- b = b->last_child;
- }
- if (b) {
- while (container && container != b) {
- finalize(container, line_number);
- container = container->parent;
- }
- finalize(b, line_number);
- *bptr = b->parent;
- }
- return 0;
+ block * container = *bptr;
+ block * b = container->top;
+ // find first containing list:
+ while (b && b->tag != list) {
+ b = b->last_child;
+ }
+ if (b) {
+ while (container && container != b) {
+ finalize(container, line_number);
+ container = container->parent;
+ }
+ finalize(b, line_number);
+ *bptr = b->parent;
+ }
+ return 0;
}
-extern int finalize(block* b, int line_number)
+extern void finalize(block* b, int line_number)
{
- int firstlinelen;
- int pos;
- block* item;
- block* subitem;
-
- check(b != NULL, "finalize called on null block");
- if (!b->open) {
- return 0; // don't do anything if the block is already closed
- }
- b->open = false;
- if (line_number > b->start_line) {
- b->end_line = line_number - 1;
- } else {
- b->end_line = line_number;
- }
-
- switch (b->tag) {
-
- case paragraph:
- pos = 0;
- while (bchar(b->string_content, 0) == '[' &&
- (pos = parse_reference(b->string_content,
- b->top->attributes.refmap))) {
- bdelete(b->string_content, 0, pos);
- }
- if (is_blank(b->string_content, 0)) {
- b->tag = reference_def;
- }
- break;
-
- case indented_code:
- remove_trailing_blank_lines(b->string_content);
- bformata(b->string_content, "\n");
- break;
-
- case fenced_code:
- // first line of contents becomes info
- firstlinelen = bstrchr(b->string_content, '\n');
- b->attributes.fenced_code_data.info =
- bmidstr(b->string_content, 0, firstlinelen);
- bdelete(b->string_content, 0, firstlinelen + 1); // +1 for \n
- btrimws(b->attributes.fenced_code_data.info);
- unescape(b->attributes.fenced_code_data.info);
- break;
-
- case list: // determine tight/loose status
- b->attributes.list_data.tight = true; // tight by default
- item = b->children;
-
- while (item) {
- // check for non-final non-empty list item ending with blank line:
- if (item->last_line_blank && item->next) {
- b->attributes.list_data.tight = false;
- break;
- }
- // recurse into children of list item, to see if there are
- // spaces between them:
- subitem = item->children;
- while (subitem) {
- if (ends_with_blank_line(subitem) &&
- (item->next || subitem->next)) {
- b->attributes.list_data.tight = false;
- break;
- }
- subitem = subitem->next;
- }
- if (!(b->attributes.list_data.tight)) {
- break;
- }
- item = item->next;
- }
-
- break;
-
- default:
- break;
- }
-
- return 0;
- error:
- return -1;
+ int firstlinelen;
+ int pos;
+ block* item;
+ block* subitem;
+
+ if (!b->open)
+ return; // don't do anything if the block is already closed
+
+ b->open = false;
+ if (line_number > b->start_line) {
+ b->end_line = line_number - 1;
+ } else {
+ b->end_line = line_number;
+ }
+
+ switch (b->tag) {
+ case paragraph:
+ pos = 0;
+ while (gh_buf_at(&b->string_content, b->string_pos) == '[' &&
+ (pos = parse_reference(&b->string_content, b->string_pos,
+ b->top->attributes.refmap))) {
+ b->string_pos = pos;
+ }
+ if (is_blank(&b->string_content, b->string_pos)) {
+ b->tag = reference_def;
+ }
+ break;
+
+ case indented_code:
+ remove_trailing_blank_lines(&b->string_content);
+ gh_buf_putc(&b->string_content, '\n');
+ break;
+
+ case fenced_code:
+ // first line of contents becomes info
+ firstlinelen = gh_buf_strchr(&b->string_content, '\n', b->string_pos);
+ gh_buf_set(
+ &b->attributes.fenced_code_data.info,
+ b->string_content.ptr + b->string_pos,
+ firstlinelen
+ );
+
+ b->string_pos = firstlinelen + 1;
+
+ gh_buf_trim(&b->attributes.fenced_code_data.info);
+ unescape_buffer(&b->attributes.fenced_code_data.info);
+ break;
+
+ case list: // determine tight/loose status
+ b->attributes.list_data.tight = true; // tight by default
+ item = b->children;
+
+ while (item) {
+ // check for non-final non-empty list item ending with blank line:
+ if (item->last_line_blank && item->next) {
+ b->attributes.list_data.tight = false;
+ break;
+ }
+ // recurse into children of list item, to see if there are
+ // spaces between them:
+ subitem = item->children;
+ while (subitem) {
+ if (ends_with_blank_line(subitem) &&
+ (item->next || subitem->next)) {
+ b->attributes.list_data.tight = false;
+ break;
+ }
+ subitem = subitem->next;
+ }
+ if (!(b->attributes.list_data.tight)) {
+ break;
+ }
+ item = item->next;
+ }
+
+ break;
+
+ default:
+ break;
+ }
}
// Add a block as child of another. Return pointer to child.
extern block* add_child(block* parent,
- int block_type, int start_line, int start_column)
+ int block_type, int start_line, int start_column)
{
- // if 'parent' isn't the kind of block that can accept this child,
- // then back up til we hit a block that can.
- while (!can_contain(parent->tag, block_type)) {
- finalize(parent, start_line);
- parent = parent->parent;
- }
-
- check(parent != NULL, "parent container cannot accept children");
-
- block* child = make_block(block_type, start_line, start_column);
- child->parent = parent;
- child->top = parent->top;
-
- if (parent->last_child) {
- parent->last_child->next = child;
- child->prev = parent->last_child;
- } else {
- parent->children = child;
- child->prev = NULL;
- }
- parent->last_child = child;
- return child;
- error:
- return NULL;
+ assert(parent);
+
+ // if 'parent' isn't the kind of block that can accept this child,
+ // then back up til we hit a block that can.
+ while (!can_contain(parent->tag, block_type)) {
+ finalize(parent, start_line);
+ parent = parent->parent;
+ }
+
+ block* child = make_block(block_type, start_line, start_column);
+ child->parent = parent;
+ child->top = parent->top;
+
+ if (parent->last_child) {
+ parent->last_child->next = child;
+ child->prev = parent->last_child;
+ } else {
+ parent->children = child;
+ child->prev = NULL;
+ }
+ parent->last_child = child;
+ return child;
}
// Free a block list and any children.
extern void free_blocks(block* e)
{
- block * next;
- while (e != NULL) {
- next = e->next;
- free_inlines(e->inline_content);
- bdestroy(e->string_content);
- if (e->tag == fenced_code) {
- bdestroy(e->attributes.fenced_code_data.info);
- } else if (e->tag == document) {
- free_reference_map(e->attributes.refmap);
- }
- free_blocks(e->children);
- free(e);
- e = next;
- }
+ block * next;
+ while (e != NULL) {
+ next = e->next;
+ free_inlines(e->inline_content);
+ gh_buf_free(&e->string_content);
+ if (e->tag == fenced_code) {
+ gh_buf_free(&e->attributes.fenced_code_data.info);
+ } else if (e->tag == document) {
+ free_reference_map(e->attributes.refmap);
+ }
+ free_blocks(e->children);
+ free(e);
+ e = next;
+ }
}
// Walk through block and all children, recursively, parsing
// string content into inline content where appropriate.
-int process_inlines(block* cur, reference** refmap)
+void process_inlines(block* cur, reference** refmap)
{
- switch (cur->tag) {
-
- case paragraph:
- case atx_header:
- case setext_header:
- check(cur->string_content != NULL, "string_content is NULL");
- cur->inline_content = parse_inlines(cur->string_content, refmap);
- bdestroy(cur->string_content);
- cur->string_content = NULL;
- break;
-
- default:
- break;
- }
-
- block * child = cur->children;
- while (child != NULL) {
- process_inlines(child, refmap);
- child = child->next;
- }
-
- return 0;
- error:
- return -1;
+ switch (cur->tag) {
+ case paragraph:
+ case atx_header:
+ case setext_header:
+ cur->inline_content = parse_inlines(&cur->string_content, cur->string_pos, refmap);
+ // MEM
+ // gh_buf_free(&cur->string_content);
+ break;
+
+ default:
+ break;
+ }
+
+ block *child = cur->children;
+ while (child != NULL) {
+ process_inlines(child, refmap);
+ child = child->next;
+ }
}
// Attempts to parse a list item marker (bullet or enumerated).
// On success, returns length of the marker, and populates
// data with the details. On failure, returns 0.
-static int parse_list_marker(bstring ln, int pos,
- struct ListData ** dataptr)
+static int parse_list_marker(gh_buf *ln, int pos,
+ struct ListData ** dataptr)
{
- char c;
- int startpos;
- int start = 1;
- struct ListData * data;
-
- startpos = pos;
- c = bchar(ln, pos);
-
- if ((c == '*' || c == '-' || c == '+') && !scan_hrule(ln, pos)) {
- pos++;
- if (!isspace(bchar(ln, pos))) {
- return 0;
- }
- data = malloc(sizeof(struct ListData));
- data->marker_offset = 0; // will be adjusted later
- data->list_type = bullet;
- data->bullet_char = c;
- data->start = 1;
- data->delimiter = period;
- data->tight = false;
-
- } else if (isdigit(c)) {
-
- pos++;
- while (isdigit(bchar(ln, pos))) {
- pos++;
- }
-
- if (!sscanf((char *) ln->data + startpos, "%d", &start)) {
- log_err("sscanf failed");
- return 0;
- }
-
- c = bchar(ln, pos);
- if (c == '.' || c == ')') {
- pos++;
- if (!isspace(bchar(ln, pos))) {
- return 0;
- }
- data = malloc(sizeof(struct ListData));
- data->marker_offset = 0; // will be adjusted later
- data->list_type = ordered;
- data->bullet_char = 0;
- data->start = start;
- data->delimiter = (c == '.' ? period : parens);
- data->tight = false;
- } else {
- return 0;
- }
-
- } else {
- return 0;
- }
-
- *dataptr = data;
- return (pos - startpos);
+ char c;
+ int startpos;
+ struct ListData * data;
+
+ startpos = pos;
+ c = gh_buf_at(ln, pos);
+
+ if ((c == '*' || c == '-' || c == '+') && !scan_hrule(ln, pos)) {
+ pos++;
+ if (!isspace(gh_buf_at(ln, pos))) {
+ return 0;
+ }
+ data = malloc(sizeof(struct ListData));
+ data->marker_offset = 0; // will be adjusted later
+ data->list_type = bullet;
+ data->bullet_char = c;
+ data->start = 1;
+ data->delimiter = period;
+ data->tight = false;
+
+ } else if (isdigit(c)) {
+ int start = 0;
+
+ do {
+ start = (10 * start) + (gh_buf_at(ln, pos) - '0');
+ pos++;
+ } while (isdigit(gh_buf_at(ln, pos)));
+
+ c = gh_buf_at(ln, pos);
+ if (c == '.' || c == ')') {
+ pos++;
+ if (!isspace(gh_buf_at(ln, pos))) {
+ return 0;
+ }
+ data = malloc(sizeof(struct ListData));
+ data->marker_offset = 0; // will be adjusted later
+ data->list_type = ordered;
+ data->bullet_char = 0;
+ data->start = start;
+ data->delimiter = (c == '.' ? period : parens);
+ data->tight = false;
+ } else {
+ return 0;
+ }
+
+ } else {
+ return 0;
+ }
+
+ *dataptr = data;
+ return (pos - startpos);
}
// Return 1 if list item belongs in list, else 0.
static int lists_match(struct ListData list_data,
- struct ListData item_data)
+ struct ListData item_data)
+{
+ return (list_data.list_type == item_data.list_type &&
+ list_data.delimiter == item_data.delimiter &&
+ // list_data.marker_offset == item_data.marker_offset &&
+ list_data.bullet_char == item_data.bullet_char);
+}
+
+static void expand_tabs(gh_buf *ob, const char *line, size_t size)
+{
+ size_t i = 0, tab = 0;
+
+ while (i < size) {
+ size_t org = i;
+
+ while (i < size && line[i] != '\t') {
+ i++; tab++;
+ }
+
+ if (i > org)
+ gh_buf_put(ob, line + org, i - org);
+
+ if (i >= size)
+ break;
+
+ do {
+ gh_buf_putc(ob, ' '); tab++;
+ } while (tab % 4);
+
+ i++;
+ }
+}
+
+extern block *stmd_parse_document(const char *buffer, size_t len)
{
- return (list_data.list_type == item_data.list_type &&
- list_data.delimiter == item_data.delimiter &&
- // list_data.marker_offset == item_data.marker_offset &&
- list_data.bullet_char == item_data.bullet_char);
+ gh_buf line = GH_BUF_INIT;
+
+ block *document = make_document();
+ int linenum = 1;
+ const char *end = buffer + len;
+
+ while (buffer < end) {
+ const char *eol = memchr(buffer, '\n', end - buffer);
+
+ if (!eol) {
+ expand_tabs(&line, buffer, end - buffer);
+ buffer = end;
+ } else {
+ expand_tabs(&line, buffer, (eol - buffer) + 1);
+ buffer += (eol - buffer) + 1;
+ }
+
+ incorporate_line(&line, linenum, &document);
+ gh_buf_clear(&line);
+ linenum++;
+ }
+
+ gh_buf_free(&line);
+
+ while (document != document->top) {
+ finalize(document, linenum);
+ document = document->parent;
+ }
+
+ finalize(document, linenum);
+ process_inlines(document, document->attributes.refmap);
+
+ return document;
}
// Process one line at a time, modifying a block.
// Returns 0 if successful. curptr is changed to point to
// the currently open block.
-extern int incorporate_line(bstring ln, int line_number, block** curptr)
+extern void incorporate_line(gh_buf *ln, int line_number, block** curptr)
{
- block* last_matched_container;
- int offset = 0;
- int matched = 0;
- int lev = 0;
- int i;
- struct ListData * data = NULL;
- bool all_matched = true;
- block* container;
- block* cur = *curptr;
- bool blank = false;
- int first_nonspace;
- int indent;
-
- // detab input line
- check(bdetab(ln, 1) != BSTR_ERR,
- "invalid UTF-8 sequence in line %d\n", line_number);
-
- // container starts at the document root.
- container = cur->top;
-
- // for each containing block, try to parse the associated line start.
- // bail out on failure: container will point to the last matching block.
-
- while (container->last_child && container->last_child->open) {
- container = container->last_child;
-
- first_nonspace = offset;
- while (bchar(ln, first_nonspace) == ' ') {
- first_nonspace++;
- }
-
- indent = first_nonspace - offset;
- blank = bchar(ln, first_nonspace) == '\n';
-
- if (container->tag == block_quote) {
-
- matched = indent <= 3 && bchar(ln, first_nonspace) == '>';
- if (matched) {
- offset = first_nonspace + 1;
- if (bchar(ln, offset) == ' ') {
- offset++;
- }
- } else {
- all_matched = false;
- }
-
- } else if (container->tag == list_item) {
-
- if (indent >= container->attributes.list_data.marker_offset +
- container->attributes.list_data.padding) {
- offset += container->attributes.list_data.marker_offset +
- container->attributes.list_data.padding;
- } else if (blank) {
- offset = first_nonspace;
- } else {
- all_matched = false;
- }
-
- } else if (container->tag == indented_code) {
-
- if (indent >= CODE_INDENT) {
- offset += CODE_INDENT;
- } else if (blank) {
- offset = first_nonspace;
- } else {
- all_matched = false;
- }
-
- } else if (container->tag == atx_header ||
- container->tag == setext_header) {
-
- // a header can never contain more than one line
- all_matched = false;
-
- } else if (container->tag == fenced_code) {
-
- // skip optional spaces of fence offset
- i = container->attributes.fenced_code_data.fence_offset;
- while (i > 0 && bchar(ln, offset) == ' ') {
- offset++;
- i--;
- }
-
- } else if (container->tag == html_block) {
-
- if (blank) {
- all_matched = false;
- }
-
- } else if (container->tag == paragraph) {
-
- if (blank) {
- container->last_line_blank =true;
- all_matched = false;
- }
-
- }
-
- if (!all_matched) {
- container = container->parent; // back up to last matching block
- break;
- }
- }
-
- last_matched_container = container;
-
- // check to see if we've hit 2nd blank line, break out of list:
- if (blank && container->last_line_blank) {
- break_out_of_lists(&container, line_number);
- }
-
- // unless last matched container is code block, try new container starts:
- while (container->tag != fenced_code && container->tag != indented_code &&
- container->tag != html_block) {
-
- first_nonspace = offset;
- while (bchar(ln, first_nonspace) == ' ') {
- first_nonspace++;
- }
-
- indent = first_nonspace - offset;
- blank = bchar(ln, first_nonspace) == '\n';
-
- if (indent >= CODE_INDENT) {
-
- if (cur->tag != paragraph && !blank) {
- offset += CODE_INDENT;
- container = add_child(container, indented_code, line_number, offset + 1);
- } else { // indent > 4 in lazy line
- break;
- }
-
- } else if (bchar(ln, first_nonspace) == '>') {
-
- offset = first_nonspace + 1;
- // optional following character
- if (bchar(ln, offset) == ' ') {
- offset++;
- }
- container = add_child(container, block_quote, line_number, offset + 1);
-
- } else if ((matched = scan_atx_header_start(ln, first_nonspace))) {
-
- offset = first_nonspace + matched;
- container = add_child(container, atx_header, line_number, offset + 1);
- int hashpos = bstrchrp(ln, '#', first_nonspace);
- check(hashpos != BSTR_ERR, "no # found in atx header start");
- int level = 0;
- while (bchar(ln, hashpos) == '#') {
- level++;
- hashpos++;
- }
- container->attributes.header_level = level;
-
- } else if ((matched = scan_open_code_fence(ln, first_nonspace))) {
-
- container = add_child(container, fenced_code, line_number,
- first_nonspace + 1);
- container->attributes.fenced_code_data.fence_char = bchar(ln,
- first_nonspace);
- container->attributes.fenced_code_data.fence_length = matched;
- container->attributes.fenced_code_data.fence_offset =
- first_nonspace - offset;
- offset = first_nonspace + matched;
-
- } else if ((matched = scan_html_block_tag(ln, first_nonspace))) {
-
- container = add_child(container, html_block, line_number,
- first_nonspace + 1);
- // note, we don't adjust offset because the tag is part of the text
-
- } else if (container->tag == paragraph &&
- (lev = scan_setext_header_line(ln, first_nonspace)) &&
- // check that there is only one line in the paragraph:
- bstrrchrp(container->string_content, '\n',
- blength(container->string_content) - 2) == BSTR_ERR) {
-
- container->tag = setext_header;
- container->attributes.header_level = lev;
- offset = blength(ln) - 1;
-
- } else if (!(container->tag == paragraph && !all_matched) &&
- (matched = scan_hrule(ln, first_nonspace))) {
-
- // it's only now that we know the line is not part of a setext header:
- container = add_child(container, hrule, line_number, first_nonspace + 1);
- finalize(container, line_number);
- container = container->parent;
- offset = blength(ln) - 1;
-
- } else if ((matched = parse_list_marker(ln, first_nonspace, &data))) {
-
- // compute padding:
- offset = first_nonspace + matched;
- i = 0;
- while (i <= 5 && bchar(ln, offset + i) == ' ') {
- i++;
- }
- // i = number of spaces after marker, up to 5
- if (i >= 5 || i < 1 || bchar(ln, offset) == '\n') {
- data->padding = matched + 1;
- if (i > 0) {
- offset += 1;
- }
- } else {
- data->padding = matched + i;
- offset += i;
- }
-
- // check container; if it's a list, see if this list item
- // can continue the list; otherwise, create a list container.
-
- data->marker_offset = indent;
-
- if (container->tag != list ||
- !lists_match(container->attributes.list_data, *data)) {
- container = add_child(container, list, line_number,
- first_nonspace + 1);
- container->attributes.list_data = *data;
- }
-
- // add the list item
- container = add_child(container, list_item, line_number,
- first_nonspace + 1);
- container->attributes.list_data = *data;
- free(data);
-
- } else {
- break;
- }
-
- if (accepts_lines(container->tag)) {
- // if it's a line container, it can't contain other containers
- break;
- }
- }
-
- // what remains at offset is a text line. add the text to the
- // appropriate container.
-
- first_nonspace = offset;
- while (bchar(ln, first_nonspace) == ' ') {
- first_nonspace++;
- }
-
- indent = first_nonspace - offset;
- blank = bchar(ln, first_nonspace) == '\n';
-
- // block quote lines are never blank as they start with >
- // and we don't count blanks in fenced code for purposes of tight/loose
- // lists or breaking out of lists. we also don't set last_line_blank
- // on an empty list item.
- container->last_line_blank = (blank &&
- container->tag != block_quote &&
- container->tag != fenced_code &&
- !(container->tag == list_item &&
- container->children == NULL &&
- container->start_line == line_number));
-
- block *cont = container;
- while (cont->parent) {
- cont->parent->last_line_blank = false;
- cont = cont->parent;
- }
-
- if (cur != last_matched_container &&
- container == last_matched_container &&
- !blank &&
- cur->tag == paragraph &&
- blength(cur->string_content) > 0) {
-
- check(add_line(cur, ln, offset) == 0, "could not add line");
-
- } else { // not a lazy continuation
-
- // finalize any blocks that were not matched and set cur to container:
- while (cur != last_matched_container) {
-
- finalize(cur, line_number);
- cur = cur->parent;
- check(cur != NULL, "cur is NULL, last_matched_container->tag = %d",
- last_matched_container->tag);
-
- }
-
- if (container->tag == indented_code) {
-
- check(add_line(container, ln, offset) == 0, "could not add line");
-
- } else if (container->tag == fenced_code) {
-
- matched = (indent <= 3
- && bchar(ln, first_nonspace) == container->attributes.fenced_code_data.fence_char)
- && scan_close_code_fence(ln, first_nonspace,
- container->attributes.fenced_code_data.fence_length);
- if (matched) {
- // if closing fence, don't add line to container; instead, close it:
- finalize(container, line_number);
- container = container->parent; // back up to parent
- } else {
- check(add_line(container, ln, offset) == 0, "could not add line");
- }
-
- } else if (container->tag == html_block) {
-
- check(add_line(container, ln, offset) == 0, "could not add line");
-
- } else if (blank) {
-
- // ??? do nothing
-
- } else if (container->tag == atx_header) {
-
- // chop off trailing ###s...use a scanner?
- brtrimws(ln);
- int p = blength(ln) - 1;
- int numhashes = 0;
- // if string ends in #s, remove these:
- while (bchar(ln, p) == '#') {
- p--;
- numhashes++;
- }
- if (bchar(ln, p) == '\\') {
- // the last # was escaped, so we include it.
- p++;
- numhashes--;
- }
- check(bdelete(ln, p + 1, numhashes) != BSTR_ERR,
- "could not delete final hashes");
- check(add_line(container, ln, first_nonspace) == 0, "could not add line");
- finalize(container, line_number);
- container = container->parent;
-
- } else if (accepts_lines(container->tag)) {
-
- check(add_line(container, ln, first_nonspace) == 0, "could not add line");
+ block* last_matched_container;
+ int offset = 0;
+ int matched = 0;
+ int lev = 0;
+ int i;
+ struct ListData * data = NULL;
+ bool all_matched = true;
+ block* container;
+ block* cur = *curptr;
+ bool blank = false;
+ int first_nonspace;
+ int indent;
+
+ // container starts at the document root.
+ container = cur->top;
+
+ // for each containing block, try to parse the associated line start.
+ // bail out on failure: container will point to the last matching block.
+
+ while (container->last_child && container->last_child->open) {
+ container = container->last_child;
+
+ first_nonspace = offset;
+ while (gh_buf_at(ln, first_nonspace) == ' ') {
+ first_nonspace++;
+ }
+
+ indent = first_nonspace - offset;
+ blank = gh_buf_at(ln, first_nonspace) == '\n';
+
+ if (container->tag == block_quote) {
+
+ matched = indent <= 3 && gh_buf_at(ln, first_nonspace) == '>';
+ if (matched) {
+ offset = first_nonspace + 1;
+ if (gh_buf_at(ln, offset) == ' ') {
+ offset++;
+ }
+ } else {
+ all_matched = false;
+ }
+
+ } else if (container->tag == list_item) {
+
+ if (indent >= container->attributes.list_data.marker_offset +
+ container->attributes.list_data.padding) {
+ offset += container->attributes.list_data.marker_offset +
+ container->attributes.list_data.padding;
+ } else if (blank) {
+ offset = first_nonspace;
+ } else {
+ all_matched = false;
+ }
+
+ } else if (container->tag == indented_code) {
+
+ if (indent >= CODE_INDENT) {
+ offset += CODE_INDENT;
+ } else if (blank) {
+ offset = first_nonspace;
+ } else {
+ all_matched = false;
+ }
+
+ } else if (container->tag == atx_header ||
+ container->tag == setext_header) {
+
+ // a header can never contain more than one line
+ all_matched = false;
+
+ } else if (container->tag == fenced_code) {
+
+ // skip optional spaces of fence offset
+ i = container->attributes.fenced_code_data.fence_offset;
+ while (i > 0 && gh_buf_at(ln, offset) == ' ') {
+ offset++;
+ i--;
+ }
+
+ } else if (container->tag == html_block) {
+
+ if (blank) {
+ all_matched = false;
+ }
+
+ } else if (container->tag == paragraph) {
+
+ if (blank) {
+ container->last_line_blank = true;
+ all_matched = false;
+ }
+
+ }
+
+ if (!all_matched) {
+ container = container->parent; // back up to last matching block
+ break;
+ }
+ }
+
+ last_matched_container = container;
+
+ // check to see if we've hit 2nd blank line, break out of list:
+ if (blank && container->last_line_blank) {
+ break_out_of_lists(&container, line_number);
+ }
+
+ // unless last matched container is code block, try new container starts:
+ while (container->tag != fenced_code && container->tag != indented_code &&
+ container->tag != html_block) {
+
+ first_nonspace = offset;
+ while (gh_buf_at(ln, first_nonspace) == ' ') {
+ first_nonspace++;
+ }
+
+ indent = first_nonspace - offset;
+ blank = gh_buf_at(ln, first_nonspace) == '\n';
+
+ if (indent >= CODE_INDENT) {
+
+ if (cur->tag != paragraph && !blank) {
+ offset += CODE_INDENT;
+ container = add_child(container, indented_code, line_number, offset + 1);
+ } else { // indent > 4 in lazy line
+ break;
+ }
+
+ } else if (gh_buf_at(ln, first_nonspace) == '>') {
+
+ offset = first_nonspace + 1;
+ // optional following character
+ if (gh_buf_at(ln, offset) == ' ') {
+ offset++;
+ }
+ container = add_child(container, block_quote, line_number, offset + 1);
+
+ } else if ((matched = scan_atx_header_start(ln, first_nonspace))) {
+
+ offset = first_nonspace + matched;
+ container = add_child(container, atx_header, line_number, offset + 1);
+
+ int hashpos = gh_buf_strchr(ln, '#', first_nonspace);
+ assert(hashpos >= 0);
+
+ int level = 0;
+ while (gh_buf_at(ln, hashpos) == '#') {
+ level++;
+ hashpos++;
+ }
+ container->attributes.header_level = level;
+
+ } else if ((matched = scan_open_code_fence(ln, first_nonspace))) {
+
+ container = add_child(container, fenced_code, line_number,
+ first_nonspace + 1);
+ container->attributes.fenced_code_data.fence_char = gh_buf_at(ln,
+ first_nonspace);
+ container->attributes.fenced_code_data.fence_length = matched;
+ container->attributes.fenced_code_data.fence_offset =
+ first_nonspace - offset;
+ offset = first_nonspace + matched;
+
+ } else if ((matched = scan_html_block_tag(ln, first_nonspace))) {
+
+ container = add_child(container, html_block, line_number,
+ first_nonspace + 1);
+ // note, we don't adjust offset because the tag is part of the text
+
+ } else if (container->tag == paragraph &&
+ (lev = scan_setext_header_line(ln, first_nonspace)) &&
+ // check that there is only one line in the paragraph:
+ gh_buf_strrchr(&container->string_content, '\n',
+ gh_buf_len(&container->string_content) - 2) < 0) {
+
+ container->tag = setext_header;
+ container->attributes.header_level = lev;
+ offset = gh_buf_len(ln) - 1;
+
+ } else if (!(container->tag == paragraph && !all_matched) &&
+ (matched = scan_hrule(ln, first_nonspace))) {
+
+ // it's only now that we know the line is not part of a setext header:
+ container = add_child(container, hrule, line_number, first_nonspace + 1);
+ finalize(container, line_number);
+ container = container->parent;
+ offset = gh_buf_len(ln) - 1;
+
+ } else if ((matched = parse_list_marker(ln, first_nonspace, &data))) {
+
+ // compute padding:
+ offset = first_nonspace + matched;
+ i = 0;
+ while (i <= 5 && gh_buf_at(ln, offset + i) == ' ') {
+ i++;
+ }
+ // i = number of spaces after marker, up to 5
+ if (i >= 5 || i < 1 || gh_buf_at(ln, offset) == '\n') {
+ data->padding = matched + 1;
+ if (i > 0) {
+ offset += 1;
+ }
+ } else {
+ data->padding = matched + i;
+ offset += i;
+ }
+
+ // check container; if it's a list, see if this list item
+ // can continue the list; otherwise, create a list container.
+
+ data->marker_offset = indent;
+
+ if (container->tag != list ||
+ !lists_match(container->attributes.list_data, *data)) {
+ container = add_child(container, list, line_number,
+ first_nonspace + 1);
+ container->attributes.list_data = *data;
+ }
+
+ // add the list item
+ container = add_child(container, list_item, line_number,
+ first_nonspace + 1);
+ container->attributes.list_data = *data;
+ free(data);
+
+ } else {
+ break;
+ }
+
+ if (accepts_lines(container->tag)) {
+ // if it's a line container, it can't contain other containers
+ break;
+ }
+ }
+
+ // what remains at offset is a text line. add the text to the
+ // appropriate container.
+
+ first_nonspace = offset;
+ while (gh_buf_at(ln, first_nonspace) == ' ') {
+ first_nonspace++;
+ }
+
+ indent = first_nonspace - offset;
+ blank = gh_buf_at(ln, first_nonspace) == '\n';
+
+ // block quote lines are never blank as they start with >
+ // and we don't count blanks in fenced code for purposes of tight/loose
+ // lists or breaking out of lists. we also don't set last_line_blank
+ // on an empty list item.
+ container->last_line_blank = (blank &&
+ container->tag != block_quote &&
+ container->tag != fenced_code &&
+ !(container->tag == list_item &&
+ container->children == NULL &&
+ container->start_line == line_number));
+
+ block *cont = container;
+ while (cont->parent) {
+ cont->parent->last_line_blank = false;
+ cont = cont->parent;
+ }
+
+ if (cur != last_matched_container &&
+ container == last_matched_container &&
+ !blank &&
+ cur->tag == paragraph &&
+ gh_buf_len(&cur->string_content) > 0) {
+
+ add_line(cur, ln, offset);
+
+ } else { // not a lazy continuation
+
+ // finalize any blocks that were not matched and set cur to container:
+ while (cur != last_matched_container) {
+
+ finalize(cur, line_number);
+ cur = cur->parent;
+ assert(cur != NULL);
+ }
+
+ if (container->tag == indented_code) {
+
+ add_line(container, ln, offset);
+
+ } else if (container->tag == fenced_code) {
+
+ matched = (indent <= 3
+ && gh_buf_at(ln, first_nonspace) == container->attributes.fenced_code_data.fence_char)
+ && scan_close_code_fence(ln, first_nonspace,
+ container->attributes.fenced_code_data.fence_length);
+ if (matched) {
+ // if closing fence, don't add line to container; instead, close it:
+ finalize(container, line_number);
+ container = container->parent; // back up to parent
+ } else {
+ add_line(container, ln, offset);
+ }
+
+ } else if (container->tag == html_block) {
+
+ add_line(container, ln, offset);
+
+ } else if (blank) {
+
+ // ??? do nothing
+
+ } else if (container->tag == atx_header) {
+ // chop off trailing ###s...use a scanner?
+ gh_buf_trim(ln);
+ int p = gh_buf_len(ln) - 1;
+
+ // if string ends in #s, remove these:
+ while (gh_buf_at(ln, p) == '#') {
+ p--;
+ }
+ if (gh_buf_at(ln, p) == '\\') {
+ // the last # was escaped, so we include it.
+ p++;
+ }
+
+ gh_buf_truncate(ln, p + 1);
+ add_line(container, ln, first_nonspace);
+ finalize(container, line_number);
+ container = container->parent;
+
+ } else if (accepts_lines(container->tag)) {
+
+ add_line(container, ln, first_nonspace);
+
+ } else if (container->tag != hrule && container->tag != setext_header) {
+
+ // create paragraph container for line
+ container = add_child(container, paragraph, line_number, first_nonspace + 1);
+ add_line(container, ln, first_nonspace);
- } else if (container->tag != hrule && container->tag != setext_header) {
-
- // create paragraph container for line
- container = add_child(container, paragraph, line_number, first_nonspace + 1);
- check(add_line(container, ln, first_nonspace) == 0, "could not add line");
-
- } else {
+ } else {
+ assert(false);
+ }
- log_warn("Line %d with container type %d did not match any condition:\n\"%s\"",
- line_number, container->tag, ln->data);
-
- }
- *curptr = container;
- }
-
- return 0;
- error:
- return -1;
+ *curptr = container;
+ }
}
diff --git a/src/bstrlib.c b/src/bstrlib.c
deleted file mode 100644
index 1b19dbe..0000000
--- a/src/bstrlib.c
+++ /dev/null
@@ -1,2979 +0,0 @@
-/*
- * This source file is part of the bstring string library. This code was
- * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
- * BSD open source license or GPL v2.0. Refer to the accompanying documentation
- * for details on usage and license.
- */
-
-/*
- * bstrlib.c
- *
- * This file is the core module for implementing the bstring functions.
- */
-
-#if defined (_MSC_VER)
-/* These warnings from MSVC++ are totally pointless. */
-# define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "bstrlib.h"
-
-/* Optionally include a mechanism for debugging memory */
-
-#if defined(MEMORY_DEBUG) || defined(BSTRLIB_MEMORY_DEBUG)
-#include "memdbg.h"
-#endif
-
-#ifndef bstr__alloc
-#define bstr__alloc(x) malloc (x)
-#endif
-
-#ifndef bstr__free
-#define bstr__free(p) free (p)
-#endif
-
-#ifndef bstr__realloc
-#define bstr__realloc(p,x) realloc ((p), (x))
-#endif
-
-#ifndef bstr__memcpy
-#define bstr__memcpy(d,s,l) memcpy ((d), (s), (l))
-#endif
-
-#ifndef bstr__memmove
-#define bstr__memmove(d,s,l) memmove ((d), (s), (l))
-#endif
-
-#ifndef bstr__memset
-#define bstr__memset(d,c,l) memset ((d), (c), (l))
-#endif
-
-#ifndef bstr__memcmp
-#define bstr__memcmp(d,c,l) memcmp ((d), (c), (l))
-#endif
-
-#ifndef bstr__memchr
-#define bstr__memchr(s,c,l) memchr ((s), (c), (l))
-#endif
-
-/* Just a length safe wrapper for memmove. */
-
-#define bBlockCopy(D,S,L) { if ((L) > 0) bstr__memmove ((D),(S),(L)); }
-
-/* Compute the snapped size for a given requested size. By snapping to powers
- of 2 like this, repeated reallocations are avoided. */
-static int snapUpSize (int i) {
- if (i < 8) {
- i = 8;
- } else {
- unsigned int j;
- j = (unsigned int) i;
-
- j |= (j >> 1);
- j |= (j >> 2);
- j |= (j >> 4);
- j |= (j >> 8); /* Ok, since int >= 16 bits */
-#if (UINT_MAX != 0xffff)
- j |= (j >> 16); /* For 32 bit int systems */
-#if (UINT_MAX > 0xffffffffUL)
- j |= (j >> 32); /* For 64 bit int systems */
-#endif
-#endif
- /* Least power of two greater than i */
- j++;
- if ((int) j >= i) i = (int) j;
- }
- return i;
-}
-
-/* int balloc (bstring b, int len)
- *
- * Increase the size of the memory backing the bstring b to at least len.
- */
-int balloc (bstring b, int olen) {
- int len;
- if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen <= 0 ||
- b->mlen < b->slen || olen <= 0) {
- return BSTR_ERR;
- }
-
- if (olen >= b->mlen) {
- unsigned char * x;
-
- if ((len = snapUpSize (olen)) <= b->mlen) return BSTR_OK;
-
- /* Assume probability of a non-moving realloc is 0.125 */
- if (7 * b->mlen < 8 * b->slen) {
-
- /* If slen is close to mlen in size then use realloc to reduce
- the memory defragmentation */
-
- reallocStrategy:;
-
- x = (unsigned char *) bstr__realloc (b->data, (size_t) len);
- if (x == NULL) {
-
- /* Since we failed, try allocating the tighest possible
- allocation */
-
- if (NULL == (x = (unsigned char *) bstr__realloc (b->data, (size_t) (len = olen)))) {
- return BSTR_ERR;
- }
- }
- } else {
-
- /* If slen is not close to mlen then avoid the penalty of copying
- the extra bytes that are allocated, but not considered part of
- the string */
-
- if (NULL == (x = (unsigned char *) bstr__alloc ((size_t) len))) {
-
- /* Perhaps there is no available memory for the two
- allocations to be in memory at once */
-
- goto reallocStrategy;
-
- } else {
- if (b->slen) bstr__memcpy ((char *) x, (char *) b->data, (size_t) b->slen);
- bstr__free (b->data);
- }
- }
- b->data = x;
- b->mlen = len;
- b->data[b->slen] = (unsigned char) '\0';
- }
-
- return BSTR_OK;
-}
-
-/* int ballocmin (bstring b, int len)
- *
- * Set the size of the memory backing the bstring b to len or b->slen+1,
- * whichever is larger. Note that repeated use of this function can degrade
- * performance.
- */
-int ballocmin (bstring b, int len) {
- unsigned char * s;
-
- if (b == NULL || b->data == NULL || (b->slen+1) < 0 || b->mlen <= 0 ||
- b->mlen < b->slen || len <= 0) {
- return BSTR_ERR;
- }
-
- if (len < b->slen + 1) len = b->slen + 1;
-
- if (len != b->mlen) {
- s = (unsigned char *) bstr__realloc (b->data, (size_t) len);
- if (NULL == s) return BSTR_ERR;
- s[b->slen] = (unsigned char) '\0';
- b->data = s;
- b->mlen = len;
- }
-
- return BSTR_OK;
-}
-
-/* bstring bfromcstr (const char * str)
- *
- * Create a bstring which contains the contents of the '\0' terminated char *
- * buffer str.
- */
-bstring bfromcstr (const char * str) {
-bstring b;
-int i;
-size_t j;
-
- if (str == NULL) return NULL;
- j = (strlen) (str);
- i = snapUpSize ((int) (j + (2 - (j != 0))));
- if (i <= (int) j) return NULL;
-
- b = (bstring) bstr__alloc (sizeof (struct tagbstring));
- if (NULL == b) return NULL;
- b->slen = (int) j;
- if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) {
- bstr__free (b);
- return NULL;
- }
-
- bstr__memcpy (b->data, str, j+1);
- return b;
-}
-
-/* bstring bfromcstralloc (int mlen, const char * str)
- *
- * Create a bstring which contains the contents of the '\0' terminated char *
- * buffer str. The memory buffer backing the string is at least len
- * characters in length.
- */
-bstring bfromcstralloc (int mlen, const char * str) {
-bstring b;
-int i;
-size_t j;
-
- if (str == NULL) return NULL;
- j = (strlen) (str);
- i = snapUpSize ((int) (j + (2 - (j != 0))));
- if (i <= (int) j) return NULL;
-
- b = (bstring) bstr__alloc (sizeof (struct tagbstring));
- if (b == NULL) return NULL;
- b->slen = (int) j;
- if (i < mlen) i = mlen;
-
- if (NULL == (b->data = (unsigned char *) bstr__alloc (b->mlen = i))) {
- bstr__free (b);
- return NULL;
- }
-
- bstr__memcpy (b->data, str, j+1);
- return b;
-}
-
-/* bstring blk2bstr (const void * blk, int len)
- *
- * Create a bstring which contains the content of the block blk of length
- * len.
- */
-bstring blk2bstr (const void * blk, int len) {
-bstring b;
-int i;
-
- if (blk == NULL || len < 0) return NULL;
- b = (bstring) bstr__alloc (sizeof (struct tagbstring));
- if (b == NULL) return NULL;
- b->slen = len;
-
- i = len + (2 - (len != 0));
- i = snapUpSize (i);
-
- b->mlen = i;
-
- b->data = (unsigned char *) bstr__alloc ((size_t) b->mlen);
- if (b->data == NULL) {
- bstr__free (b);
- return NULL;
- }
-
- if (len > 0) bstr__memcpy (b->data, blk, (size_t) len);
- b->data[len] = (unsigned char) '\0';
-
- return b;
-}
-
-/* char * bstr2cstr (const_bstring s, char z)
- *
- * Create a '\0' terminated char * buffer which is equal to the contents of
- * the bstring s, except that any contained '\0' characters are converted
- * to the character in z. This returned value should be freed with a
- * bcstrfree () call, by the calling application.
- */
-char * bstr2cstr (const_bstring b, char z) {
-int i, l;
-char * r;
-
- if (b == NULL || b->slen < 0 || b->data == NULL) return NULL;
- l = b->slen;
- r = (char *) bstr__alloc ((size_t) (l + 1));
- if (r == NULL) return r;
-
- for (i=0; i < l; i ++) {
- r[i] = (char) ((b->data[i] == '\0') ? z : (char) (b->data[i]));
- }
-
- r[l] = (unsigned char) '\0';
-
- return r;
-}
-
-/* int bcstrfree (char * s)
- *
- * Frees a C-string generated by bstr2cstr (). This is normally unnecessary
- * since it just wraps a call to bstr__free (), however, if bstr__alloc ()
- * and bstr__free () have been redefined as a macros within the bstrlib
- * module (via defining them in memdbg.h after defining
- * BSTRLIB_MEMORY_DEBUG) with some difference in behaviour from the std
- * library functions, then this allows a correct way of freeing the memory
- * that allows higher level code to be independent from these macro
- * redefinitions.
- */
-int bcstrfree (char * s) {
- if (s) {
- bstr__free (s);
- return BSTR_OK;
- }
- return BSTR_ERR;
-}
-
-/* int bconcat (bstring b0, const_bstring b1)
- *
- * Concatenate the bstring b1 to the bstring b0.
- */
-int bconcat (bstring b0, const_bstring b1) {
-int len, d;
-bstring aux = (bstring) b1;
-
- if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL) return BSTR_ERR;
-
- d = b0->slen;
- len = b1->slen;
- if ((d | (b0->mlen - d) | len | (d + len)) < 0) return BSTR_ERR;
-
- if (b0->mlen <= d + len + 1) {
- ptrdiff_t pd = b1->data - b0->data;
- if (0 <= pd && pd < b0->mlen) {
- if (NULL == (aux = bstrcpy (b1))) return BSTR_ERR;
- }
- if (balloc (b0, d + len + 1) != BSTR_OK) {
- if (aux != b1) bdestroy (aux);
- return BSTR_ERR;
- }
- }
-
- bBlockCopy (&b0->data[d], &aux->data[0], (size_t) len);
- b0->data[d + len] = (unsigned char) '\0';
- b0->slen = d + len;
- if (aux != b1) bdestroy (aux);
- return BSTR_OK;
-}
-
-/* int bconchar (bstring b, char c)
-/ *
- * Concatenate the single character c to the bstring b.
- */
-int bconchar (bstring b, char c) {
-int d;
-
- if (b == NULL) return BSTR_ERR;
- d = b->slen;
- if ((d | (b->mlen - d)) < 0 || balloc (b, d + 2) != BSTR_OK) return BSTR_ERR;
- b->data[d] = (unsigned char) c;
- b->data[d + 1] = (unsigned char) '\0';
- b->slen++;
- return BSTR_OK;
-}
-
-/* int bcatcstr (bstring b, const char * s)
- *
- * Concatenate a char * string to a bstring.
- */
-int bcatcstr (bstring b, const char * s) {
-char * d;
-int i, l;
-
- if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen
- || b->mlen <= 0 || s == NULL) return BSTR_ERR;
-
- /* Optimistically concatenate directly */
- l = b->mlen - b->slen;
- d = (char *) &b->data[b->slen];
- for (i=0; i < l; i++) {
- if ((*d++ = *s++) == '\0') {
- b->slen += i;
- return BSTR_OK;
- }
- }
- b->slen += i;
-
- /* Need to explicitely resize and concatenate tail */
- return bcatblk (b, (const void *) s, (int) strlen (s));
-}
-
-/* int bcatblk (bstring b, const void * s, int len)
- *
- * Concatenate a fixed length buffer to a bstring.
- */
-int bcatblk (bstring b, const void * s, int len) {
-int nl;
-
- if (b == NULL || b->data == NULL || b->slen < 0 || b->mlen < b->slen
- || b->mlen <= 0 || s == NULL || len < 0) return BSTR_ERR;
-
- if (0 > (nl = b->slen + len)) return BSTR_ERR; /* Overflow? */
- if (b->mlen <= nl && 0 > balloc (b, nl + 1)) return BSTR_ERR;
-
- bBlockCopy (&b->data[b->slen], s, (size_t) len);
- b->slen = nl;
- b->data[nl] = (unsigned char) '\0';
- return BSTR_OK;
-}
-
-/* bstring bstrcpy (const_bstring b)
- *
- * Create a copy of the bstring b.
- */
-bstring bstrcpy (const_bstring b) {
-bstring b0;
-int i,j;
-
- /* Attempted to copy an invalid string? */
- if (b == NULL || b->slen < 0 || b->data == NULL) return NULL;
-
- b0 = (bstring) bstr__alloc (sizeof (struct tagbstring));
- if (b0 == NULL) {
- /* Unable to allocate memory for string header */
- return NULL;
- }
-
- i = b->slen;
- j = snapUpSize (i + 1);
-
- b0->data = (unsigned char *) bstr__alloc (j);
- if (b0->data == NULL) {
- j = i + 1;
- b0->data = (unsigned char *) bstr__alloc (j);
- if (b0->data == NULL) {
- /* Unable to allocate memory for string data */
- bstr__free (b0);
- return NULL;
- }
- }
-
- b0->mlen = j;
- b0->slen = i;
-
- if (i) bstr__memcpy ((char *) b0->data, (char *) b->data, i);
- b0->data[b0->slen] = (unsigned char) '\0';
-
- return b0;
-}
-
-/* int bassign (bstring a, const_bstring b)
- *
- * Overwrite the string a with the contents of string b.
- */
-int bassign (bstring a, const_bstring b) {
- if (b == NULL || b->data == NULL || b->slen < 0)
- return BSTR_ERR;
- if (b->slen != 0) {
- if (balloc (a, b->slen) != BSTR_OK) return BSTR_ERR;
- bstr__memmove (a->data, b->data, b->slen);
- } else {
- if (a == NULL || a->data == NULL || a->mlen < a->slen ||
- a->slen < 0 || a->mlen == 0)
- return BSTR_ERR;
- }
- a->data[b->slen] = (unsigned char) '\0';
- a->slen = b->slen;
- return BSTR_OK;
-}
-
-/* int bassignmidstr (bstring a, const_bstring b, int left, int len)
- *
- * Overwrite the string a with the middle of contents of string b
- * starting from position left and running for a length len. left and
- * len are clamped to the ends of b as with the function bmidstr.
- */
-int bassignmidstr (bstring a, const_bstring b, int left, int len) {
- if (b == NULL || b->data == NULL || b->slen < 0)
- return BSTR_ERR;
-
- if (left < 0) {
- len += left;
- left = 0;
- }
-
- if (len > b->slen - left) len = b->slen - left;
-
- if (a == NULL || a->data == NULL || a->mlen < a->slen ||
- a->slen < 0 || a->mlen == 0)
- return BSTR_ERR;
-
- if (len > 0) {
- if (balloc (a, len) != BSTR_OK) return BSTR_ERR;
- bstr__memmove (a->data, b->data + left, len);
- a->slen = len;
- } else {
- a->slen = 0;
- }
- a->data[a->slen] = (unsigned char) '\0';
- return BSTR_OK;
-}
-
-/* int bassigncstr (bstring a, const char * str)
- *
- * Overwrite the string a with the contents of char * string str. Note that
- * the bstring a must be a well defined and writable bstring. If an error
- * occurs BSTR_ERR is returned however a may be partially overwritten.
- */
-int bassigncstr (bstring a, const char * str) {
-int i;
-size_t len;
- if (a == NULL || a->data == NULL || a->mlen < a->slen ||
- a->slen < 0 || a->mlen == 0 || NULL == str)
- return BSTR_ERR;
-
- for (i=0; i < a->mlen; i++) {
- if ('\0' == (a->data[i] = str[i])) {
- a->slen = i;
- return BSTR_OK;
- }
- }
-
- a->slen = i;
- len = strlen (str + i);
- if (len > INT_MAX || i + len + 1 > INT_MAX ||
- 0 > balloc (a, (int) (i + len + 1))) return BSTR_ERR;
- bBlockCopy (a->data + i, str + i, (size_t) len + 1);
- a->slen += (int) len;
- return BSTR_OK;
-}
-
-/* int bassignblk (bstring a, const void * s, int len)
- *
- * Overwrite the string a with the contents of the block (s, len). Note that
- * the bstring a must be a well defined and writable bstring. If an error
- * occurs BSTR_ERR is returned and a is not overwritten.
- */
-int bassignblk (bstring a, const void * s, int len) {
- if (a == NULL || a->data == NULL || a->mlen < a->slen ||
- a->slen < 0 || a->mlen == 0 || NULL == s || len + 1 < 1)
- return BSTR_ERR;
- if (len + 1 > a->mlen && 0 > balloc (a, len + 1)) return BSTR_ERR;
- bBlockCopy (a->data, s, (size_t) len);
- a->data[len] = (unsigned char) '\0';
- a->slen = len;
- return BSTR_OK;
-}
-
-/* int btrunc (bstring b, int n)
- *
- * Truncate the bstring to at most n characters.
- */
-int btrunc (bstring b, int n) {
- if (n < 0 || b == NULL || b->data == NULL || b->mlen < b->slen ||
- b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
- if (b->slen > n) {
- b->slen = n;
- b->data[n] = (unsigned char) '\0';
- }
- return BSTR_OK;
-}
-
-#define upcase(c) (toupper ((unsigned char) c))
-#define downcase(c) (tolower ((unsigned char) c))
-#define wspace(c) (isspace ((unsigned char) c))
-
-/* int btoupper (bstring b)
- *
- * Convert contents of bstring to upper case.
- */
-int btoupper (bstring b) {
-int i, len;
- if (b == NULL || b->data == NULL || b->mlen < b->slen ||
- b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
- for (i=0, len = b->slen; i < len; i++) {
- b->data[i] = (unsigned char) upcase (b->data[i]);
- }
- return BSTR_OK;
-}
-
-/* int btolower (bstring b)
- *
- * Convert contents of bstring to lower case.
- */
-int btolower (bstring b) {
-int i, len;
- if (b == NULL || b->data == NULL || b->mlen < b->slen ||
- b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
- for (i=0, len = b->slen; i < len; i++) {
- b->data[i] = (unsigned char) downcase (b->data[i]);
- }
- return BSTR_OK;
-}
-
-/* int bstricmp (const_bstring b0, const_bstring b1)
- *
- * Compare two strings without differentiating between case. The return
- * value is the difference of the values of the characters where the two
- * strings first differ after lower case transformation, otherwise 0 is
- * returned indicating that the strings are equal. If the lengths are
- * different, then a difference from 0 is given, but if the first extra
- * character is '\0', then it is taken to be the value UCHAR_MAX+1.
- */
-int bstricmp (const_bstring b0, const_bstring b1) {
-int i, v, n;
-
- if (bdata (b0) == NULL || b0->slen < 0 ||
- bdata (b1) == NULL || b1->slen < 0) return SHRT_MIN;
- if ((n = b0->slen) > b1->slen) n = b1->slen;
- else if (b0->slen == b1->slen && b0->data == b1->data) return BSTR_OK;
-
- for (i = 0; i < n; i ++) {
- v = (char) downcase (b0->data[i])
- - (char) downcase (b1->data[i]);
- if (0 != v) return v;
- }
-
- if (b0->slen > n) {
- v = (char) downcase (b0->data[n]);
- if (v) return v;
- return UCHAR_MAX + 1;
- }
- if (b1->slen > n) {
- v = - (char) downcase (b1->data[n]);
- if (v) return v;
- return - (int) (UCHAR_MAX + 1);
- }
- return BSTR_OK;
-}
-
-/* int bstrnicmp (const_bstring b0, const_bstring b1, int n)
- *
- * Compare two strings without differentiating between case for at most n
- * characters. If the position where the two strings first differ is
- * before the nth position, the return value is the difference of the values
- * of the characters, otherwise 0 is returned. If the lengths are different
- * and less than n characters, then a difference from 0 is given, but if the
- * first extra character is '\0', then it is taken to be the value
- * UCHAR_MAX+1.
- */
-int bstrnicmp (const_bstring b0, const_bstring b1, int n) {
-int i, v, m;
-
- if (bdata (b0) == NULL || b0->slen < 0 ||
- bdata (b1) == NULL || b1->slen < 0 || n < 0) return SHRT_MIN;
- m = n;
- if (m > b0->slen) m = b0->slen;
- if (m > b1->slen) m = b1->slen;
-
- if (b0->data != b1->data) {
- for (i = 0; i < m; i ++) {
- v = (char) downcase (b0->data[i]);
- v -= (char) downcase (b1->data[i]);
- if (v != 0) return b0->data[i] - b1->data[i];
- }
- }
-
- if (n == m || b0->slen == b1->slen) return BSTR_OK;
-
- if (b0->slen > m) {
- v = (char) downcase (b0->data[m]);
- if (v) return v;
- return UCHAR_MAX + 1;
- }
-
- v = - (char) downcase (b1->data[m]);
- if (v) return v;
- return - (int) (UCHAR_MAX + 1);
-}
-
-/* int biseqcaseless (const_bstring b0, const_bstring b1)
- *
- * Compare two strings for equality without differentiating between case.
- * If the strings differ other than in case, 0 is returned, if the strings
- * are the same, 1 is returned, if there is an error, -1 is returned. If
- * the length of the strings are different, this function is O(1). '\0'
- * termination characters are not treated in any special way.
- */
-int biseqcaseless (const_bstring b0, const_bstring b1) {
-int i, n;
-
- if (bdata (b0) == NULL || b0->slen < 0 ||
- bdata (b1) == NULL || b1->slen < 0) return BSTR_ERR;
- if (b0->slen != b1->slen) return BSTR_OK;
- if (b0->data == b1->data || b0->slen == 0) return 1;
- for (i=0, n=b0->slen; i < n; i++) {
- if (b0->data[i] != b1->data[i]) {
- unsigned char c = (unsigned char) downcase (b0->data[i]);
- if (c != (unsigned char) downcase (b1->data[i])) return 0;
- }
- }
- return 1;
-}
-
-/* int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len)
- *
- * Compare beginning of string b0 with a block of memory of length len
- * without differentiating between case for equality. If the beginning of b0
- * differs from the memory block other than in case (or if b0 is too short),
- * 0 is returned, if the strings are the same, 1 is returned, if there is an
- * error, -1 is returned. '\0' characters are not treated in any special
- * way.
- */
-int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len) {
-int i;
-
- if (bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0)
- return BSTR_ERR;
- if (b0->slen < len) return BSTR_OK;
- if (b0->data == (const unsigned char *) blk || len == 0) return 1;
-
- for (i = 0; i < len; i ++) {
- if (b0->data[i] != ((const unsigned char *) blk)[i]) {
- if (downcase (b0->data[i]) !=
- downcase (((const unsigned char *) blk)[i])) return 0;
- }
- }
- return 1;
-}
-
-/*
- * int bltrimws (bstring b)
- *
- * Delete whitespace contiguous from the left end of the string.
- */
-int bltrimws (bstring b) {
-int i, len;
-
- if (b == NULL || b->data == NULL || b->mlen < b->slen ||
- b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
-
- for (len = b->slen, i = 0; i < len; i++) {
- if (!wspace (b->data[i])) {
- return bdelete (b, 0, i);
- }
- }
-
- b->data[0] = (unsigned char) '\0';
- b->slen = 0;
- return BSTR_OK;
-}
-
-/*
- * int brtrimws (bstring b)
- *
- * Delete whitespace contiguous from the right end of the string.
- */
-int brtrimws (bstring b) {
-int i;
-
- if (b == NULL || b->data == NULL || b->mlen < b->slen ||
- b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
-
- for (i = b->slen - 1; i >= 0; i--) {
- if (!wspace (b->data[i])) {
- if (b->mlen > i) b->data[i+1] = (unsigned char) '\0';
- b->slen = i + 1;
- return BSTR_OK;
- }
- }
-
- b->data[0] = (unsigned char) '\0';
- b->slen = 0;
- return BSTR_OK;
-}
-
-/*
- * int btrimws (bstring b)
- *
- * Delete whitespace contiguous from both ends of the string.
- */
-int btrimws (bstring b) {
-int i, j;
-
- if (b == NULL || b->data == NULL || b->mlen < b->slen ||
- b->slen < 0 || b->mlen <= 0) return BSTR_ERR;
-
- for (i = b->slen - 1; i >= 0; i--) {
- if (!wspace (b->data[i])) {
- if (b->mlen > i) b->data[i+1] = (unsigned char) '\0';
- b->slen = i + 1;
- for (j = 0; wspace (b->data[j]); j++) {}
- return bdelete (b, 0, j);
- }
- }
-
- b->data[0] = (unsigned char) '\0';
- b->slen = 0;
- return BSTR_OK;
-}
-
-/* int biseq (const_bstring b0, const_bstring b1)
- *
- * Compare the string b0 and b1. If the strings differ, 0 is returned, if
- * the strings are the same, 1 is returned, if there is an error, -1 is
- * returned. If the length of the strings are different, this function is
- * O(1). '\0' termination characters are not treated in any special way.
- */
-int biseq (const_bstring b0, const_bstring b1) {
- if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL ||
- b0->slen < 0 || b1->slen < 0) return BSTR_ERR;
- if (b0->slen != b1->slen) return BSTR_OK;
- if (b0->data == b1->data || b0->slen == 0) return 1;
- return !bstr__memcmp (b0->data, b1->data, b0->slen);
-}
-
-/* int bisstemeqblk (const_bstring b0, const void * blk, int len)
- *
- * Compare beginning of string b0 with a block of memory of length len for
- * equality. If the beginning of b0 differs from the memory block (or if b0
- * is too short), 0 is returned, if the strings are the same, 1 is returned,
- * if there is an error, -1 is returned. '\0' characters are not treated in
- * any special way.
- */
-int bisstemeqblk (const_bstring b0, const void * blk, int len) {
-int i;
-
- if (bdata (b0) == NULL || b0->slen < 0 || NULL == blk || len < 0)
- return BSTR_ERR;
- if (b0->slen < len) return BSTR_OK;
- if (b0->data == (const unsigned char *) blk || len == 0) return 1;
-
- for (i = 0; i < len; i ++) {
- if (b0->data[i] != ((const unsigned char *) blk)[i]) return BSTR_OK;
- }
- return 1;
-}
-
-/* int biseqcstr (const_bstring b, const char *s)
- *
- * Compare the bstring b and char * string s. The C string s must be '\0'
- * terminated at exactly the length of the bstring b, and the contents
- * between the two must be identical with the bstring b with no '\0'
- * characters for the two contents to be considered equal. This is
- * equivalent to the condition that their current contents will be always be
- * equal when comparing them in the same format after converting one or the
- * other. If the strings are equal 1 is returned, if they are unequal 0 is
- * returned and if there is a detectable error BSTR_ERR is returned.
- */
-int biseqcstr (const_bstring b, const char * s) {
-int i;
- if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR;
- for (i=0; i < b->slen; i++) {
- if (s[i] == '\0' || b->data[i] != (unsigned char) s[i]) return BSTR_OK;
- }
- return s[i] == '\0';
-}
-
-/* int biseqcstrcaseless (const_bstring b, const char *s)
- *
- * Compare the bstring b and char * string s. The C string s must be '\0'
- * terminated at exactly the length of the bstring b, and the contents
- * between the two must be identical except for case with the bstring b with
- * no '\0' characters for the two contents to be considered equal. This is
- * equivalent to the condition that their current contents will be always be
- * equal ignoring case when comparing them in the same format after
- * converting one or the other. If the strings are equal, except for case,
- * 1 is returned, if they are unequal regardless of case 0 is returned and
- * if there is a detectable error BSTR_ERR is returned.
- */
-int biseqcstrcaseless (const_bstring b, const char * s) {
-int i;
- if (b == NULL || s == NULL || b->data == NULL || b->slen < 0) return BSTR_ERR;
- for (i=0; i < b->slen; i++) {
- if (s[i] == '\0' ||
- (b->data[i] != (unsigned char) s[i] &&
- downcase (b->data[i]) != (unsigned char) downcase (s[i])))
- return BSTR_OK;
- }
- return s[i] == '\0';
-}
-
-/* int bstrcmp (const_bstring b0, const_bstring b1)
- *
- * Compare the string b0 and b1. If there is an error, SHRT_MIN is returned,
- * otherwise a value less than or greater than zero, indicating that the
- * string pointed to by b0 is lexicographically less than or greater than
- * the string pointed to by b1 is returned. If the the string lengths are
- * unequal but the characters up until the length of the shorter are equal
- * then a value less than, or greater than zero, indicating that the string
- * pointed to by b0 is shorter or longer than the string pointed to by b1 is
- * returned. 0 is returned if and only if the two strings are the same. If
- * the length of the strings are different, this function is O(n). Like its
- * standard C library counter part strcmp, the comparison does not proceed
- * past any '\0' termination characters encountered.
- */
-int bstrcmp (const_bstring b0, const_bstring b1) {
-int i, v, n;
-
- if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL ||
- b0->slen < 0 || b1->slen < 0) return SHRT_MIN;
- n = b0->slen; if (n > b1->slen) n = b1->slen;
- if (b0->slen == b1->slen && (b0->data == b1->data || b0->slen == 0))
- return BSTR_OK;
-
- for (i = 0; i < n; i ++) {
- v = ((char) b0->data[i]) - ((char) b1->data[i]);
- if (v != 0) return v;
- if (b0->data[i] == (unsigned char) '\0') return BSTR_OK;
- }
-
- if (b0->slen > n) return 1;
- if (b1->slen > n) return -1;
- return BSTR_OK;
-}
-
-/* int bstrncmp (const_bstring b0, const_bstring b1, int n)
- *
- * Compare the string b0 and b1 for at most n characters. If there is an
- * error, SHRT_MIN is returned, otherwise a value is returned as if b0 and
- * b1 were first truncated to at most n characters then bstrcmp was called
- * with these new strings are paremeters. If the length of the strings are
- * different, this function is O(n). Like its standard C library counter
- * part strcmp, the comparison does not proceed past any '\0' termination
- * characters encountered.
- */
-int bstrncmp (const_bstring b0, const_bstring b1, int n) {
-int i, v, m;
-
- if (b0 == NULL || b1 == NULL || b0->data == NULL || b1->data == NULL ||
- b0->slen < 0 || b1->slen < 0) return SHRT_MIN;
- m = n;
- if (m > b0->slen) m = b0->slen;
- if (m > b1->slen) m = b1->slen;
-
- if (b0->data != b1->data) {
- for (i = 0; i < m; i ++) {
- v = ((char) b0->data[i]) - ((char) b1->data[i]);
- if (v != 0) return v;
- if (b0->data[i] == (unsigned char) '\0') return BSTR_OK;
- }
- }
-
- if (n == m || b0->slen == b1->slen) return BSTR_OK;
-
- if (b0->slen > m) return 1;
- return -1;
-}
-
-/* bstring bmidstr (const_bstring b, int left, int len)
- *
- * Create a bstring which is the substring of b starting from position left
- * and running for a length len (clamped by the end of the bstring b.) If
- * b is detectably invalid, then NULL is returned. The section described
- * by (left, len) is clamped to the boundaries of b.
- */
-bstring bmidstr (const_bstring b, int left, int len) {
-
- if (b == NULL || b->slen < 0 || b->data == NULL) return NULL;
-
- if (left < 0) {
- len += left;
- left = 0;
- }
-
- if (len > b->slen - left) len = b->slen - left;
-
- if (len <= 0) return bfromcstr ("");
- return blk2bstr (b->data + left, len);
-}
-
-/* int bdelete (bstring b, int pos, int len)
- *
- * Removes characters from pos to pos+len-1 inclusive and shifts the tail of
- * the bstring starting from pos+len to pos. len must be positive for this
- * call to have any effect. The section of the string described by (pos,
- * len) is clamped to boundaries of the bstring b.
- */
-int bdelete (bstring b, int pos, int len) {
- /* Clamp to left side of bstring */
- if (pos < 0) {
- len += pos;
- pos = 0;
- }
-
- if (len < 0 || b == NULL || b->data == NULL || b->slen < 0 ||
- b->mlen < b->slen || b->mlen <= 0)
- return BSTR_ERR;
- if (len > 0 && pos < b->slen) {
- if (pos + len >= b->slen) {
- b->slen = pos;
- } else {
- bBlockCopy ((char *) (b->data + pos),
- (char *) (b->data + pos + len),
- b->slen - (pos+len));
- b->slen -= len;
- }
- b->data[b->slen] = (unsigned char) '\0';
- }
- return BSTR_OK;
-}
-
-/* int bdestroy (bstring b)
- *
- * Free up the bstring. Note that if b is detectably invalid or not writable
- * then no action is performed and BSTR_ERR is returned. Like a freed memory
- * allocation, dereferences, writes or any other action on b after it has
- * been bdestroyed is undefined.
- */
-int bdestroy (bstring b) {
- if (b == NULL || b->slen < 0 || b->mlen <= 0 || b->mlen < b->slen ||
- b->data == NULL)
- return BSTR_ERR;
-
- bstr__free (b->data);
-
- /* In case there is any stale usage, there is one more chance to
- notice this error. */
-
- b->slen = -1;
- b->mlen = -__LINE__;
- b->data = NULL;
-
- bstr__free (b);
- return BSTR_OK;
-}
-
-/* int binstr (const_bstring b1, int pos, const_bstring b2)
- *
- * Search for the bstring b2 in b1 starting from position pos, and searching
- * forward. If it is found then return with the first position where it is
- * found, otherwise return BSTR_ERR. Note that this is just a brute force
- * string searcher that does not attempt clever things like the Boyer-Moore
- * search algorithm. Because of this there are many degenerate cases where
- * this can take much longer than it needs to.
- */
-int binstr (const_bstring b1, int pos, const_bstring b2) {
-int j, ii, ll, lf;
-unsigned char * d0;
-unsigned char c0;
-register unsigned char * d1;
-register unsigned char c1;
-register int i;
-
- if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
- b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
- if (b1->slen == pos) return (b2->slen == 0)?pos:BSTR_ERR;
- if (b1->slen < pos || pos < 0) return BSTR_ERR;
- if (b2->slen == 0) return pos;
-
- /* No space to find such a string? */
- if ((lf = b1->slen - b2->slen + 1) <= pos) return BSTR_ERR;
-
- /* An obvious alias case */
- if (b1->data == b2->data && pos == 0) return 0;
-
- i = pos;
-
- d0 = b2->data;
- d1 = b1->data;
- ll = b2->slen;
-
- /* Peel off the b2->slen == 1 case */
- c0 = d0[0];
- if (1 == ll) {
- for (;i < lf; i++) if (c0 == d1[i]) return i;
- return BSTR_ERR;
- }
-
- c1 = c0;
- j = 0;
- lf = b1->slen - 1;
-
- ii = -1;
- if (i < lf) do {
- /* Unrolled current character test */
- if (c1 != d1[i]) {
- if (c1 != d1[1+i]) {
- i += 2;
- continue;
- }
- i++;
- }
-
- /* Take note if this is the start of a potential match */
- if (0 == j) ii = i;
-
- /* Shift the test character down by one */
- j++;
- i++;
-
- /* If this isn't past the last character continue */
- if (j < ll) {
- c1 = d0[j];
- continue;
- }
-
- N0:;
-
- /* If no characters mismatched, then we matched */
- if (i == ii+j) return ii;
-
- /* Shift back to the beginning */
- i -= j;
- j = 0;
- c1 = c0;
- } while (i < lf);
-
- /* Deal with last case if unrolling caused a misalignment */
- if (i == lf && ll == j+1 && c1 == d1[i]) goto N0;
-
- return BSTR_ERR;
-}
-
-/* int binstrr (const_bstring b1, int pos, const_bstring b2)
- *
- * Search for the bstring b2 in b1 starting from position pos, and searching
- * backward. If it is found then return with the first position where it is
- * found, otherwise return BSTR_ERR. Note that this is just a brute force
- * string searcher that does not attempt clever things like the Boyer-Moore
- * search algorithm. Because of this there are many degenerate cases where
- * this can take much longer than it needs to.
- */
-int binstrr (const_bstring b1, int pos, const_bstring b2) {
-int j, i, l;
-unsigned char * d0, * d1;
-
- if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
- b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
- if (b1->slen == pos && b2->slen == 0) return pos;
- if (b1->slen < pos || pos < 0) return BSTR_ERR;
- if (b2->slen == 0) return pos;
-
- /* Obvious alias case */
- if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return 0;
-
- i = pos;
- if ((l = b1->slen - b2->slen) < 0) return BSTR_ERR;
-
- /* If no space to find such a string then snap back */
- if (l + 1 <= i) i = l;
- j = 0;
-
- d0 = b2->data;
- d1 = b1->data;
- l = b2->slen;
-
- for (;;) {
- if (d0[j] == d1[i + j]) {
- j ++;
- if (j >= l) return i;
- } else {
- i --;
- if (i < 0) break;
- j=0;
- }
- }
-
- return BSTR_ERR;
-}
-
-/* int binstrcaseless (const_bstring b1, int pos, const_bstring b2)
- *
- * Search for the bstring b2 in b1 starting from position pos, and searching
- * forward but without regard to case. If it is found then return with the
- * first position where it is found, otherwise return BSTR_ERR. Note that
- * this is just a brute force string searcher that does not attempt clever
- * things like the Boyer-Moore search algorithm. Because of this there are
- * many degenerate cases where this can take much longer than it needs to.
- */
-int binstrcaseless (const_bstring b1, int pos, const_bstring b2) {
-int j, i, l, ll;
-unsigned char * d0, * d1;
-
- if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
- b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
- if (b1->slen == pos) return (b2->slen == 0)?pos:BSTR_ERR;
- if (b1->slen < pos || pos < 0) return BSTR_ERR;
- if (b2->slen == 0) return pos;
-
- l = b1->slen - b2->slen + 1;
-
- /* No space to find such a string? */
- if (l <= pos) return BSTR_ERR;
-
- /* An obvious alias case */
- if (b1->data == b2->data && pos == 0) return BSTR_OK;
-
- i = pos;
- j = 0;
-
- d0 = b2->data;
- d1 = b1->data;
- ll = b2->slen;
-
- for (;;) {
- if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) {
- j ++;
- if (j >= ll) return i;
- } else {
- i ++;
- if (i >= l) break;
- j=0;
- }
- }
-
- return BSTR_ERR;
-}
-
-/* int binstrrcaseless (const_bstring b1, int pos, const_bstring b2)
- *
- * Search for the bstring b2 in b1 starting from position pos, and searching
- * backward but without regard to case. If it is found then return with the
- * first position where it is found, otherwise return BSTR_ERR. Note that
- * this is just a brute force string searcher that does not attempt clever
- * things like the Boyer-Moore search algorithm. Because of this there are
- * many degenerate cases where this can take much longer than it needs to.
- */
-int binstrrcaseless (const_bstring b1, int pos, const_bstring b2) {
-int j, i, l;
-unsigned char * d0, * d1;
-
- if (b1 == NULL || b1->data == NULL || b1->slen < 0 ||
- b2 == NULL || b2->data == NULL || b2->slen < 0) return BSTR_ERR;
- if (b1->slen == pos && b2->slen == 0) return pos;
- if (b1->slen < pos || pos < 0) return BSTR_ERR;
- if (b2->slen == 0) return pos;
-
- /* Obvious alias case */
- if (b1->data == b2->data && pos == 0 && b2->slen <= b1->slen) return BSTR_OK;
-
- i = pos;
- if ((l = b1->slen - b2->slen) < 0) return BSTR_ERR;
-
- /* If no space to find such a string then snap back */
- if (l + 1 <= i) i = l;
- j = 0;
-
- d0 = b2->data;
- d1 = b1->data;
- l = b2->slen;
-
- for (;;) {
- if (d0[j] == d1[i + j] || downcase (d0[j]) == downcase (d1[i + j])) {
- j ++;
- if (j >= l) return i;
- } else {
- i --;
- if (i < 0) break;
- j=0;
- }
- }
-
- return BSTR_ERR;
-}
-
-
-/* int bstrchrp (const_bstring b, int c, int pos)
- *
- * Search for the character c in b forwards from the position pos
- * (inclusive).
- */
-int bstrchrp (const_bstring b, int c, int pos) {
-unsigned char * p;
-
- if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR;
- p = (unsigned char *) bstr__memchr ((b->data + pos), (unsigned char) c, (b->slen - pos));
- if (p) return (int) (p - b->data);
- return BSTR_ERR;
-}
-
-/* int bstrrchrp (const_bstring b, int c, int pos)
- *
- * Search for the character c in b backwards from the position pos in string
- * (inclusive).
- */
-int bstrrchrp (const_bstring b, int c, int pos) {
-int i;
-
- if (b == NULL || b->data == NULL || b->slen <= pos || pos < 0) return BSTR_ERR;
- for (i=pos; i >= 0; i--) {
- if (b->data[i] == (unsigned char) c) return i;
- }
- return BSTR_ERR;
-}
-
-#if !defined (BSTRLIB_AGGRESSIVE_MEMORY_FOR_SPEED_TRADEOFF)
-#define LONG_LOG_BITS_QTY (3)
-#define LONG_BITS_QTY (1 << LONG_LOG_BITS_QTY)
-#define LONG_TYPE unsigned char
-
-#define CFCLEN ((1 << CHAR_BIT) / LONG_BITS_QTY)
-struct charField { LONG_TYPE content[CFCLEN]; };
-#define testInCharField(cf,c) ((cf)->content[(c) >> LONG_LOG_BITS_QTY] & (((long)1) << ((c) & (LONG_BITS_QTY-1))))
-#define setInCharField(cf,idx) { \
- unsigned int c = (unsigned int) (idx); \
- (cf)->content[c >> LONG_LOG_BITS_QTY] |= (LONG_TYPE) (1ul << (c & (LONG_BITS_QTY-1))); \
-}
-
-#else
-
-#define CFCLEN (1 << CHAR_BIT)
-struct charField { unsigned char content[CFCLEN]; };
-#define testInCharField(cf,c) ((cf)->content[(unsigned char) (c)])
-#define setInCharField(cf,idx) (cf)->content[(unsigned int) (idx)] = ~0
-
-#endif
-
-/* Convert a bstring to charField */
-static int buildCharField (struct charField * cf, const_bstring b) {
-int i;
- if (b == NULL || b->data == NULL || b->slen <= 0) return BSTR_ERR;
- memset ((void *) cf->content, 0, sizeof (struct charField));
- for (i=0; i < b->slen; i++) {
- setInCharField (cf, b->data[i]);
- }
- return BSTR_OK;
-}
-
-static void invertCharField (struct charField * cf) {
-int i;
- for (i=0; i < CFCLEN; i++) cf->content[i] = ~cf->content[i];
-}
-
-/* Inner engine for binchr */
-static int binchrCF (const unsigned char * data, int len, int pos, const struct charField * cf) {
-int i;
- for (i=pos; i < len; i++) {
- unsigned char c = (unsigned char) data[i];
- if (testInCharField (cf, c)) return i;
- }
- return BSTR_ERR;
-}
-
-/* int binchr (const_bstring b0, int pos, const_bstring b1);
- *
- * Search for the first position in b0 starting from pos or after, in which
- * one of the characters in b1 is found and return it. If such a position
- * does not exist in b0, then BSTR_ERR is returned.
- */
-int binchr (const_bstring b0, int pos, const_bstring b1) {
-struct charField chrs;
- if (pos < 0 || b0 == NULL || b0->data == NULL ||
- b0->slen <= pos) return BSTR_ERR;
- if (1 == b1->slen) return bstrchrp (b0, b1->data[0], pos);
- if (0 > buildCharField (&chrs, b1)) return BSTR_ERR;
- return binchrCF (b0->data, b0->slen, pos, &chrs);
-}
-
-/* Inner engine for binchrr */
-static int binchrrCF (const unsigned char * data, int pos, const struct charField * cf) {
-int i;
- for (i=pos; i >= 0; i--) {
- unsigned int c = (unsigned int) data[i];
- if (testInCharField (cf, c)) return i;
- }
- return BSTR_ERR;
-}
-
-/* int binchrr (const_bstring b0, int pos, const_bstring b1);
- *
- * Search for the last position in b0 no greater than pos, in which one of
- * the characters in b1 is found and return it. If such a position does not
- * exist in b0, then BSTR_ERR is returned.
- */
-int binchrr (const_bstring b0, int pos, const_bstring b1) {
-struct charField chrs;
- if (pos < 0 || b0 == NULL || b0->data == NULL || b1 == NULL ||
- b0->slen < pos) return BSTR_ERR;
- if (pos == b0->slen) pos--;
- if (1 == b1->slen) return bstrrchrp (b0, b1->data[0], pos);
- if (0 > buildCharField (&chrs, b1)) return BSTR_ERR;
- return binchrrCF (b0->data, pos, &chrs);
-}
-
-/* int bninchr (const_bstring b0, int pos, const_bstring b1);
- *
- * Search for the first position in b0 starting from pos or after, in which
- * none of the characters in b1 is found and return it. If such a position
- * does not exist in b0, then BSTR_ERR is returned.
- */
-int bninchr (const_bstring b0, int pos, const_bstring b1) {
-struct charField chrs;
- if (pos < 0 || b0 == NULL || b0->data == NULL ||
- b0->slen <= pos) return BSTR_ERR;
- if (buildCharField (&chrs, b1) < 0) return BSTR_ERR;
- invertCharField (&chrs);
- return binchrCF (b0->data, b0->slen, pos, &chrs);
-}
-
-/* int bninchrr (const_bstring b0, int pos, const_bstring b1);
- *
- * Search for the last position in b0 no greater than pos, in which none of
- * the characters in b1 is found and return it. If such a position does not
- * exist in b0, then BSTR_ERR is returned.
- */
-int bninchrr (const_bstring b0, int pos, const_bstring b1) {
-struct charField chrs;
- if (pos < 0 || b0 == NULL || b0->data == NULL ||
- b0->slen < pos) return BSTR_ERR;
- if (pos == b0->slen) pos--;
- if (buildCharField (&chrs, b1) < 0) return BSTR_ERR;
- invertCharField (&chrs);
- return binchrrCF (b0->data, pos, &chrs);
-}
-
-/* int bsetstr (bstring b0, int pos, bstring b1, unsigned char fill)
- *
- * Overwrite the string b0 starting at position pos with the string b1. If
- * the position pos is past the end of b0, then the character "fill" is
- * appended as necessary to make up the gap between the end of b0 and pos.
- * If b1 is NULL, it behaves as if it were a 0-length string.
- */
-int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill) {
-int d, newlen;
-ptrdiff_t pd;
-bstring aux = (bstring) b1;
-
- if (pos < 0 || b0 == NULL || b0->slen < 0 || NULL == b0->data ||
- b0->mlen < b0->slen || b0->mlen <= 0) return BSTR_ERR;
- if (b1 != NULL && (b1->slen < 0 || b1->data == NULL)) return BSTR_ERR;
-
- d = pos;
-
- /* Aliasing case */
- if (NULL != aux) {
- if ((pd = (ptrdiff_t) (b1->data - b0->data)) >= 0 && pd < (ptrdiff_t) b0->mlen) {
- if (NULL == (aux = bstrcpy (b1))) return BSTR_ERR;
- }
- d += aux->slen;
- }
-
- /* Increase memory size if necessary */
- if (balloc (b0, d + 1) != BSTR_OK) {
- if (aux != b1) bdestroy (aux);
- return BSTR_ERR;
- }
-
- newlen = b0->slen;
-
- /* Fill in "fill" character as necessary */
- if (pos > newlen) {
- bstr__memset (b0->data + b0->slen, (int) fill, (size_t) (pos - b0->slen));
- newlen = pos;
- }
-
- /* Copy b1 to position pos in b0. */
- if (aux != NULL) {
- bBlockCopy ((char *) (b0->data + pos), (char *) aux->data, aux->slen);
- if (aux != b1) bdestroy (aux);
- }
-
- /* Indicate the potentially increased size of b0 */
- if (d > newlen) newlen = d;
-
- b0->slen = newlen;
- b0->data[newlen] = (unsigned char) '\0';
-
- return BSTR_OK;
-}
-
-/* int binsert (bstring b1, int pos, bstring b2, unsigned char fill)
- *
- * Inserts the string b2 into b1 at position pos. If the position pos is
- * past the end of b1, then the character "fill" is appended as necessary to
- * make up the gap between the end of b1 and pos. Unlike bsetstr, binsert
- * does not allow b2 to be NULL.
- */
-int binsert (bstring b1, int pos, const_bstring b2, unsigned char fill) {
-int d, l;
-ptrdiff_t pd;
-bstring aux = (bstring) b2;
-
- if (pos < 0 || b1 == NULL || b2 == NULL || b1->slen < 0 ||
- b2->slen < 0 || b1->mlen < b1->slen || b1->mlen <= 0) return BSTR_ERR;
-
- /* Aliasing case */
- if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->mlen) {
- if (NULL == (aux = bstrcpy (b2))) return BSTR_ERR;
- }
-
- /* Compute the two possible end pointers */
- d = b1->slen + aux->slen;
- l = pos + aux->slen;
- if ((d|l) < 0) return BSTR_ERR;
-
- if (l > d) {
- /* Inserting past the end of the string */
- if (balloc (b1, l + 1) != BSTR_OK) {
- if (aux != b2) bdestroy (aux);
- return BSTR_ERR;
- }
- bstr__memset (b1->data + b1->slen, (int) fill, (size_t) (pos - b1->slen));
- b1->slen = l;
- } else {
- /* Inserting in the middle of the string */
- if (balloc (b1, d + 1) != BSTR_OK) {
- if (aux != b2) bdestroy (aux);
- return BSTR_ERR;
- }
- bBlockCopy (b1->data + l, b1->data + pos, d - l);
- b1->slen = d;
- }
- bBlockCopy (b1->data + pos, aux->data, aux->slen);
- b1->data[b1->slen] = (unsigned char) '\0';
- if (aux != b2) bdestroy (aux);
- return BSTR_OK;
-}
-
-/* int breplace (bstring b1, int pos, int len, bstring b2,
- * unsigned char fill)
- *
- * Replace a section of a string from pos for a length len with the string b2.
- * fill is used is pos > b1->slen.
- */
-int breplace (bstring b1, int pos, int len, const_bstring b2,
- unsigned char fill) {
-int pl, ret;
-ptrdiff_t pd;
-bstring aux = (bstring) b2;
-
- if (pos < 0 || len < 0 || (pl = pos + len) < 0 || b1 == NULL ||
- b2 == NULL || b1->data == NULL || b2->data == NULL ||
- b1->slen < 0 || b2->slen < 0 || b1->mlen < b1->slen ||
- b1->mlen <= 0) return BSTR_ERR;
-
- /* Straddles the end? */
- if (pl >= b1->slen) {
- if ((ret = bsetstr (b1, pos, b2, fill)) < 0) return ret;
- if (pos + b2->slen < b1->slen) {
- b1->slen = pos + b2->slen;
- b1->data[b1->slen] = (unsigned char) '\0';
- }
- return ret;
- }
-
- /* Aliasing case */
- if ((pd = (ptrdiff_t) (b2->data - b1->data)) >= 0 && pd < (ptrdiff_t) b1->slen) {
- if (NULL == (aux = bstrcpy (b2))) return BSTR_ERR;
- }
-
- if (aux->slen > len) {
- if (balloc (b1, b1->slen + aux->slen - len) != BSTR_OK) {
- if (aux != b2) bdestroy (aux);
- return BSTR_ERR;
- }
- }
-
- if (aux->slen != len) bstr__memmove (b1->data + pos + aux->slen, b1->data + pos + len, b1->slen - (pos + len));
- bstr__memcpy (b1->data + pos, aux->data, aux->slen);
- b1->slen += aux->slen - len;
- b1->data[b1->slen] = (unsigned char) '\0';
- if (aux != b2) bdestroy (aux);
- return BSTR_OK;
-}
-
-/*
- * findreplaceengine is used to implement bfindreplace and
- * bfindreplacecaseless. It works by breaking the three cases of
- * expansion, reduction and replacement, and solving each of these
- * in the most efficient way possible.
- */
-
-typedef int (*instr_fnptr) (const_bstring s1, int pos, const_bstring s2);
-
-#define INITIAL_STATIC_FIND_INDEX_COUNT 32
-
-static int findreplaceengine (bstring b, const_bstring find, const_bstring repl, int pos, instr_fnptr instr) {
-int i, ret, slen, mlen, delta, acc;
-int * d;
-int static_d[INITIAL_STATIC_FIND_INDEX_COUNT+1]; /* This +1 is unnecessary, but it shuts up LINT. */
-ptrdiff_t pd;
-bstring auxf = (bstring) find;
-bstring auxr = (bstring) repl;
-
- if (b == NULL || b->data == NULL || find == NULL ||
- find->data == NULL || repl == NULL || repl->data == NULL ||
- pos < 0 || find->slen <= 0 || b->mlen < 0 || b->slen > b->mlen ||
- b->mlen <= 0 || b->slen < 0 || repl->slen < 0) return BSTR_ERR;
- if (pos > b->slen - find->slen) return BSTR_OK;
-
- /* Alias with find string */
- pd = (ptrdiff_t) (find->data - b->data);
- if ((ptrdiff_t) (pos - find->slen) < pd && pd < (ptrdiff_t) b->slen) {
- if (NULL == (auxf = bstrcpy (find))) return BSTR_ERR;
- }
-
- /* Alias with repl string */
- pd = (ptrdiff_t) (repl->data - b->data);
- if ((ptrdiff_t) (pos - repl->slen) < pd && pd < (ptrdiff_t) b->slen) {
- if (NULL == (auxr = bstrcpy (repl))) {
- if (auxf != find) bdestroy (auxf);
- return BSTR_ERR;
- }
- }
-
- delta = auxf->slen - auxr->slen;
-
- /* in-place replacement since find and replace strings are of equal
- length */
- if (delta == 0) {
- while ((pos = instr (b, pos, auxf)) >= 0) {
- bstr__memcpy (b->data + pos, auxr->data, auxr->slen);
- pos += auxf->slen;
- }
- if (auxf != find) bdestroy (auxf);
- if (auxr != repl) bdestroy (auxr);
- return BSTR_OK;
- }
-
- /* shrinking replacement since auxf->slen > auxr->slen */
- if (delta > 0) {
- acc = 0;
-
- while ((i = instr (b, pos, auxf)) >= 0) {
- if (acc && i > pos)
- bstr__memmove (b->data + pos - acc, b->data + pos, i - pos);
- if (auxr->slen)
- bstr__memcpy (b->data + i - acc, auxr->data, auxr->slen);
- acc += delta;
- pos = i + auxf->slen;
- }
-
- if (acc) {
- i = b->slen;
- if (i > pos)
- bstr__memmove (b->data + pos - acc, b->data + pos, i - pos);
- b->slen -= acc;
- b->data[b->slen] = (unsigned char) '\0';
- }
-
- if (auxf != find) bdestroy (auxf);
- if (auxr != repl) bdestroy (auxr);
- return BSTR_OK;
- }
-
- /* expanding replacement since find->slen < repl->slen. Its a lot
- more complicated. This works by first finding all the matches and
- storing them to a growable array, then doing at most one resize of
- the destination bstring and then performing the direct memory transfers
- of the string segment pieces to form the final result. The growable
- array of matches uses a deferred doubling reallocing strategy. What
- this means is that it starts as a reasonably fixed sized auto array in
- the hopes that many if not most cases will never need to grow this
- array. But it switches as soon as the bounds of the array will be
- exceeded. An extra find result is always appended to this array that
- corresponds to the end of the destination string, so slen is checked
- against mlen - 1 rather than mlen before resizing.
- */
-
- mlen = INITIAL_STATIC_FIND_INDEX_COUNT;
- d = (int *) static_d; /* Avoid malloc for trivial/initial cases */
- acc = slen = 0;
-
- while ((pos = instr (b, pos, auxf)) >= 0) {
- if (slen >= mlen - 1) {
- int sl, *t;
-
- mlen += mlen;
- sl = sizeof (int *) * mlen;
- if (static_d == d) d = NULL; /* static_d cannot be realloced */
- if (mlen <= 0 || sl < mlen || NULL == (t = (int *) bstr__realloc (d, sl))) {
- ret = BSTR_ERR;
- goto done;
- }
- if (NULL == d) bstr__memcpy (t, static_d, sizeof (static_d));
- d = t;
- }
- d[slen] = pos;
- slen++;
- acc -= delta;
- pos += auxf->slen;
- if (pos < 0 || acc < 0) {
- ret = BSTR_ERR;
- goto done;
- }
- }
-
- /* slen <= INITIAL_STATIC_INDEX_COUNT-1 or mlen-1 here. */
- d[slen] = b->slen;
-
- if (BSTR_OK == (ret = balloc (b, b->slen + acc + 1))) {
- b->slen += acc;
- for (i = slen-1; i >= 0; i--) {
- int s, l;
- s = d[i] + auxf->slen;
- l = d[i+1] - s; /* d[slen] may be accessed here. */
- if (l) {
- bstr__memmove (b->data + s + acc, b->data + s, l);
- }
- if (auxr->slen) {
- bstr__memmove (b->data + s + acc - auxr->slen,
- auxr->data, auxr->slen);
- }
- acc += delta;
- }
- b->data[b->slen] = (unsigned char) '\0';
- }
-
- done:;
- if (static_d == d) d = NULL;
- bstr__free (d);
- if (auxf != find) bdestroy (auxf);
- if (auxr != repl) bdestroy (auxr);
- return ret;
-}
-
-/* int bfindreplace (bstring b, const_bstring find, const_bstring repl,
- * int pos)
- *
- * Replace all occurrences of a find string with a replace string after a
- * given point in a bstring.
- */
-int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos) {
- return findreplaceengine (b, find, repl, pos, binstr);
-}
-
-/* int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl,
- * int pos)
- *
- * Replace all occurrences of a find string, ignoring case, with a replace
- * string after a given point in a bstring.
- */
-int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos) {
- return findreplaceengine (b, find, repl, pos, binstrcaseless);
-}
-
-/* int binsertch (bstring b, int pos, int len, unsigned char fill)
- *
- * Inserts the character fill repeatedly into b at position pos for a
- * length len. If the position pos is past the end of b, then the
- * character "fill" is appended as necessary to make up the gap between the
- * end of b and the position pos + len.
- */
-int binsertch (bstring b, int pos, int len, unsigned char fill) {
-int d, l, i;
-
- if (pos < 0 || b == NULL || b->slen < 0 || b->mlen < b->slen ||
- b->mlen <= 0 || len < 0) return BSTR_ERR;
-
- /* Compute the two possible end pointers */
- d = b->slen + len;
- l = pos + len;
- if ((d|l) < 0) return BSTR_ERR;
-
- if (l > d) {
- /* Inserting past the end of the string */
- if (balloc (b, l + 1) != BSTR_OK) return BSTR_ERR;
- pos = b->slen;
- b->slen = l;
- } else {
- /* Inserting in the middle of the string */
- if (balloc (b, d + 1) != BSTR_OK) return BSTR_ERR;
- for (i = d - 1; i >= l; i--) {
- b->data[i] = b->data[i - len];
- }
- b->slen = d;
- }
-
- for (i=pos; i < l; i++) b->data[i] = fill;
- b->data[b->slen] = (unsigned char) '\0';
- return BSTR_OK;
-}
-
-/* int bpattern (bstring b, int len)
- *
- * Replicate the bstring, b in place, end to end repeatedly until it
- * surpasses len characters, then chop the result to exactly len characters.
- * This function operates in-place. The function will return with BSTR_ERR
- * if b is NULL or of length 0, otherwise BSTR_OK is returned.
- */
-int bpattern (bstring b, int len) {
-int i, d;
-
- d = blength (b);
- if (d <= 0 || len < 0 || balloc (b, len + 1) != BSTR_OK) return BSTR_ERR;
- if (len > 0) {
- if (d == 1) return bsetstr (b, len, NULL, b->data[0]);
- for (i = d; i < len; i++) b->data[i] = b->data[i - d];
- }
- b->data[len] = (unsigned char) '\0';
- b->slen = len;
- return BSTR_OK;
-}
-
-#define BS_BUFF_SZ (1024)
-
-/* int breada (bstring b, bNread readPtr, void * parm)
- *
- * Use a finite buffer fread-like function readPtr to concatenate to the
- * bstring b the entire contents of file-like source data in a roughly
- * efficient way.
- */
-int breada (bstring b, bNread readPtr, void * parm) {
-int i, l, n;
-
- if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen ||
- b->mlen <= 0 || readPtr == NULL) return BSTR_ERR;
-
- i = b->slen;
- for (n=i+16; ; n += ((n < BS_BUFF_SZ) ? n : BS_BUFF_SZ)) {
- if (BSTR_OK != balloc (b, n + 1)) return BSTR_ERR;
- l = (int) readPtr ((void *) (b->data + i), 1, n - i, parm);
- i += l;
- b->slen = i;
- if (i < n) break;
- }
-
- b->data[i] = (unsigned char) '\0';
- return BSTR_OK;
-}
-
-/* bstring bread (bNread readPtr, void * parm)
- *
- * Use a finite buffer fread-like function readPtr to create a bstring
- * filled with the entire contents of file-like source data in a roughly
- * efficient way.
- */
-bstring bread (bNread readPtr, void * parm) {
-bstring buff;
-
- if (0 > breada (buff = bfromcstr (""), readPtr, parm)) {
- bdestroy (buff);
- return NULL;
- }
- return buff;
-}
-
-/* int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator)
- *
- * Use an fgetc-like single character stream reading function (getcPtr) to
- * obtain a sequence of characters which are concatenated to the end of the
- * bstring b. The stream read is terminated by the passed in terminator
- * parameter.
- *
- * If getcPtr returns with a negative number, or the terminator character
- * (which is appended) is read, then the stream reading is halted and the
- * function returns with a partial result in b. If there is an empty partial
- * result, 1 is returned. If no characters are read, or there is some other
- * detectable error, BSTR_ERR is returned.
- */
-int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator) {
-int c, d, e;
-
- if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen ||
- b->mlen <= 0 || getcPtr == NULL) return BSTR_ERR;
- d = 0;
- e = b->mlen - 2;
-
- while ((c = getcPtr (parm)) >= 0) {
- if (d > e) {
- b->slen = d;
- if (balloc (b, d + 2) != BSTR_OK) return BSTR_ERR;
- e = b->mlen - 2;
- }
- b->data[d] = (unsigned char) c;
- d++;
- if (c == terminator) break;
- }
-
- b->data[d] = (unsigned char) '\0';
- b->slen = d;
-
- return d == 0 && c < 0;
-}
-
-/* int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator)
- *
- * Use an fgetc-like single character stream reading function (getcPtr) to
- * obtain a sequence of characters which are concatenated to the end of the
- * bstring b. The stream read is terminated by the passed in terminator
- * parameter.
- *
- * If getcPtr returns with a negative number, or the terminator character
- * (which is appended) is read, then the stream reading is halted and the
- * function returns with a partial result concatentated to b. If there is
- * an empty partial result, 1 is returned. If no characters are read, or
- * there is some other detectable error, BSTR_ERR is returned.
- */
-int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator) {
-int c, d, e;
-
- if (b == NULL || b->mlen <= 0 || b->slen < 0 || b->mlen < b->slen ||
- b->mlen <= 0 || getcPtr == NULL) return BSTR_ERR;
- d = b->slen;
- e = b->mlen - 2;
-
- while ((c = getcPtr (parm)) >= 0) {
- if (d > e) {
- b->slen = d;
- if (balloc (b, d + 2) != BSTR_OK) return BSTR_ERR;
- e = b->mlen - 2;
- }
- b->data[d] = (unsigned char) c;
- d++;
- if (c == terminator) break;
- }
-
- b->data[d] = (unsigned char) '\0';
- b->slen = d;
-
- return d == 0 && c < 0;
-}
-
-/* bstring bgets (bNgetc getcPtr, void * parm, char terminator)
- *
- * Use an fgetc-like single character stream reading function (getcPtr) to
- * obtain a sequence of characters which are concatenated into a bstring.
- * The stream read is terminated by the passed in terminator function.
- *
- * If getcPtr returns with a negative number, or the terminator character
- * (which is appended) is read, then the stream reading is halted and the
- * result obtained thus far is returned. If no characters are read, or
- * there is some other detectable error, NULL is returned.
- */
-bstring bgets (bNgetc getcPtr, void * parm, char terminator) {
-bstring buff;
-
- if (0 > bgetsa (buff = bfromcstr (""), getcPtr, parm, terminator) || 0 >= buff->slen) {
- bdestroy (buff);
- buff = NULL;
- }
- return buff;
-}
-
-struct bStream {
- bstring buff; /* Buffer for over-reads */
- void * parm; /* The stream handle for core stream */
- bNread readFnPtr; /* fread compatible fnptr for core stream */
- int isEOF; /* track file's EOF state */
- int maxBuffSz;
-};
-
-/* struct bStream * bsopen (bNread readPtr, void * parm)
- *
- * Wrap a given open stream (described by a fread compatible function
- * pointer and stream handle) into an open bStream suitable for the bstring
- * library streaming functions.
- */
-struct bStream * bsopen (bNread readPtr, void * parm) {
-struct bStream * s;
-
- if (readPtr == NULL) return NULL;
- s = (struct bStream *) bstr__alloc (sizeof (struct bStream));
- if (s == NULL) return NULL;
- s->parm = parm;
- s->buff = bfromcstr ("");
- s->readFnPtr = readPtr;
- s->maxBuffSz = BS_BUFF_SZ;
- s->isEOF = 0;
- return s;
-}
-
-/* int bsbufflength (struct bStream * s, int sz)
- *
- * Set the length of the buffer used by the bStream. If sz is zero, the
- * length is not set. This function returns with the previous length.
- */
-int bsbufflength (struct bStream * s, int sz) {
-int oldSz;
- if (s == NULL || sz < 0) return BSTR_ERR;
- oldSz = s->maxBuffSz;
- if (sz > 0) s->maxBuffSz = sz;
- return oldSz;
-}
-
-int bseof (const struct bStream * s) {
- if (s == NULL || s->readFnPtr == NULL) return BSTR_ERR;
- return s->isEOF && (s->buff->slen == 0);
-}
-
-/* void * bsclose (struct bStream * s)
- *
- * Close the bStream, and return the handle to the stream that was originally
- * used to open the given stream.
- */
-void * bsclose (struct bStream * s) {
-void * parm;
- if (s == NULL) return NULL;
- s->readFnPtr = NULL;
- if (s->buff) bdestroy (s->buff);
- s->buff = NULL;
- parm = s->parm;
- s->parm = NULL;
- s->isEOF = 1;
- bstr__free (s);
- return parm;
-}
-
-/* int bsreadlna (bstring r, struct bStream * s, char terminator)
- *
- * Read a bstring terminated by the terminator character or the end of the
- * stream from the bStream (s) and return it into the parameter r. This
- * function may read additional characters from the core stream that are not
- * returned, but will be retained for subsequent read operations.
- */
-int bsreadlna (bstring r, struct bStream * s, char terminator) {
-int i, l, ret, rlo;
-char * b;
-struct tagbstring x;
-
- if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0 ||
- r->slen < 0 || r->mlen < r->slen) return BSTR_ERR;
- l = s->buff->slen;
- if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
- b = (char *) s->buff->data;
- x.data = (unsigned char *) b;
-
- /* First check if the current buffer holds the terminator */
- b[l] = terminator; /* Set sentinel */
- for (i=0; b[i] != terminator; i++) ;
- if (i < l) {
- x.slen = i + 1;
- ret = bconcat (r, &x);
- s->buff->slen = l;
- if (BSTR_OK == ret) bdelete (s->buff, 0, i + 1);
- return BSTR_OK;
- }
-
- rlo = r->slen;
-
- /* If not then just concatenate the entire buffer to the output */
- x.slen = l;
- if (BSTR_OK != bconcat (r, &x)) return BSTR_ERR;
-
- /* Perform direct in-place reads into the destination to allow for
- the minimum of data-copies */
- for (;;) {
- if (BSTR_OK != balloc (r, r->slen + s->maxBuffSz + 1)) return BSTR_ERR;
- b = (char *) (r->data + r->slen);
- l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm);
- if (l <= 0) {
- r->data[r->slen] = (unsigned char) '\0';
- s->buff->slen = 0;
- s->isEOF = 1;
- /* If nothing was read return with an error message */
- return BSTR_ERR & -(r->slen == rlo);
- }
- b[l] = terminator; /* Set sentinel */
- for (i=0; b[i] != terminator; i++) ;
- if (i < l) break;
- r->slen += l;
- }
-
- /* Terminator found, push over-read back to buffer */
- i++;
- r->slen += i;
- s->buff->slen = l - i;
- bstr__memcpy (s->buff->data, b + i, l - i);
- r->data[r->slen] = (unsigned char) '\0';
- return BSTR_OK;
-}
-
-/* int bsreadlnsa (bstring r, struct bStream * s, bstring term)
- *
- * Read a bstring terminated by any character in the term string or the end
- * of the stream from the bStream (s) and return it into the parameter r.
- * This function may read additional characters from the core stream that
- * are not returned, but will be retained for subsequent read operations.
- */
-int bsreadlnsa (bstring r, struct bStream * s, const_bstring term) {
-int i, l, ret, rlo;
-unsigned char * b;
-struct tagbstring x;
-struct charField cf;
-
- if (s == NULL || s->buff == NULL || r == NULL || term == NULL ||
- term->data == NULL || r->mlen <= 0 || r->slen < 0 ||
- r->mlen < r->slen) return BSTR_ERR;
- if (term->slen == 1) return bsreadlna (r, s, term->data[0]);
- if (term->slen < 1 || buildCharField (&cf, term)) return BSTR_ERR;
-
- l = s->buff->slen;
- if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
- b = (unsigned char *) s->buff->data;
- x.data = b;
-
- /* First check if the current buffer holds the terminator */
- b[l] = term->data[0]; /* Set sentinel */
- for (i=0; !testInCharField (&cf, b[i]); i++) ;
- if (i < l) {
- x.slen = i + 1;
- ret = bconcat (r, &x);
- s->buff->slen = l;
- if (BSTR_OK == ret) bdelete (s->buff, 0, i + 1);
- return BSTR_OK;
- }
-
- rlo = r->slen;
-
- /* If not then just concatenate the entire buffer to the output */
- x.slen = l;
- if (BSTR_OK != bconcat (r, &x)) return BSTR_ERR;
-
- /* Perform direct in-place reads into the destination to allow for
- the minimum of data-copies */
- for (;;) {
- if (BSTR_OK != balloc (r, r->slen + s->maxBuffSz + 1)) return BSTR_ERR;
- b = (unsigned char *) (r->data + r->slen);
- l = (int) s->readFnPtr (b, 1, s->maxBuffSz, s->parm);
- if (l <= 0) {
- r->data[r->slen] = (unsigned char) '\0';
- s->buff->slen = 0;
- s->isEOF = 1;
- /* If nothing was read return with an error message */
- return BSTR_ERR & -(r->slen == rlo);
- }
-
- b[l] = term->data[0]; /* Set sentinel */
- for (i=0; !testInCharField (&cf, b[i]); i++) ;
- if (i < l) break;
- r->slen += l;
- }
-
- /* Terminator found, push over-read back to buffer */
- i++;
- r->slen += i;
- s->buff->slen = l - i;
- bstr__memcpy (s->buff->data, b + i, l - i);
- r->data[r->slen] = (unsigned char) '\0';
- return BSTR_OK;
-}
-
-/* int bsreada (bstring r, struct bStream * s, int n)
- *
- * Read a bstring of length n (or, if it is fewer, as many bytes as is
- * remaining) from the bStream. This function may read additional
- * characters from the core stream that are not returned, but will be
- * retained for subsequent read operations. This function will not read
- * additional characters from the core stream beyond virtual stream pointer.
- */
-int bsreada (bstring r, struct bStream * s, int n) {
-int l, ret, orslen;
-char * b;
-struct tagbstring x;
-
- if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0
- || r->slen < 0 || r->mlen < r->slen || n <= 0) return BSTR_ERR;
-
- n += r->slen;
- if (n <= 0) return BSTR_ERR;
-
- l = s->buff->slen;
-
- orslen = r->slen;
-
- if (0 == l) {
- if (s->isEOF) return BSTR_ERR;
- if (r->mlen > n) {
- l = (int) s->readFnPtr (r->data + r->slen, 1, n - r->slen, s->parm);
- if (0 >= l || l > n - r->slen) {
- s->isEOF = 1;
- return BSTR_ERR;
- }
- r->slen += l;
- r->data[r->slen] = (unsigned char) '\0';
- return 0;
- }
- }
-
- if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
- b = (char *) s->buff->data;
- x.data = (unsigned char *) b;
-
- do {
- if (l + r->slen >= n) {
- x.slen = n - r->slen;
- ret = bconcat (r, &x);
- s->buff->slen = l;
- if (BSTR_OK == ret) bdelete (s->buff, 0, x.slen);
- return BSTR_ERR & -(r->slen == orslen);
- }
-
- x.slen = l;
- if (BSTR_OK != bconcat (r, &x)) break;
-
- l = n - r->slen;
- if (l > s->maxBuffSz) l = s->maxBuffSz;
-
- l = (int) s->readFnPtr (b, 1, l, s->parm);
-
- } while (l > 0);
- if (l < 0) l = 0;
- if (l == 0) s->isEOF = 1;
- s->buff->slen = l;
- return BSTR_ERR & -(r->slen == orslen);
-}
-
-/* int bsreadln (bstring r, struct bStream * s, char terminator)
- *
- * Read a bstring terminated by the terminator character or the end of the
- * stream from the bStream (s) and return it into the parameter r. This
- * function may read additional characters from the core stream that are not
- * returned, but will be retained for subsequent read operations.
- */
-int bsreadln (bstring r, struct bStream * s, char terminator) {
- if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0)
- return BSTR_ERR;
- if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
- r->slen = 0;
- return bsreadlna (r, s, terminator);
-}
-
-/* int bsreadlns (bstring r, struct bStream * s, bstring term)
- *
- * Read a bstring terminated by any character in the term string or the end
- * of the stream from the bStream (s) and return it into the parameter r.
- * This function may read additional characters from the core stream that
- * are not returned, but will be retained for subsequent read operations.
- */
-int bsreadlns (bstring r, struct bStream * s, const_bstring term) {
- if (s == NULL || s->buff == NULL || r == NULL || term == NULL
- || term->data == NULL || r->mlen <= 0) return BSTR_ERR;
- if (term->slen == 1) return bsreadln (r, s, term->data[0]);
- if (term->slen < 1) return BSTR_ERR;
- if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
- r->slen = 0;
- return bsreadlnsa (r, s, term);
-}
-
-/* int bsread (bstring r, struct bStream * s, int n)
- *
- * Read a bstring of length n (or, if it is fewer, as many bytes as is
- * remaining) from the bStream. This function may read additional
- * characters from the core stream that are not returned, but will be
- * retained for subsequent read operations. This function will not read
- * additional characters from the core stream beyond virtual stream pointer.
- */
-int bsread (bstring r, struct bStream * s, int n) {
- if (s == NULL || s->buff == NULL || r == NULL || r->mlen <= 0
- || n <= 0) return BSTR_ERR;
- if (BSTR_OK != balloc (s->buff, s->maxBuffSz + 1)) return BSTR_ERR;
- r->slen = 0;
- return bsreada (r, s, n);
-}
-
-/* int bsunread (struct bStream * s, const_bstring b)
- *
- * Insert a bstring into the bStream at the current position. These
- * characters will be read prior to those that actually come from the core
- * stream.
- */
-int bsunread (struct bStream * s, const_bstring b) {
- if (s == NULL || s->buff == NULL) return BSTR_ERR;
- return binsert (s->buff, 0, b, (unsigned char) '?');
-}
-
-/* int bspeek (bstring r, const struct bStream * s)
- *
- * Return the currently buffered characters from the bStream that will be
- * read prior to reads from the core stream.
- */
-int bspeek (bstring r, const struct bStream * s) {
- if (s == NULL || s->buff == NULL) return BSTR_ERR;
- return bassign (r, s->buff);
-}
-
-/* bstring bjoin (const struct bstrList * bl, const_bstring sep);
- *
- * Join the entries of a bstrList into one bstring by sequentially
- * concatenating them with the sep string in between. If there is an error
- * NULL is returned, otherwise a bstring with the correct result is returned.
- */
-bstring bjoin (const struct bstrList * bl, const_bstring sep) {
-bstring b;
-int i, c, v;
-
- if (bl == NULL || bl->qty < 0) return NULL;
- if (sep != NULL && (sep->slen < 0 || sep->data == NULL)) return NULL;
-
- for (i = 0, c = 1; i < bl->qty; i++) {
- v = bl->entry[i]->slen;
- if (v < 0) return NULL; /* Invalid input */
- c += v;
- if (c < 0) return NULL; /* Wrap around ?? */
- }
-
- if (sep != NULL) c += (bl->qty - 1) * sep->slen;
-
- b = (bstring) bstr__alloc (sizeof (struct tagbstring));
- if (NULL == b) return NULL; /* Out of memory */
- b->data = (unsigned char *) bstr__alloc (c);
- if (b->data == NULL) {
- bstr__free (b);
- return NULL;
- }
-
- b->mlen = c;
- b->slen = c-1;
-
- for (i = 0, c = 0; i < bl->qty; i++) {
- if (i > 0 && sep != NULL) {
- bstr__memcpy (b->data + c, sep->data, sep->slen);
- c += sep->slen;
- }
- v = bl->entry[i]->slen;
- bstr__memcpy (b->data + c, bl->entry[i]->data, v);
- c += v;
- }
- b->data[c] = (unsigned char) '\0';
- return b;
-}
-
-#define BSSSC_BUFF_LEN (256)
-
-/* int bssplitscb (struct bStream * s, const_bstring splitStr,
- * int (* cb) (void * parm, int ofs, const_bstring entry), void * parm)
- *
- * Iterate the set of disjoint sequential substrings read from a stream
- * divided by any of the characters in splitStr. An empty splitStr causes
- * the whole stream to be iterated once.
- *
- * Note: At the point of calling the cb function, the bStream pointer is
- * pointed exactly at the position right after having read the split
- * character. The cb function can act on the stream by causing the bStream
- * pointer to move, and bssplitscb will continue by starting the next split
- * at the position of the pointer after the return from cb.
- *
- * However, if the cb causes the bStream s to be destroyed then the cb must
- * return with a negative value, otherwise bssplitscb will continue in an
- * undefined manner.
- */
-int bssplitscb (struct bStream * s, const_bstring splitStr,
- int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) {
-struct charField chrs;
-bstring buff;
-int i, p, ret;
-
- if (cb == NULL || s == NULL || s->readFnPtr == NULL
- || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
-
- if (NULL == (buff = bfromcstr (""))) return BSTR_ERR;
-
- if (splitStr->slen == 0) {
- while (bsreada (buff, s, BSSSC_BUFF_LEN) >= 0) ;
- if ((ret = cb (parm, 0, buff)) > 0)
- ret = 0;
- } else {
- buildCharField (&chrs, splitStr);
- ret = p = i = 0;
- for (;;) {
- if (i >= buff->slen) {
- bsreada (buff, s, BSSSC_BUFF_LEN);
- if (i >= buff->slen) {
- if (0 < (ret = cb (parm, p, buff))) ret = 0;
- break;
- }
- }
- if (testInCharField (&chrs, buff->data[i])) {
- struct tagbstring t;
- unsigned char c;
-
- blk2tbstr (t, buff->data + i + 1, buff->slen - (i + 1));
- if ((ret = bsunread (s, &t)) < 0) break;
- buff->slen = i;
- c = buff->data[i];
- buff->data[i] = (unsigned char) '\0';
- if ((ret = cb (parm, p, buff)) < 0) break;
- buff->data[i] = c;
- buff->slen = 0;
- p += i + 1;
- i = -1;
- }
- i++;
- }
- }
-
- bdestroy (buff);
- return ret;
-}
-
-/* int bssplitstrcb (struct bStream * s, const_bstring splitStr,
- * int (* cb) (void * parm, int ofs, const_bstring entry), void * parm)
- *
- * Iterate the set of disjoint sequential substrings read from a stream
- * divided by the entire substring splitStr. An empty splitStr causes
- * each character of the stream to be iterated.
- *
- * Note: At the point of calling the cb function, the bStream pointer is
- * pointed exactly at the position right after having read the split
- * character. The cb function can act on the stream by causing the bStream
- * pointer to move, and bssplitscb will continue by starting the next split
- * at the position of the pointer after the return from cb.
- *
- * However, if the cb causes the bStream s to be destroyed then the cb must
- * return with a negative value, otherwise bssplitscb will continue in an
- * undefined manner.
- */
-int bssplitstrcb (struct bStream * s, const_bstring splitStr,
- int (* cb) (void * parm, int ofs, const_bstring entry), void * parm) {
-bstring buff;
-int i, p, ret;
-
- if (cb == NULL || s == NULL || s->readFnPtr == NULL
- || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
-
- if (splitStr->slen == 1) return bssplitscb (s, splitStr, cb, parm);
-
- if (NULL == (buff = bfromcstr (""))) return BSTR_ERR;
-
- if (splitStr->slen == 0) {
- for (i=0; bsreada (buff, s, BSSSC_BUFF_LEN) >= 0; i++) {
- if ((ret = cb (parm, 0, buff)) < 0) {
- bdestroy (buff);
- return ret;
- }
- buff->slen = 0;
- }
- return BSTR_OK;
- } else {
- ret = p = i = 0;
- for (i=p=0;;) {
- if ((ret = binstr (buff, 0, splitStr)) >= 0) {
- struct tagbstring t;
- blk2tbstr (t, buff->data, ret);
- i = ret + splitStr->slen;
- if ((ret = cb (parm, p, &t)) < 0) break;
- p += i;
- bdelete (buff, 0, i);
- } else {
- bsreada (buff, s, BSSSC_BUFF_LEN);
- if (bseof (s)) {
- if ((ret = cb (parm, p, buff)) > 0) ret = 0;
- break;
- }
- }
- }
- }
-
- bdestroy (buff);
- return ret;
-}
-
-/* int bstrListCreate (void)
- *
- * Create a bstrList.
- */
-struct bstrList * bstrListCreate (void) {
-struct bstrList * sl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
- if (sl) {
- sl->entry = (bstring *) bstr__alloc (1*sizeof (bstring));
- if (!sl->entry) {
- bstr__free (sl);
- sl = NULL;
- } else {
- sl->qty = 0;
- sl->mlen = 1;
- }
- }
- return sl;
-}
-
-/* int bstrListDestroy (struct bstrList * sl)
- *
- * Destroy a bstrList that has been created by bsplit, bsplits or bstrListCreate.
- */
-int bstrListDestroy (struct bstrList * sl) {
-int i;
- if (sl == NULL || sl->qty < 0) return BSTR_ERR;
- for (i=0; i < sl->qty; i++) {
- if (sl->entry[i]) {
- bdestroy (sl->entry[i]);
- sl->entry[i] = NULL;
- }
- }
- sl->qty = -1;
- sl->mlen = -1;
- bstr__free (sl->entry);
- sl->entry = NULL;
- bstr__free (sl);
- return BSTR_OK;
-}
-
-/* int bstrListAlloc (struct bstrList * sl, int msz)
- *
- * Ensure that there is memory for at least msz number of entries for the
- * list.
- */
-int bstrListAlloc (struct bstrList * sl, int msz) {
-bstring * l;
-int smsz;
-size_t nsz;
- if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return BSTR_ERR;
- if (sl->mlen >= msz) return BSTR_OK;
- smsz = snapUpSize (msz);
- nsz = ((size_t) smsz) * sizeof (bstring);
- if (nsz < (size_t) smsz) return BSTR_ERR;
- l = (bstring *) bstr__realloc (sl->entry, nsz);
- if (!l) {
- smsz = msz;
- nsz = ((size_t) smsz) * sizeof (bstring);
- l = (bstring *) bstr__realloc (sl->entry, nsz);
- if (!l) return BSTR_ERR;
- }
- sl->mlen = smsz;
- sl->entry = l;
- return BSTR_OK;
-}
-
-/* int bstrListAllocMin (struct bstrList * sl, int msz)
- *
- * Try to allocate the minimum amount of memory for the list to include at
- * least msz entries or sl->qty whichever is greater.
- */
-int bstrListAllocMin (struct bstrList * sl, int msz) {
-bstring * l;
-size_t nsz;
- if (!sl || msz <= 0 || !sl->entry || sl->qty < 0 || sl->mlen <= 0 || sl->qty > sl->mlen) return BSTR_ERR;
- if (msz < sl->qty) msz = sl->qty;
- if (sl->mlen == msz) return BSTR_OK;
- nsz = ((size_t) msz) * sizeof (bstring);
- if (nsz < (size_t) msz) return BSTR_ERR;
- l = (bstring *) bstr__realloc (sl->entry, nsz);
- if (!l) return BSTR_ERR;
- sl->mlen = msz;
- sl->entry = l;
- return BSTR_OK;
-}
-
-/* int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
- * int (* cb) (void * parm, int ofs, int len), void * parm)
- *
- * Iterate the set of disjoint sequential substrings over str divided by the
- * character in splitChar.
- *
- * Note: Non-destructive modification of str from within the cb function
- * while performing this split is not undefined. bsplitcb behaves in
- * sequential lock step with calls to cb. I.e., after returning from a cb
- * that return a non-negative integer, bsplitcb continues from the position
- * 1 character after the last detected split character and it will halt
- * immediately if the length of str falls below this point. However, if the
- * cb function destroys str, then it *must* return with a negative value,
- * otherwise bsplitcb will continue in an undefined manner.
- */
-int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
- int (* cb) (void * parm, int ofs, int len), void * parm) {
-int i, p, ret;
-
- if (cb == NULL || str == NULL || pos < 0 || pos > str->slen)
- return BSTR_ERR;
-
- p = pos;
- do {
- for (i=p; i < str->slen; i++) {
- if (str->data[i] == splitChar) break;
- }
- if ((ret = cb (parm, p, i - p)) < 0) return ret;
- p = i + 1;
- } while (p <= str->slen);
- return BSTR_OK;
-}
-
-/* int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
- * int (* cb) (void * parm, int ofs, int len), void * parm)
- *
- * Iterate the set of disjoint sequential substrings over str divided by any
- * of the characters in splitStr. An empty splitStr causes the whole str to
- * be iterated once.
- *
- * Note: Non-destructive modification of str from within the cb function
- * while performing this split is not undefined. bsplitscb behaves in
- * sequential lock step with calls to cb. I.e., after returning from a cb
- * that return a non-negative integer, bsplitscb continues from the position
- * 1 character after the last detected split character and it will halt
- * immediately if the length of str falls below this point. However, if the
- * cb function destroys str, then it *must* return with a negative value,
- * otherwise bsplitscb will continue in an undefined manner.
- */
-int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
- int (* cb) (void * parm, int ofs, int len), void * parm) {
-struct charField chrs;
-int i, p, ret;
-
- if (cb == NULL || str == NULL || pos < 0 || pos > str->slen
- || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
- if (splitStr->slen == 0) {
- if ((ret = cb (parm, 0, str->slen)) > 0) ret = 0;
- return ret;
- }
-
- if (splitStr->slen == 1)
- return bsplitcb (str, splitStr->data[0], pos, cb, parm);
-
- buildCharField (&chrs, splitStr);
-
- p = pos;
- do {
- for (i=p; i < str->slen; i++) {
- if (testInCharField (&chrs, str->data[i])) break;
- }
- if ((ret = cb (parm, p, i - p)) < 0) return ret;
- p = i + 1;
- } while (p <= str->slen);
- return BSTR_OK;
-}
-
-/* int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
- * int (* cb) (void * parm, int ofs, int len), void * parm)
- *
- * Iterate the set of disjoint sequential substrings over str divided by the
- * substring splitStr. An empty splitStr causes the whole str to be
- * iterated once.
- *
- * Note: Non-destructive modification of str from within the cb function
- * while performing this split is not undefined. bsplitstrcb behaves in
- * sequential lock step with calls to cb. I.e., after returning from a cb
- * that return a non-negative integer, bsplitscb continues from the position
- * 1 character after the last detected split character and it will halt
- * immediately if the length of str falls below this point. However, if the
- * cb function destroys str, then it *must* return with a negative value,
- * otherwise bsplitscb will continue in an undefined manner.
- */
-int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
- int (* cb) (void * parm, int ofs, int len), void * parm) {
-int i, p, ret;
-
- if (cb == NULL || str == NULL || pos < 0 || pos > str->slen
- || splitStr == NULL || splitStr->slen < 0) return BSTR_ERR;
-
- if (0 == splitStr->slen) {
- for (i=pos; i < str->slen; i++) {
- if ((ret = cb (parm, i, 1)) < 0) return ret;
- }
- return BSTR_OK;
- }
-
- if (splitStr->slen == 1)
- return bsplitcb (str, splitStr->data[0], pos, cb, parm);
-
- for (i=p=pos; i <= str->slen - splitStr->slen; i++) {
- if (0 == bstr__memcmp (splitStr->data, str->data + i, splitStr->slen)) {
- if ((ret = cb (parm, p, i - p)) < 0) return ret;
- i += splitStr->slen;
- p = i;
- }
- }
- if ((ret = cb (parm, p, str->slen - p)) < 0) return ret;
- return BSTR_OK;
-}
-
-struct genBstrList {
- bstring b;
- struct bstrList * bl;
-};
-
-static int bscb (void * parm, int ofs, int len) {
-struct genBstrList * g = (struct genBstrList *) parm;
- if (g->bl->qty >= g->bl->mlen) {
- int mlen = g->bl->mlen * 2;
- bstring * tbl;
-
- while (g->bl->qty >= mlen) {
- if (mlen < g->bl->mlen) return BSTR_ERR;
- mlen += mlen;
- }
-
- tbl = (bstring *) bstr__realloc (g->bl->entry, sizeof (bstring) * mlen);
- if (tbl == NULL) return BSTR_ERR;
-
- g->bl->entry = tbl;
- g->bl->mlen = mlen;
- }
-
- g->bl->entry[g->bl->qty] = bmidstr (g->b, ofs, len);
- g->bl->qty++;
- return BSTR_OK;
-}
-
-/* struct bstrList * bsplit (const_bstring str, unsigned char splitChar)
- *
- * Create an array of sequential substrings from str divided by the character
- * splitChar.
- */
-struct bstrList * bsplit (const_bstring str, unsigned char splitChar) {
-struct genBstrList g;
-
- if (str == NULL || str->data == NULL || str->slen < 0) return NULL;
-
- g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
- if (g.bl == NULL) return NULL;
- g.bl->mlen = 4;
- g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring));
- if (NULL == g.bl->entry) {
- bstr__free (g.bl);
- return NULL;
- }
-
- g.b = (bstring) str;
- g.bl->qty = 0;
- if (bsplitcb (str, splitChar, 0, bscb, &g) < 0) {
- bstrListDestroy (g.bl);
- return NULL;
- }
- return g.bl;
-}
-
-/* struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr)
- *
- * Create an array of sequential substrings from str divided by the entire
- * substring splitStr.
- */
-struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr) {
-struct genBstrList g;
-
- if (str == NULL || str->data == NULL || str->slen < 0) return NULL;
-
- g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
- if (g.bl == NULL) return NULL;
- g.bl->mlen = 4;
- g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring));
- if (NULL == g.bl->entry) {
- bstr__free (g.bl);
- return NULL;
- }
-
- g.b = (bstring) str;
- g.bl->qty = 0;
- if (bsplitstrcb (str, splitStr, 0, bscb, &g) < 0) {
- bstrListDestroy (g.bl);
- return NULL;
- }
- return g.bl;
-}
-
-/* struct bstrList * bsplits (const_bstring str, bstring splitStr)
- *
- * Create an array of sequential substrings from str divided by any of the
- * characters in splitStr. An empty splitStr causes a single entry bstrList
- * containing a copy of str to be returned.
- */
-struct bstrList * bsplits (const_bstring str, const_bstring splitStr) {
-struct genBstrList g;
-
- if ( str == NULL || str->slen < 0 || str->data == NULL ||
- splitStr == NULL || splitStr->slen < 0 || splitStr->data == NULL)
- return NULL;
-
- g.bl = (struct bstrList *) bstr__alloc (sizeof (struct bstrList));
- if (g.bl == NULL) return NULL;
- g.bl->mlen = 4;
- g.bl->entry = (bstring *) bstr__alloc (g.bl->mlen * sizeof (bstring));
- if (NULL == g.bl->entry) {
- bstr__free (g.bl);
- return NULL;
- }
- g.b = (bstring) str;
- g.bl->qty = 0;
-
- if (bsplitscb (str, splitStr, 0, bscb, &g) < 0) {
- bstrListDestroy (g.bl);
- return NULL;
- }
- return g.bl;
-}
-
-#if defined (__TURBOC__) && !defined (__BORLANDC__)
-# ifndef BSTRLIB_NOVSNP
-# define BSTRLIB_NOVSNP
-# endif
-#endif
-
-/* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */
-#if defined(__WATCOMC__) || defined(_MSC_VER)
-#define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);}
-#else
-#ifdef BSTRLIB_NOVSNP
-/* This is just a hack. If you are using a system without a vsnprintf, it is
- not recommended that bformat be used at all. */
-#define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;}
-#define START_VSNBUFF (256)
-#else
-
-#if defined(__GNUC__) && !defined(__APPLE__)
-/* Something is making gcc complain about this prototype not being here, so
- I've just gone ahead and put it in. */
-extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg);
-#endif
-
-#define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);}
-#endif
-#endif
-
-#if !defined (BSTRLIB_NOVSNP)
-
-#ifndef START_VSNBUFF
-#define START_VSNBUFF (16)
-#endif
-
-/* On IRIX vsnprintf returns n-1 when the operation would overflow the target
- buffer, WATCOM and MSVC both return -1, while C99 requires that the
- returned value be exactly what the length would be if the buffer would be
- large enough. This leads to the idea that if the return value is larger
- than n, then changing n to the return value will reduce the number of
- iterations required. */
-
-/* int bformata (bstring b, const char * fmt, ...)
- *
- * After the first parameter, it takes the same parameters as printf (), but
- * rather than outputting results to stdio, it appends the results to
- * a bstring which contains what would have been output. Note that if there
- * is an early generation of a '\0' character, the bstring will be truncated
- * to this end point.
- */
-int bformata (bstring b, const char * fmt, ...) {
-va_list arglist;
-bstring buff;
-int n, r;
-
- if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0
- || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR;
-
- /* Since the length is not determinable beforehand, a search is
- performed using the truncating "vsnprintf" call (to avoid buffer
- overflows) on increasing potential sizes for the output result. */
-
- if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
- if (NULL == (buff = bfromcstralloc (n + 2, ""))) {
- n = 1;
- if (NULL == (buff = bfromcstralloc (n + 2, ""))) return BSTR_ERR;
- }
-
- for (;;) {
- va_start (arglist, fmt);
- exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist);
- va_end (arglist);
-
- buff->data[n] = (unsigned char) '\0';
- buff->slen = (int) (strlen) ((char *) buff->data);
-
- if (buff->slen < n) break;
-
- if (r > n) n = r; else n += n;
-
- if (BSTR_OK != balloc (buff, n + 2)) {
- bdestroy (buff);
- return BSTR_ERR;
- }
- }
-
- r = bconcat (b, buff);
- bdestroy (buff);
- return r;
-}
-
-/* int bassignformat (bstring b, const char * fmt, ...)
- *
- * After the first parameter, it takes the same parameters as printf (), but
- * rather than outputting results to stdio, it outputs the results to
- * the bstring parameter b. Note that if there is an early generation of a
- * '\0' character, the bstring will be truncated to this end point.
- */
-int bassignformat (bstring b, const char * fmt, ...) {
-va_list arglist;
-bstring buff;
-int n, r;
-
- if (b == NULL || fmt == NULL || b->data == NULL || b->mlen <= 0
- || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR;
-
- /* Since the length is not determinable beforehand, a search is
- performed using the truncating "vsnprintf" call (to avoid buffer
- overflows) on increasing potential sizes for the output result. */
-
- if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
- if (NULL == (buff = bfromcstralloc (n + 2, ""))) {
- n = 1;
- if (NULL == (buff = bfromcstralloc (n + 2, ""))) return BSTR_ERR;
- }
-
- for (;;) {
- va_start (arglist, fmt);
- exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist);
- va_end (arglist);
-
- buff->data[n] = (unsigned char) '\0';
- buff->slen = (int) (strlen) ((char *) buff->data);
-
- if (buff->slen < n) break;
-
- if (r > n) n = r; else n += n;
-
- if (BSTR_OK != balloc (buff, n + 2)) {
- bdestroy (buff);
- return BSTR_ERR;
- }
- }
-
- r = bassign (b, buff);
- bdestroy (buff);
- return r;
-}
-
-/* bstring bformat (const char * fmt, ...)
- *
- * Takes the same parameters as printf (), but rather than outputting results
- * to stdio, it forms a bstring which contains what would have been output.
- * Note that if there is an early generation of a '\0' character, the
- * bstring will be truncated to this end point.
- */
-bstring bformat (const char * fmt, ...) {
-va_list arglist;
-bstring buff;
-int n, r;
-
- if (fmt == NULL) return NULL;
-
- /* Since the length is not determinable beforehand, a search is
- performed using the truncating "vsnprintf" call (to avoid buffer
- overflows) on increasing potential sizes for the output result. */
-
- if ((n = (int) (2*strlen (fmt))) < START_VSNBUFF) n = START_VSNBUFF;
- if (NULL == (buff = bfromcstralloc (n + 2, ""))) {
- n = 1;
- if (NULL == (buff = bfromcstralloc (n + 2, ""))) return NULL;
- }
-
- for (;;) {
- va_start (arglist, fmt);
- exvsnprintf (r, (char *) buff->data, n + 1, fmt, arglist);
- va_end (arglist);
-
- buff->data[n] = (unsigned char) '\0';
- buff->slen = (int) (strlen) ((char *) buff->data);
-
- if (buff->slen < n) break;
-
- if (r > n) n = r; else n += n;
-
- if (BSTR_OK != balloc (buff, n + 2)) {
- bdestroy (buff);
- return NULL;
- }
- }
-
- return buff;
-}
-
-/* int bvcformata (bstring b, int count, const char * fmt, va_list arglist)
- *
- * The bvcformata function formats data under control of the format control
- * string fmt and attempts to append the result to b. The fmt parameter is
- * the same as that of the printf function. The variable argument list is
- * replaced with arglist, which has been initialized by the va_start macro.
- * The size of the appended output is upper bounded by count. If the
- * required output exceeds count, the string b is not augmented with any
- * contents and a value below BSTR_ERR is returned. If a value below -count
- * is returned then it is recommended that the negative of this value be
- * used as an update to the count in a subsequent pass. On other errors,
- * such as running out of memory, parameter errors or numeric wrap around
- * BSTR_ERR is returned. BSTR_OK is returned when the output is successfully
- * generated and appended to b.
- *
- * Note: There is no sanity checking of arglist, and this function is
- * destructive of the contents of b from the b->slen point onward. If there
- * is an early generation of a '\0' character, the bstring will be truncated
- * to this end point.
- */
-int bvcformata (bstring b, int count, const char * fmt, va_list arg) {
-int n, r, l;
-
- if (b == NULL || fmt == NULL || count <= 0 || b->data == NULL
- || b->mlen <= 0 || b->slen < 0 || b->slen > b->mlen) return BSTR_ERR;
-
- if (count > (n = b->slen + count) + 2) return BSTR_ERR;
- if (BSTR_OK != balloc (b, n + 2)) return BSTR_ERR;
-
- exvsnprintf (r, (char *) b->data + b->slen, count + 2, fmt, arg);
-
- /* Did the operation complete successfully within bounds? */
- for (l = b->slen; l <= n; l++) {
- if ('\0' == b->data[l]) {
- b->slen = l;
- return BSTR_OK;
- }
- }
-
- /* Abort, since the buffer was not large enough. The return value
- tries to help set what the retry length should be. */
-
- b->data[b->slen] = '\0';
- if (r > count + 1) { /* Does r specify a particular target length? */
- n = r;
- } else {
- n = count + count; /* If not, just double the size of count */
- if (count > n) n = INT_MAX;
- }
- n = -n;
-
- if (n > BSTR_ERR-1) n = BSTR_ERR-1;
- return n;
-}
-
-#endif
diff --git a/src/bstrlib.h b/src/bstrlib.h
deleted file mode 100644
index c8fa694..0000000
--- a/src/bstrlib.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * This source file is part of the bstring string library. This code was
- * written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
- * BSD open source license or GPL v2.0. Refer to the accompanying documentation
- * for details on usage and license.
- */
-
-/*
- * bstrlib.h
- *
- * This file is the header file for the core module for implementing the
- * bstring functions.
- */
-
-#ifndef BSTRLIB_INCLUDE
-#define BSTRLIB_INCLUDE
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include
-#include
-#include
-#include
-
-#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
-# if defined (__TURBOC__) && !defined (__BORLANDC__)
-# define BSTRLIB_NOVSNP
-# endif
-#endif
-
-#define BSTR_ERR (-1)
-#define BSTR_OK (0)
-#define BSTR_BS_BUFF_LENGTH_GET (0)
-
-typedef struct tagbstring * bstring;
-typedef const struct tagbstring * const_bstring;
-
-/* Copy functions */
-#define cstr2bstr bfromcstr
-extern bstring bfromcstr (const char * str);
-extern bstring bfromcstralloc (int mlen, const char * str);
-extern bstring blk2bstr (const void * blk, int len);
-extern char * bstr2cstr (const_bstring s, char z);
-extern int bcstrfree (char * s);
-extern bstring bstrcpy (const_bstring b1);
-extern int bassign (bstring a, const_bstring b);
-extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
-extern int bassigncstr (bstring a, const char * str);
-extern int bassignblk (bstring a, const void * s, int len);
-
-/* Destroy function */
-extern int bdestroy (bstring b);
-
-/* Space allocation hinting functions */
-extern int balloc (bstring s, int len);
-extern int ballocmin (bstring b, int len);
-
-/* Substring extraction */
-extern bstring bmidstr (const_bstring b, int left, int len);
-
-/* Various standard manipulations */
-extern int bconcat (bstring b0, const_bstring b1);
-extern int bconchar (bstring b0, char c);
-extern int bcatcstr (bstring b, const char * s);
-extern int bcatblk (bstring b, const void * s, int len);
-extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
-extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
-extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
-extern int bdelete (bstring s1, int pos, int len);
-extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
-extern int btrunc (bstring b, int n);
-
-/* Scan/search functions */
-extern int bstricmp (const_bstring b0, const_bstring b1);
-extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
-extern int biseqcaseless (const_bstring b0, const_bstring b1);
-extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
-extern int biseq (const_bstring b0, const_bstring b1);
-extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
-extern int biseqcstr (const_bstring b, const char * s);
-extern int biseqcstrcaseless (const_bstring b, const char * s);
-extern int bstrcmp (const_bstring b0, const_bstring b1);
-extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
-extern int binstr (const_bstring s1, int pos, const_bstring s2);
-extern int binstrr (const_bstring s1, int pos, const_bstring s2);
-extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
-extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
-extern int bstrchrp (const_bstring b, int c, int pos);
-extern int bstrrchrp (const_bstring b, int c, int pos);
-#define bstrchr(b,c) bstrchrp ((b), (c), 0)
-#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
-extern int binchr (const_bstring b0, int pos, const_bstring b1);
-extern int binchrr (const_bstring b0, int pos, const_bstring b1);
-extern int bninchr (const_bstring b0, int pos, const_bstring b1);
-extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
-extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
-extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
-
-/* List of string container functions */
-struct bstrList {
- int qty, mlen;
- bstring * entry;
-};
-extern struct bstrList * bstrListCreate (void);
-extern int bstrListDestroy (struct bstrList * sl);
-extern int bstrListAlloc (struct bstrList * sl, int msz);
-extern int bstrListAllocMin (struct bstrList * sl, int msz);
-
-/* String split and join functions */
-extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
-extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
-extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
-extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
-extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
- int (* cb) (void * parm, int ofs, int len), void * parm);
-extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
- int (* cb) (void * parm, int ofs, int len), void * parm);
-extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
- int (* cb) (void * parm, int ofs, int len), void * parm);
-
-/* Miscellaneous functions */
-extern int bpattern (bstring b, int len);
-extern int btoupper (bstring b);
-extern int btolower (bstring b);
-extern int bltrimws (bstring b);
-extern int brtrimws (bstring b);
-extern int btrimws (bstring b);
-
-/* <*>printf format functions */
-#if !defined (BSTRLIB_NOVSNP)
-extern bstring bformat (const char * fmt, ...);
-extern int bformata (bstring b, const char * fmt, ...);
-extern int bassignformat (bstring b, const char * fmt, ...);
-extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
-
-#define bvformata(ret, b, fmt, lastarg) { \
-bstring bstrtmp_b = (b); \
-const char * bstrtmp_fmt = (fmt); \
-int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
- for (;;) { \
- va_list bstrtmp_arglist; \
- va_start (bstrtmp_arglist, lastarg); \
- bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
- va_end (bstrtmp_arglist); \
- if (bstrtmp_r >= 0) { /* Everything went ok */ \
- bstrtmp_r = BSTR_OK; \
- break; \
- } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
- bstrtmp_r = BSTR_ERR; \
- break; \
- } \
- bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
- } \
- ret = bstrtmp_r; \
-}
-
-#endif
-
-typedef int (*bNgetc) (void *parm);
-typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
-
-/* Input functions */
-extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
-extern bstring bread (bNread readPtr, void * parm);
-extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
-extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
-extern int breada (bstring b, bNread readPtr, void * parm);
-
-/* Stream functions */
-extern struct bStream * bsopen (bNread readPtr, void * parm);
-extern void * bsclose (struct bStream * s);
-extern int bsbufflength (struct bStream * s, int sz);
-extern int bsreadln (bstring b, struct bStream * s, char terminator);
-extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
-extern int bsread (bstring b, struct bStream * s, int n);
-extern int bsreadlna (bstring b, struct bStream * s, char terminator);
-extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
-extern int bsreada (bstring b, struct bStream * s, int n);
-extern int bsunread (struct bStream * s, const_bstring b);
-extern int bspeek (bstring r, const struct bStream * s);
-extern int bssplitscb (struct bStream * s, const_bstring splitStr,
- int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
-extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
- int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
-extern int bseof (const struct bStream * s);
-
-struct tagbstring {
- int mlen;
- int slen;
- unsigned char * data;
-};
-
-/* Accessor macros */
-#define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
-#define blength(b) (blengthe ((b), 0))
-#define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
-#define bdataofs(b, o) (bdataofse ((b), (o), (void *)0))
-#define bdatae(b, e) (bdataofse (b, 0, e))
-#define bdata(b) (bdataofs (b, 0))
-#define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
-#define bchar(b, p) bchare ((b), (p), '\0')
-
-/* Static constant string initialization macro */
-#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
-#if defined(_MSC_VER)
-/* There are many versions of MSVC which emit __LINE__ as a non-constant. */
-# define bsStatic(q) bsStaticMlen(q,-32)
-#endif
-#ifndef bsStatic
-# define bsStatic(q) bsStaticMlen(q,-__LINE__)
-#endif
-
-/* Static constant block parameter pair */
-#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
-
-/* Reference building macros */
-#define cstr2tbstr btfromcstr
-#define btfromcstr(t,s) { \
- (t).data = (unsigned char *) (s); \
- (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
- (t).mlen = -1; \
-}
-#define blk2tbstr(t,s,l) { \
- (t).data = (unsigned char *) (s); \
- (t).slen = l; \
- (t).mlen = -1; \
-}
-#define btfromblk(t,s,l) blk2tbstr(t,s,l)
-#define bmid2tbstr(t,b,p,l) { \
- const_bstring bstrtmp_s = (b); \
- if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
- int bstrtmp_left = (p); \
- int bstrtmp_len = (l); \
- if (bstrtmp_left < 0) { \
- bstrtmp_len += bstrtmp_left; \
- bstrtmp_left = 0; \
- } \
- if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \
- bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
- if (bstrtmp_len <= 0) { \
- (t).data = (unsigned char *)""; \
- (t).slen = 0; \
- } else { \
- (t).data = bstrtmp_s->data + bstrtmp_left; \
- (t).slen = bstrtmp_len; \
- } \
- } else { \
- (t).data = (unsigned char *)""; \
- (t).slen = 0; \
- } \
- (t).mlen = -__LINE__; \
-}
-#define btfromblkltrimws(t,s,l) { \
- int bstrtmp_idx = 0, bstrtmp_len = (l); \
- unsigned char * bstrtmp_s = (s); \
- if (bstrtmp_s && bstrtmp_len >= 0) { \
- for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
- if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
- } \
- } \
- (t).data = bstrtmp_s + bstrtmp_idx; \
- (t).slen = bstrtmp_len - bstrtmp_idx; \
- (t).mlen = -__LINE__; \
-}
-#define btfromblkrtrimws(t,s,l) { \
- int bstrtmp_len = (l) - 1; \
- unsigned char * bstrtmp_s = (s); \
- if (bstrtmp_s && bstrtmp_len >= 0) { \
- for (; bstrtmp_len >= 0; bstrtmp_len--) { \
- if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
- } \
- } \
- (t).data = bstrtmp_s; \
- (t).slen = bstrtmp_len + 1; \
- (t).mlen = -__LINE__; \
-}
-#define btfromblktrimws(t,s,l) { \
- int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
- unsigned char * bstrtmp_s = (s); \
- if (bstrtmp_s && bstrtmp_len >= 0) { \
- for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
- if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
- } \
- for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
- if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
- } \
- } \
- (t).data = bstrtmp_s + bstrtmp_idx; \
- (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
- (t).mlen = -__LINE__; \
-}
-
-/* Write protection macros */
-#define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; }
-#define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
-#define biswriteprotected(t) ((t).mlen <= 0)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/buffer.c b/src/buffer.c
new file mode 100644
index 0000000..b81e7fa
--- /dev/null
+++ b/src/buffer.c
@@ -0,0 +1,313 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "buffer.h"
+
+/* Used as default value for gh_buf->ptr so that people can always
+ * assume ptr is non-NULL and zero terminated even for new gh_bufs.
+ */
+unsigned char gh_buf__initbuf[1];
+unsigned char gh_buf__oom[1];
+
+#define ENSURE_SIZE(b, d) \
+ if ((d) > buf->asize && gh_buf_grow(b, (d)) < 0)\
+ return -1;
+
+void gh_buf_init(gh_buf *buf, int initial_size)
+{
+ buf->asize = 0;
+ buf->size = 0;
+ buf->ptr = gh_buf__initbuf;
+
+ if (initial_size)
+ gh_buf_grow(buf, initial_size);
+}
+
+int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom)
+{
+ char *new_ptr;
+ size_t new_size;
+
+ if (buf->ptr == gh_buf__oom || buf->asize < 0)
+ return -1;
+
+ if (target_size <= buf->asize)
+ return 0;
+
+ if (buf->asize == 0) {
+ new_size = target_size;
+ new_ptr = NULL;
+ } else {
+ new_size = buf->asize;
+ new_ptr = buf->ptr;
+ }
+
+ /* grow the buffer size by 1.5, until it's big enough
+ * to fit our target size */
+ while (new_size < target_size)
+ new_size = (new_size << 1) - (new_size >> 1);
+
+ /* round allocation up to multiple of 8 */
+ new_size = (new_size + 7) & ~7;
+
+ new_ptr = realloc(new_ptr, new_size);
+
+ if (!new_ptr) {
+ if (mark_oom)
+ buf->ptr = gh_buf__oom;
+ return -1;
+ }
+
+ buf->asize = new_size;
+ buf->ptr = new_ptr;
+
+ /* truncate the existing buffer size if necessary */
+ if (buf->size >= buf->asize)
+ buf->size = buf->asize - 1;
+ buf->ptr[buf->size] = '\0';
+
+ return 0;
+}
+
+void gh_buf_free(gh_buf *buf)
+{
+ if (!buf) return;
+
+ if (buf->asize > 0 && buf->ptr != gh_buf__initbuf && buf->ptr != gh_buf__oom)
+ free(buf->ptr);
+
+ gh_buf_init(buf, 0);
+}
+
+void gh_buf_clear(gh_buf *buf)
+{
+ buf->size = 0;
+
+ if (buf->asize > 0)
+ buf->ptr[0] = '\0';
+
+ if (buf->asize < 0) {
+ buf->ptr = gh_buf__initbuf;
+ buf->asize = 0;
+ }
+}
+
+int gh_buf_set(gh_buf *buf, const char *data, int len)
+{
+ if (len == 0 || data == NULL) {
+ gh_buf_clear(buf);
+ } else {
+ if (data != buf->ptr) {
+ ENSURE_SIZE(buf, len + 1);
+ memmove(buf->ptr, data, len);
+ }
+ buf->size = len;
+ buf->ptr[buf->size] = '\0';
+ }
+ return 0;
+}
+
+int gh_buf_sets(gh_buf *buf, const char *string)
+{
+ return gh_buf_set(buf, string, string ? strlen(string) : 0);
+}
+
+int gh_buf_putc(gh_buf *buf, char c)
+{
+ ENSURE_SIZE(buf, buf->size + 2);
+ buf->ptr[buf->size++] = c;
+ buf->ptr[buf->size] = '\0';
+ return 0;
+}
+
+int gh_buf_put(gh_buf *buf, const char *data, int len)
+{
+ ENSURE_SIZE(buf, buf->size + len + 1);
+ memmove(buf->ptr + buf->size, data, len);
+ buf->size += len;
+ buf->ptr[buf->size] = '\0';
+ return 0;
+}
+
+int gh_buf_puts(gh_buf *buf, const char *string)
+{
+ assert(string);
+ return gh_buf_put(buf, string, strlen(string));
+}
+
+int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap)
+{
+ const int expected_size = buf->size + (strlen(format) * 2);
+ int len;
+
+ ENSURE_SIZE(buf, expected_size);
+
+ while (1) {
+ va_list args;
+ va_copy(args, ap);
+
+ len = vsnprintf(
+ buf->ptr + buf->size,
+ buf->asize - buf->size,
+ format, args
+ );
+
+ if (len < 0) {
+ free(buf->ptr);
+ buf->ptr = gh_buf__oom;
+ return -1;
+ }
+
+ if (len + 1 <= buf->asize - buf->size) {
+ buf->size += len;
+ break;
+ }
+
+ ENSURE_SIZE(buf, buf->size + len + 1);
+ }
+
+ return 0;
+}
+
+int gh_buf_printf(gh_buf *buf, const char *format, ...)
+{
+ int r;
+ va_list ap;
+
+ va_start(ap, format);
+ r = gh_buf_vprintf(buf, format, ap);
+ va_end(ap);
+
+ return r;
+}
+
+void gh_buf_copy_cstr(char *data, size_t datasize, const gh_buf *buf)
+{
+ size_t copylen;
+
+ assert(data && datasize && buf);
+
+ data[0] = '\0';
+
+ if (buf->size == 0 || buf->asize <= 0)
+ return;
+
+ copylen = buf->size;
+ if (copylen > datasize - 1)
+ copylen = datasize - 1;
+ memmove(data, buf->ptr, copylen);
+ data[copylen] = '\0';
+}
+
+void gh_buf_swap(gh_buf *buf_a, gh_buf *buf_b)
+{
+ gh_buf t = *buf_a;
+ *buf_a = *buf_b;
+ *buf_b = t;
+}
+
+char *gh_buf_detach(gh_buf *buf)
+{
+ char *data = buf->ptr;
+
+ if (buf->asize == 0 || buf->ptr == gh_buf__oom)
+ return NULL;
+
+ gh_buf_init(buf, 0);
+
+ return data;
+}
+
+void gh_buf_attach(gh_buf *buf, char *ptr, int asize)
+{
+ gh_buf_free(buf);
+
+ if (ptr) {
+ buf->ptr = ptr;
+ buf->size = strlen(ptr);
+ if (asize)
+ buf->asize = (asize < buf->size) ? buf->size + 1 : asize;
+ else /* pass 0 to fall back on strlen + 1 */
+ buf->asize = buf->size + 1;
+ } else {
+ gh_buf_grow(buf, asize);
+ }
+}
+
+int gh_buf_cmp(const gh_buf *a, const gh_buf *b)
+{
+ int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size));
+ return (result != 0) ? result :
+ (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
+}
+
+int gh_buf_strchr(const gh_buf *buf, int c, int pos)
+{
+ const char *p = memchr(buf->ptr + pos, c, buf->size - pos);
+ if (!p)
+ return -1;
+
+ return (int)(p - p->ptr);
+}
+
+int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
+{
+ int i;
+
+ for (i = pos; i >= 0; i--) {
+ if (buf->ptr[i] == (unsigned char) c)
+ return i;
+ }
+
+ return -1;
+}
+
+void gh_buf_truncate(gh_buf *buf, size_t len)
+{
+ assert(buf->asize >= 0);
+
+ if (len < buf->size) {
+ buf->size = len;
+ buf->ptr[buf->size] = '\0';
+ }
+}
+
+void gh_buf_ltruncate(gh_buf *buf, size_t len)
+{
+ assert(buf->asize >= 0);
+
+ if (len && len < buf->size) {
+ memmove(buf->ptr, buf->ptr + len, buf->size - len);
+ buf->size -= len;
+ buf->ptr[buf->size] = '\0';
+ }
+}
+
+void gh_buf_trim(gh_buf *buf)
+{
+ size_t i = 0;
+
+ assert(buf->asize >= 0);
+
+ /* ltrim */
+ while (i < buf->size && isspace(buf->ptr[i]))
+ i++;
+
+ gh_buf_truncate(buf, i);
+
+ /* rtrim */
+ while (buf->size > 0) {
+ if (!isspace(buf->ptr[buf->size - 1]))
+ break;
+
+ buf->size--;
+ }
+
+ buf->ptr[buf->size] = '\0';
+}
diff --git a/src/buffer.h b/src/buffer.h
new file mode 100644
index 0000000..2581ee3
--- /dev/null
+++ b/src/buffer.h
@@ -0,0 +1,119 @@
+#ifndef INCLUDE_buffer_h__
+#define INCLUDE_buffer_h__
+
+#include
+#include
+#include
+#include
+
+typedef struct {
+ unsigned char *ptr;
+ int asize, size;
+} gh_buf;
+
+extern unsigned char gh_buf__initbuf[];
+extern unsigned char gh_buf__oom[];
+
+#define GH_BUF_INIT { gh_buf__initbuf, 0, 0 }
+
+/**
+ * Initialize a gh_buf structure.
+ *
+ * For the cases where GH_BUF_INIT cannot be used to do static
+ * initialization.
+ */
+extern void gh_buf_init(gh_buf *buf, int initial_size);
+
+static inline void gh_buf_static(gh_buf *buf, unsigned char *source)
+{
+ buf->ptr = source;
+ buf->size = strlen(source);
+ buf->asize = -1;
+}
+
+/**
+ * Attempt to grow the buffer to hold at least `target_size` bytes.
+ *
+ * If the allocation fails, this will return an error. If mark_oom is true,
+ * this will mark the buffer as invalid for future operations; if false,
+ * existing buffer content will be preserved, but calling code must handle
+ * that buffer was not expanded.
+ */
+extern int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom);
+
+/**
+ * Grow the buffer to hold at least `target_size` bytes.
+ *
+ * If the allocation fails, this will return an error and the buffer will be
+ * marked as invalid for future operations, invaliding contents.
+ *
+ * @return 0 on success or -1 on failure
+ */
+static inline int gh_buf_grow(gh_buf *buf, int target_size)
+{
+ return gh_buf_try_grow(buf, target_size, true);
+}
+
+extern void gh_buf_free(gh_buf *buf);
+extern void gh_buf_swap(gh_buf *buf_a, gh_buf *buf_b);
+
+/**
+ * Test if there have been any reallocation failures with this gh_buf.
+ *
+ * Any function that writes to a gh_buf can fail due to memory allocation
+ * issues. If one fails, the gh_buf will be marked with an OOM error and
+ * further calls to modify the buffer will fail. Check gh_buf_oom() at the
+ * end of your sequence and it will be true if you ran out of memory at any
+ * point with that buffer.
+ *
+ * @return false if no error, true if allocation error
+ */
+static inline bool gh_buf_oom(const gh_buf *buf)
+{
+ return (buf->ptr == gh_buf__oom);
+}
+
+
+static inline size_t gh_buf_len(const gh_buf *buf)
+{
+ return buf->size;
+}
+
+extern int gh_buf_cmp(const gh_buf *a, const gh_buf *b);
+
+extern void gh_buf_attach(gh_buf *buf, char *ptr, int asize);
+extern char *gh_buf_detach(gh_buf *buf);
+extern void gh_buf_copy_cstr(char *data, int datasize, const gh_buf *buf);
+
+static inline const char *gh_buf_cstr(const gh_buf *buf)
+{
+ return buf->ptr;
+}
+
+#define gh_buf_at(buf, n) ((buf)->ptr[n])
+
+/*
+ * Functions below that return int value error codes will return 0 on
+ * success or -1 on failure (which generally means an allocation failed).
+ * Using a gh_buf where the allocation has failed with result in -1 from
+ * all further calls using that buffer. As a result, you can ignore the
+ * return code of these functions and call them in a series then just call
+ * gh_buf_oom at the end.
+ */
+extern int gh_buf_set(gh_buf *buf, const char *data, int len);
+extern int gh_buf_sets(gh_buf *buf, const char *string);
+extern int gh_buf_putc(gh_buf *buf, char c);
+extern int gh_buf_put(gh_buf *buf, const char *data, int len);
+extern int gh_buf_puts(gh_buf *buf, const char *string);
+extern int gh_buf_printf(gh_buf *buf, const char *format, ...)
+ __attribute__((format (printf, 2, 3)));
+extern int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap);
+extern void gh_buf_clear(gh_buf *buf);
+
+int gh_buf_strchr(const gh_buf *buf, int c, int pos);
+int gh_buf_strrchr(const gh_buf *buf, int c, int pos);
+void gh_buf_truncate(gh_buf *buf, int len);
+void gh_buf_ltruncate(gh_buf *buf, int len);
+void gh_buf_trim(gh_buf *buf);
+
+#endif
diff --git a/src/case_fold_switch.c b/src/case_fold_switch.c
deleted file mode 100644
index 70fdd75..0000000
--- a/src/case_fold_switch.c
+++ /dev/null
@@ -1,2637 +0,0 @@
- switch (c) {
- case 0x0041:
- bufpush(0x0061);
- break;
- case 0x0042:
- bufpush(0x0062);
- break;
- case 0x0043:
- bufpush(0x0063);
- break;
- case 0x0044:
- bufpush(0x0064);
- break;
- case 0x0045:
- bufpush(0x0065);
- break;
- case 0x0046:
- bufpush(0x0066);
- break;
- case 0x0047:
- bufpush(0x0067);
- break;
- case 0x0048:
- bufpush(0x0068);
- break;
- case 0x0049:
- bufpush(0x0069);
- break;
- case 0x004A:
- bufpush(0x006A);
- break;
- case 0x004B:
- bufpush(0x006B);
- break;
- case 0x004C:
- bufpush(0x006C);
- break;
- case 0x004D:
- bufpush(0x006D);
- break;
- case 0x004E:
- bufpush(0x006E);
- break;
- case 0x004F:
- bufpush(0x006F);
- break;
- case 0x0050:
- bufpush(0x0070);
- break;
- case 0x0051:
- bufpush(0x0071);
- break;
- case 0x0052:
- bufpush(0x0072);
- break;
- case 0x0053:
- bufpush(0x0073);
- break;
- case 0x0054:
- bufpush(0x0074);
- break;
- case 0x0055:
- bufpush(0x0075);
- break;
- case 0x0056:
- bufpush(0x0076);
- break;
- case 0x0057:
- bufpush(0x0077);
- break;
- case 0x0058:
- bufpush(0x0078);
- break;
- case 0x0059:
- bufpush(0x0079);
- break;
- case 0x005A:
- bufpush(0x007A);
- break;
- case 0x00B5:
- bufpush(0x03BC);
- break;
- case 0x00C0:
- bufpush(0x00E0);
- break;
- case 0x00C1:
- bufpush(0x00E1);
- break;
- case 0x00C2:
- bufpush(0x00E2);
- break;
- case 0x00C3:
- bufpush(0x00E3);
- break;
- case 0x00C4:
- bufpush(0x00E4);
- break;
- case 0x00C5:
- bufpush(0x00E5);
- break;
- case 0x00C6:
- bufpush(0x00E6);
- break;
- case 0x00C7:
- bufpush(0x00E7);
- break;
- case 0x00C8:
- bufpush(0x00E8);
- break;
- case 0x00C9:
- bufpush(0x00E9);
- break;
- case 0x00CA:
- bufpush(0x00EA);
- break;
- case 0x00CB:
- bufpush(0x00EB);
- break;
- case 0x00CC:
- bufpush(0x00EC);
- break;
- case 0x00CD:
- bufpush(0x00ED);
- break;
- case 0x00CE:
- bufpush(0x00EE);
- break;
- case 0x00CF:
- bufpush(0x00EF);
- break;
- case 0x00D0:
- bufpush(0x00F0);
- break;
- case 0x00D1:
- bufpush(0x00F1);
- break;
- case 0x00D2:
- bufpush(0x00F2);
- break;
- case 0x00D3:
- bufpush(0x00F3);
- break;
- case 0x00D4:
- bufpush(0x00F4);
- break;
- case 0x00D5:
- bufpush(0x00F5);
- break;
- case 0x00D6:
- bufpush(0x00F6);
- break;
- case 0x00D8:
- bufpush(0x00F8);
- break;
- case 0x00D9:
- bufpush(0x00F9);
- break;
- case 0x00DA:
- bufpush(0x00FA);
- break;
- case 0x00DB:
- bufpush(0x00FB);
- break;
- case 0x00DC:
- bufpush(0x00FC);
- break;
- case 0x00DD:
- bufpush(0x00FD);
- break;
- case 0x00DE:
- bufpush(0x00FE);
- break;
- case 0x00DF:
- bufpush(0x0073);
- bufpush(0x0073);
- break;
- case 0x0100:
- bufpush(0x0101);
- break;
- case 0x0102:
- bufpush(0x0103);
- break;
- case 0x0104:
- bufpush(0x0105);
- break;
- case 0x0106:
- bufpush(0x0107);
- break;
- case 0x0108:
- bufpush(0x0109);
- break;
- case 0x010A:
- bufpush(0x010B);
- break;
- case 0x010C:
- bufpush(0x010D);
- break;
- case 0x010E:
- bufpush(0x010F);
- break;
- case 0x0110:
- bufpush(0x0111);
- break;
- case 0x0112:
- bufpush(0x0113);
- break;
- case 0x0114:
- bufpush(0x0115);
- break;
- case 0x0116:
- bufpush(0x0117);
- break;
- case 0x0118:
- bufpush(0x0119);
- break;
- case 0x011A:
- bufpush(0x011B);
- break;
- case 0x011C:
- bufpush(0x011D);
- break;
- case 0x011E:
- bufpush(0x011F);
- break;
- case 0x0120:
- bufpush(0x0121);
- break;
- case 0x0122:
- bufpush(0x0123);
- break;
- case 0x0124:
- bufpush(0x0125);
- break;
- case 0x0126:
- bufpush(0x0127);
- break;
- case 0x0128:
- bufpush(0x0129);
- break;
- case 0x012A:
- bufpush(0x012B);
- break;
- case 0x012C:
- bufpush(0x012D);
- break;
- case 0x012E:
- bufpush(0x012F);
- break;
- case 0x0130:
- bufpush(0x0069);
- bufpush(0x0307);
- break;
- case 0x0132:
- bufpush(0x0133);
- break;
- case 0x0134:
- bufpush(0x0135);
- break;
- case 0x0136:
- bufpush(0x0137);
- break;
- case 0x0139:
- bufpush(0x013A);
- break;
- case 0x013B:
- bufpush(0x013C);
- break;
- case 0x013D:
- bufpush(0x013E);
- break;
- case 0x013F:
- bufpush(0x0140);
- break;
- case 0x0141:
- bufpush(0x0142);
- break;
- case 0x0143:
- bufpush(0x0144);
- break;
- case 0x0145:
- bufpush(0x0146);
- break;
- case 0x0147:
- bufpush(0x0148);
- break;
- case 0x0149:
- bufpush(0x02BC);
- bufpush(0x006E);
- break;
- case 0x014A:
- bufpush(0x014B);
- break;
- case 0x014C:
- bufpush(0x014D);
- break;
- case 0x014E:
- bufpush(0x014F);
- break;
- case 0x0150:
- bufpush(0x0151);
- break;
- case 0x0152:
- bufpush(0x0153);
- break;
- case 0x0154:
- bufpush(0x0155);
- break;
- case 0x0156:
- bufpush(0x0157);
- break;
- case 0x0158:
- bufpush(0x0159);
- break;
- case 0x015A:
- bufpush(0x015B);
- break;
- case 0x015C:
- bufpush(0x015D);
- break;
- case 0x015E:
- bufpush(0x015F);
- break;
- case 0x0160:
- bufpush(0x0161);
- break;
- case 0x0162:
- bufpush(0x0163);
- break;
- case 0x0164:
- bufpush(0x0165);
- break;
- case 0x0166:
- bufpush(0x0167);
- break;
- case 0x0168:
- bufpush(0x0169);
- break;
- case 0x016A:
- bufpush(0x016B);
- break;
- case 0x016C:
- bufpush(0x016D);
- break;
- case 0x016E:
- bufpush(0x016F);
- break;
- case 0x0170:
- bufpush(0x0171);
- break;
- case 0x0172:
- bufpush(0x0173);
- break;
- case 0x0174:
- bufpush(0x0175);
- break;
- case 0x0176:
- bufpush(0x0177);
- break;
- case 0x0178:
- bufpush(0x00FF);
- break;
- case 0x0179:
- bufpush(0x017A);
- break;
- case 0x017B:
- bufpush(0x017C);
- break;
- case 0x017D:
- bufpush(0x017E);
- break;
- case 0x017F:
- bufpush(0x0073);
- break;
- case 0x0181:
- bufpush(0x0253);
- break;
- case 0x0182:
- bufpush(0x0183);
- break;
- case 0x0184:
- bufpush(0x0185);
- break;
- case 0x0186:
- bufpush(0x0254);
- break;
- case 0x0187:
- bufpush(0x0188);
- break;
- case 0x0189:
- bufpush(0x0256);
- break;
- case 0x018A:
- bufpush(0x0257);
- break;
- case 0x018B:
- bufpush(0x018C);
- break;
- case 0x018E:
- bufpush(0x01DD);
- break;
- case 0x018F:
- bufpush(0x0259);
- break;
- case 0x0190:
- bufpush(0x025B);
- break;
- case 0x0191:
- bufpush(0x0192);
- break;
- case 0x0193:
- bufpush(0x0260);
- break;
- case 0x0194:
- bufpush(0x0263);
- break;
- case 0x0196:
- bufpush(0x0269);
- break;
- case 0x0197:
- bufpush(0x0268);
- break;
- case 0x0198:
- bufpush(0x0199);
- break;
- case 0x019C:
- bufpush(0x026F);
- break;
- case 0x019D:
- bufpush(0x0272);
- break;
- case 0x019F:
- bufpush(0x0275);
- break;
- case 0x01A0:
- bufpush(0x01A1);
- break;
- case 0x01A2:
- bufpush(0x01A3);
- break;
- case 0x01A4:
- bufpush(0x01A5);
- break;
- case 0x01A6:
- bufpush(0x0280);
- break;
- case 0x01A7:
- bufpush(0x01A8);
- break;
- case 0x01A9:
- bufpush(0x0283);
- break;
- case 0x01AC:
- bufpush(0x01AD);
- break;
- case 0x01AE:
- bufpush(0x0288);
- break;
- case 0x01AF:
- bufpush(0x01B0);
- break;
- case 0x01B1:
- bufpush(0x028A);
- break;
- case 0x01B2:
- bufpush(0x028B);
- break;
- case 0x01B3:
- bufpush(0x01B4);
- break;
- case 0x01B5:
- bufpush(0x01B6);
- break;
- case 0x01B7:
- bufpush(0x0292);
- break;
- case 0x01B8:
- bufpush(0x01B9);
- break;
- case 0x01BC:
- bufpush(0x01BD);
- break;
- case 0x01C4:
- bufpush(0x01C6);
- break;
- case 0x01C5:
- bufpush(0x01C6);
- break;
- case 0x01C7:
- bufpush(0x01C9);
- break;
- case 0x01C8:
- bufpush(0x01C9);
- break;
- case 0x01CA:
- bufpush(0x01CC);
- break;
- case 0x01CB:
- bufpush(0x01CC);
- break;
- case 0x01CD:
- bufpush(0x01CE);
- break;
- case 0x01CF:
- bufpush(0x01D0);
- break;
- case 0x01D1:
- bufpush(0x01D2);
- break;
- case 0x01D3:
- bufpush(0x01D4);
- break;
- case 0x01D5:
- bufpush(0x01D6);
- break;
- case 0x01D7:
- bufpush(0x01D8);
- break;
- case 0x01D9:
- bufpush(0x01DA);
- break;
- case 0x01DB:
- bufpush(0x01DC);
- break;
- case 0x01DE:
- bufpush(0x01DF);
- break;
- case 0x01E0:
- bufpush(0x01E1);
- break;
- case 0x01E2:
- bufpush(0x01E3);
- break;
- case 0x01E4:
- bufpush(0x01E5);
- break;
- case 0x01E6:
- bufpush(0x01E7);
- break;
- case 0x01E8:
- bufpush(0x01E9);
- break;
- case 0x01EA:
- bufpush(0x01EB);
- break;
- case 0x01EC:
- bufpush(0x01ED);
- break;
- case 0x01EE:
- bufpush(0x01EF);
- break;
- case 0x01F0:
- bufpush(0x006A);
- bufpush(0x030C);
- break;
- case 0x01F1:
- bufpush(0x01F3);
- break;
- case 0x01F2:
- bufpush(0x01F3);
- break;
- case 0x01F4:
- bufpush(0x01F5);
- break;
- case 0x01F6:
- bufpush(0x0195);
- break;
- case 0x01F7:
- bufpush(0x01BF);
- break;
- case 0x01F8:
- bufpush(0x01F9);
- break;
- case 0x01FA:
- bufpush(0x01FB);
- break;
- case 0x01FC:
- bufpush(0x01FD);
- break;
- case 0x01FE:
- bufpush(0x01FF);
- break;
- case 0x0200:
- bufpush(0x0201);
- break;
- case 0x0202:
- bufpush(0x0203);
- break;
- case 0x0204:
- bufpush(0x0205);
- break;
- case 0x0206:
- bufpush(0x0207);
- break;
- case 0x0208:
- bufpush(0x0209);
- break;
- case 0x020A:
- bufpush(0x020B);
- break;
- case 0x020C:
- bufpush(0x020D);
- break;
- case 0x020E:
- bufpush(0x020F);
- break;
- case 0x0210:
- bufpush(0x0211);
- break;
- case 0x0212:
- bufpush(0x0213);
- break;
- case 0x0214:
- bufpush(0x0215);
- break;
- case 0x0216:
- bufpush(0x0217);
- break;
- case 0x0218:
- bufpush(0x0219);
- break;
- case 0x021A:
- bufpush(0x021B);
- break;
- case 0x021C:
- bufpush(0x021D);
- break;
- case 0x021E:
- bufpush(0x021F);
- break;
- case 0x0220:
- bufpush(0x019E);
- break;
- case 0x0222:
- bufpush(0x0223);
- break;
- case 0x0224:
- bufpush(0x0225);
- break;
- case 0x0226:
- bufpush(0x0227);
- break;
- case 0x0228:
- bufpush(0x0229);
- break;
- case 0x022A:
- bufpush(0x022B);
- break;
- case 0x022C:
- bufpush(0x022D);
- break;
- case 0x022E:
- bufpush(0x022F);
- break;
- case 0x0230:
- bufpush(0x0231);
- break;
- case 0x0232:
- bufpush(0x0233);
- break;
- case 0x0345:
- bufpush(0x03B9);
- break;
- case 0x0386:
- bufpush(0x03AC);
- break;
- case 0x0388:
- bufpush(0x03AD);
- break;
- case 0x0389:
- bufpush(0x03AE);
- break;
- case 0x038A:
- bufpush(0x03AF);
- break;
- case 0x038C:
- bufpush(0x03CC);
- break;
- case 0x038E:
- bufpush(0x03CD);
- break;
- case 0x038F:
- bufpush(0x03CE);
- break;
- case 0x0390:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x0391:
- bufpush(0x03B1);
- break;
- case 0x0392:
- bufpush(0x03B2);
- break;
- case 0x0393:
- bufpush(0x03B3);
- break;
- case 0x0394:
- bufpush(0x03B4);
- break;
- case 0x0395:
- bufpush(0x03B5);
- break;
- case 0x0396:
- bufpush(0x03B6);
- break;
- case 0x0397:
- bufpush(0x03B7);
- break;
- case 0x0398:
- bufpush(0x03B8);
- break;
- case 0x0399:
- bufpush(0x03B9);
- break;
- case 0x039A:
- bufpush(0x03BA);
- break;
- case 0x039B:
- bufpush(0x03BB);
- break;
- case 0x039C:
- bufpush(0x03BC);
- break;
- case 0x039D:
- bufpush(0x03BD);
- break;
- case 0x039E:
- bufpush(0x03BE);
- break;
- case 0x039F:
- bufpush(0x03BF);
- break;
- case 0x03A0:
- bufpush(0x03C0);
- break;
- case 0x03A1:
- bufpush(0x03C1);
- break;
- case 0x03A3:
- bufpush(0x03C3);
- break;
- case 0x03A4:
- bufpush(0x03C4);
- break;
- case 0x03A5:
- bufpush(0x03C5);
- break;
- case 0x03A6:
- bufpush(0x03C6);
- break;
- case 0x03A7:
- bufpush(0x03C7);
- break;
- case 0x03A8:
- bufpush(0x03C8);
- break;
- case 0x03A9:
- bufpush(0x03C9);
- break;
- case 0x03AA:
- bufpush(0x03CA);
- break;
- case 0x03AB:
- bufpush(0x03CB);
- break;
- case 0x03B0:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x03C2:
- bufpush(0x03C3);
- break;
- case 0x03D0:
- bufpush(0x03B2);
- break;
- case 0x03D1:
- bufpush(0x03B8);
- break;
- case 0x03D5:
- bufpush(0x03C6);
- break;
- case 0x03D6:
- bufpush(0x03C0);
- break;
- case 0x03D8:
- bufpush(0x03D9);
- break;
- case 0x03DA:
- bufpush(0x03DB);
- break;
- case 0x03DC:
- bufpush(0x03DD);
- break;
- case 0x03DE:
- bufpush(0x03DF);
- break;
- case 0x03E0:
- bufpush(0x03E1);
- break;
- case 0x03E2:
- bufpush(0x03E3);
- break;
- case 0x03E4:
- bufpush(0x03E5);
- break;
- case 0x03E6:
- bufpush(0x03E7);
- break;
- case 0x03E8:
- bufpush(0x03E9);
- break;
- case 0x03EA:
- bufpush(0x03EB);
- break;
- case 0x03EC:
- bufpush(0x03ED);
- break;
- case 0x03EE:
- bufpush(0x03EF);
- break;
- case 0x03F0:
- bufpush(0x03BA);
- break;
- case 0x03F1:
- bufpush(0x03C1);
- break;
- case 0x03F2:
- bufpush(0x03C3);
- break;
- case 0x03F4:
- bufpush(0x03B8);
- break;
- case 0x03F5:
- bufpush(0x03B5);
- break;
- case 0x0400:
- bufpush(0x0450);
- break;
- case 0x0401:
- bufpush(0x0451);
- break;
- case 0x0402:
- bufpush(0x0452);
- break;
- case 0x0403:
- bufpush(0x0453);
- break;
- case 0x0404:
- bufpush(0x0454);
- break;
- case 0x0405:
- bufpush(0x0455);
- break;
- case 0x0406:
- bufpush(0x0456);
- break;
- case 0x0407:
- bufpush(0x0457);
- break;
- case 0x0408:
- bufpush(0x0458);
- break;
- case 0x0409:
- bufpush(0x0459);
- break;
- case 0x040A:
- bufpush(0x045A);
- break;
- case 0x040B:
- bufpush(0x045B);
- break;
- case 0x040C:
- bufpush(0x045C);
- break;
- case 0x040D:
- bufpush(0x045D);
- break;
- case 0x040E:
- bufpush(0x045E);
- break;
- case 0x040F:
- bufpush(0x045F);
- break;
- case 0x0410:
- bufpush(0x0430);
- break;
- case 0x0411:
- bufpush(0x0431);
- break;
- case 0x0412:
- bufpush(0x0432);
- break;
- case 0x0413:
- bufpush(0x0433);
- break;
- case 0x0414:
- bufpush(0x0434);
- break;
- case 0x0415:
- bufpush(0x0435);
- break;
- case 0x0416:
- bufpush(0x0436);
- break;
- case 0x0417:
- bufpush(0x0437);
- break;
- case 0x0418:
- bufpush(0x0438);
- break;
- case 0x0419:
- bufpush(0x0439);
- break;
- case 0x041A:
- bufpush(0x043A);
- break;
- case 0x041B:
- bufpush(0x043B);
- break;
- case 0x041C:
- bufpush(0x043C);
- break;
- case 0x041D:
- bufpush(0x043D);
- break;
- case 0x041E:
- bufpush(0x043E);
- break;
- case 0x041F:
- bufpush(0x043F);
- break;
- case 0x0420:
- bufpush(0x0440);
- break;
- case 0x0421:
- bufpush(0x0441);
- break;
- case 0x0422:
- bufpush(0x0442);
- break;
- case 0x0423:
- bufpush(0x0443);
- break;
- case 0x0424:
- bufpush(0x0444);
- break;
- case 0x0425:
- bufpush(0x0445);
- break;
- case 0x0426:
- bufpush(0x0446);
- break;
- case 0x0427:
- bufpush(0x0447);
- break;
- case 0x0428:
- bufpush(0x0448);
- break;
- case 0x0429:
- bufpush(0x0449);
- break;
- case 0x042A:
- bufpush(0x044A);
- break;
- case 0x042B:
- bufpush(0x044B);
- break;
- case 0x042C:
- bufpush(0x044C);
- break;
- case 0x042D:
- bufpush(0x044D);
- break;
- case 0x042E:
- bufpush(0x044E);
- break;
- case 0x042F:
- bufpush(0x044F);
- break;
- case 0x0460:
- bufpush(0x0461);
- break;
- case 0x0462:
- bufpush(0x0463);
- break;
- case 0x0464:
- bufpush(0x0465);
- break;
- case 0x0466:
- bufpush(0x0467);
- break;
- case 0x0468:
- bufpush(0x0469);
- break;
- case 0x046A:
- bufpush(0x046B);
- break;
- case 0x046C:
- bufpush(0x046D);
- break;
- case 0x046E:
- bufpush(0x046F);
- break;
- case 0x0470:
- bufpush(0x0471);
- break;
- case 0x0472:
- bufpush(0x0473);
- break;
- case 0x0474:
- bufpush(0x0475);
- break;
- case 0x0476:
- bufpush(0x0477);
- break;
- case 0x0478:
- bufpush(0x0479);
- break;
- case 0x047A:
- bufpush(0x047B);
- break;
- case 0x047C:
- bufpush(0x047D);
- break;
- case 0x047E:
- bufpush(0x047F);
- break;
- case 0x0480:
- bufpush(0x0481);
- break;
- case 0x048A:
- bufpush(0x048B);
- break;
- case 0x048C:
- bufpush(0x048D);
- break;
- case 0x048E:
- bufpush(0x048F);
- break;
- case 0x0490:
- bufpush(0x0491);
- break;
- case 0x0492:
- bufpush(0x0493);
- break;
- case 0x0494:
- bufpush(0x0495);
- break;
- case 0x0496:
- bufpush(0x0497);
- break;
- case 0x0498:
- bufpush(0x0499);
- break;
- case 0x049A:
- bufpush(0x049B);
- break;
- case 0x049C:
- bufpush(0x049D);
- break;
- case 0x049E:
- bufpush(0x049F);
- break;
- case 0x04A0:
- bufpush(0x04A1);
- break;
- case 0x04A2:
- bufpush(0x04A3);
- break;
- case 0x04A4:
- bufpush(0x04A5);
- break;
- case 0x04A6:
- bufpush(0x04A7);
- break;
- case 0x04A8:
- bufpush(0x04A9);
- break;
- case 0x04AA:
- bufpush(0x04AB);
- break;
- case 0x04AC:
- bufpush(0x04AD);
- break;
- case 0x04AE:
- bufpush(0x04AF);
- break;
- case 0x04B0:
- bufpush(0x04B1);
- break;
- case 0x04B2:
- bufpush(0x04B3);
- break;
- case 0x04B4:
- bufpush(0x04B5);
- break;
- case 0x04B6:
- bufpush(0x04B7);
- break;
- case 0x04B8:
- bufpush(0x04B9);
- break;
- case 0x04BA:
- bufpush(0x04BB);
- break;
- case 0x04BC:
- bufpush(0x04BD);
- break;
- case 0x04BE:
- bufpush(0x04BF);
- break;
- case 0x04C1:
- bufpush(0x04C2);
- break;
- case 0x04C3:
- bufpush(0x04C4);
- break;
- case 0x04C5:
- bufpush(0x04C6);
- break;
- case 0x04C7:
- bufpush(0x04C8);
- break;
- case 0x04C9:
- bufpush(0x04CA);
- break;
- case 0x04CB:
- bufpush(0x04CC);
- break;
- case 0x04CD:
- bufpush(0x04CE);
- break;
- case 0x04D0:
- bufpush(0x04D1);
- break;
- case 0x04D2:
- bufpush(0x04D3);
- break;
- case 0x04D4:
- bufpush(0x04D5);
- break;
- case 0x04D6:
- bufpush(0x04D7);
- break;
- case 0x04D8:
- bufpush(0x04D9);
- break;
- case 0x04DA:
- bufpush(0x04DB);
- break;
- case 0x04DC:
- bufpush(0x04DD);
- break;
- case 0x04DE:
- bufpush(0x04DF);
- break;
- case 0x04E0:
- bufpush(0x04E1);
- break;
- case 0x04E2:
- bufpush(0x04E3);
- break;
- case 0x04E4:
- bufpush(0x04E5);
- break;
- case 0x04E6:
- bufpush(0x04E7);
- break;
- case 0x04E8:
- bufpush(0x04E9);
- break;
- case 0x04EA:
- bufpush(0x04EB);
- break;
- case 0x04EC:
- bufpush(0x04ED);
- break;
- case 0x04EE:
- bufpush(0x04EF);
- break;
- case 0x04F0:
- bufpush(0x04F1);
- break;
- case 0x04F2:
- bufpush(0x04F3);
- break;
- case 0x04F4:
- bufpush(0x04F5);
- break;
- case 0x04F8:
- bufpush(0x04F9);
- break;
- case 0x0500:
- bufpush(0x0501);
- break;
- case 0x0502:
- bufpush(0x0503);
- break;
- case 0x0504:
- bufpush(0x0505);
- break;
- case 0x0506:
- bufpush(0x0507);
- break;
- case 0x0508:
- bufpush(0x0509);
- break;
- case 0x050A:
- bufpush(0x050B);
- break;
- case 0x050C:
- bufpush(0x050D);
- break;
- case 0x050E:
- bufpush(0x050F);
- break;
- case 0x0531:
- bufpush(0x0561);
- break;
- case 0x0532:
- bufpush(0x0562);
- break;
- case 0x0533:
- bufpush(0x0563);
- break;
- case 0x0534:
- bufpush(0x0564);
- break;
- case 0x0535:
- bufpush(0x0565);
- break;
- case 0x0536:
- bufpush(0x0566);
- break;
- case 0x0537:
- bufpush(0x0567);
- break;
- case 0x0538:
- bufpush(0x0568);
- break;
- case 0x0539:
- bufpush(0x0569);
- break;
- case 0x053A:
- bufpush(0x056A);
- break;
- case 0x053B:
- bufpush(0x056B);
- break;
- case 0x053C:
- bufpush(0x056C);
- break;
- case 0x053D:
- bufpush(0x056D);
- break;
- case 0x053E:
- bufpush(0x056E);
- break;
- case 0x053F:
- bufpush(0x056F);
- break;
- case 0x0540:
- bufpush(0x0570);
- break;
- case 0x0541:
- bufpush(0x0571);
- break;
- case 0x0542:
- bufpush(0x0572);
- break;
- case 0x0543:
- bufpush(0x0573);
- break;
- case 0x0544:
- bufpush(0x0574);
- break;
- case 0x0545:
- bufpush(0x0575);
- break;
- case 0x0546:
- bufpush(0x0576);
- break;
- case 0x0547:
- bufpush(0x0577);
- break;
- case 0x0548:
- bufpush(0x0578);
- break;
- case 0x0549:
- bufpush(0x0579);
- break;
- case 0x054A:
- bufpush(0x057A);
- break;
- case 0x054B:
- bufpush(0x057B);
- break;
- case 0x054C:
- bufpush(0x057C);
- break;
- case 0x054D:
- bufpush(0x057D);
- break;
- case 0x054E:
- bufpush(0x057E);
- break;
- case 0x054F:
- bufpush(0x057F);
- break;
- case 0x0550:
- bufpush(0x0580);
- break;
- case 0x0551:
- bufpush(0x0581);
- break;
- case 0x0552:
- bufpush(0x0582);
- break;
- case 0x0553:
- bufpush(0x0583);
- break;
- case 0x0554:
- bufpush(0x0584);
- break;
- case 0x0555:
- bufpush(0x0585);
- break;
- case 0x0556:
- bufpush(0x0586);
- break;
- case 0x0587:
- bufpush(0x0565);
- bufpush(0x0582);
- break;
- case 0x1E00:
- bufpush(0x1E01);
- break;
- case 0x1E02:
- bufpush(0x1E03);
- break;
- case 0x1E04:
- bufpush(0x1E05);
- break;
- case 0x1E06:
- bufpush(0x1E07);
- break;
- case 0x1E08:
- bufpush(0x1E09);
- break;
- case 0x1E0A:
- bufpush(0x1E0B);
- break;
- case 0x1E0C:
- bufpush(0x1E0D);
- break;
- case 0x1E0E:
- bufpush(0x1E0F);
- break;
- case 0x1E10:
- bufpush(0x1E11);
- break;
- case 0x1E12:
- bufpush(0x1E13);
- break;
- case 0x1E14:
- bufpush(0x1E15);
- break;
- case 0x1E16:
- bufpush(0x1E17);
- break;
- case 0x1E18:
- bufpush(0x1E19);
- break;
- case 0x1E1A:
- bufpush(0x1E1B);
- break;
- case 0x1E1C:
- bufpush(0x1E1D);
- break;
- case 0x1E1E:
- bufpush(0x1E1F);
- break;
- case 0x1E20:
- bufpush(0x1E21);
- break;
- case 0x1E22:
- bufpush(0x1E23);
- break;
- case 0x1E24:
- bufpush(0x1E25);
- break;
- case 0x1E26:
- bufpush(0x1E27);
- break;
- case 0x1E28:
- bufpush(0x1E29);
- break;
- case 0x1E2A:
- bufpush(0x1E2B);
- break;
- case 0x1E2C:
- bufpush(0x1E2D);
- break;
- case 0x1E2E:
- bufpush(0x1E2F);
- break;
- case 0x1E30:
- bufpush(0x1E31);
- break;
- case 0x1E32:
- bufpush(0x1E33);
- break;
- case 0x1E34:
- bufpush(0x1E35);
- break;
- case 0x1E36:
- bufpush(0x1E37);
- break;
- case 0x1E38:
- bufpush(0x1E39);
- break;
- case 0x1E3A:
- bufpush(0x1E3B);
- break;
- case 0x1E3C:
- bufpush(0x1E3D);
- break;
- case 0x1E3E:
- bufpush(0x1E3F);
- break;
- case 0x1E40:
- bufpush(0x1E41);
- break;
- case 0x1E42:
- bufpush(0x1E43);
- break;
- case 0x1E44:
- bufpush(0x1E45);
- break;
- case 0x1E46:
- bufpush(0x1E47);
- break;
- case 0x1E48:
- bufpush(0x1E49);
- break;
- case 0x1E4A:
- bufpush(0x1E4B);
- break;
- case 0x1E4C:
- bufpush(0x1E4D);
- break;
- case 0x1E4E:
- bufpush(0x1E4F);
- break;
- case 0x1E50:
- bufpush(0x1E51);
- break;
- case 0x1E52:
- bufpush(0x1E53);
- break;
- case 0x1E54:
- bufpush(0x1E55);
- break;
- case 0x1E56:
- bufpush(0x1E57);
- break;
- case 0x1E58:
- bufpush(0x1E59);
- break;
- case 0x1E5A:
- bufpush(0x1E5B);
- break;
- case 0x1E5C:
- bufpush(0x1E5D);
- break;
- case 0x1E5E:
- bufpush(0x1E5F);
- break;
- case 0x1E60:
- bufpush(0x1E61);
- break;
- case 0x1E62:
- bufpush(0x1E63);
- break;
- case 0x1E64:
- bufpush(0x1E65);
- break;
- case 0x1E66:
- bufpush(0x1E67);
- break;
- case 0x1E68:
- bufpush(0x1E69);
- break;
- case 0x1E6A:
- bufpush(0x1E6B);
- break;
- case 0x1E6C:
- bufpush(0x1E6D);
- break;
- case 0x1E6E:
- bufpush(0x1E6F);
- break;
- case 0x1E70:
- bufpush(0x1E71);
- break;
- case 0x1E72:
- bufpush(0x1E73);
- break;
- case 0x1E74:
- bufpush(0x1E75);
- break;
- case 0x1E76:
- bufpush(0x1E77);
- break;
- case 0x1E78:
- bufpush(0x1E79);
- break;
- case 0x1E7A:
- bufpush(0x1E7B);
- break;
- case 0x1E7C:
- bufpush(0x1E7D);
- break;
- case 0x1E7E:
- bufpush(0x1E7F);
- break;
- case 0x1E80:
- bufpush(0x1E81);
- break;
- case 0x1E82:
- bufpush(0x1E83);
- break;
- case 0x1E84:
- bufpush(0x1E85);
- break;
- case 0x1E86:
- bufpush(0x1E87);
- break;
- case 0x1E88:
- bufpush(0x1E89);
- break;
- case 0x1E8A:
- bufpush(0x1E8B);
- break;
- case 0x1E8C:
- bufpush(0x1E8D);
- break;
- case 0x1E8E:
- bufpush(0x1E8F);
- break;
- case 0x1E90:
- bufpush(0x1E91);
- break;
- case 0x1E92:
- bufpush(0x1E93);
- break;
- case 0x1E94:
- bufpush(0x1E95);
- break;
- case 0x1E96:
- bufpush(0x0068);
- bufpush(0x0331);
- break;
- case 0x1E97:
- bufpush(0x0074);
- bufpush(0x0308);
- break;
- case 0x1E98:
- bufpush(0x0077);
- bufpush(0x030A);
- break;
- case 0x1E99:
- bufpush(0x0079);
- bufpush(0x030A);
- break;
- case 0x1E9A:
- bufpush(0x0061);
- bufpush(0x02BE);
- break;
- case 0x1E9B:
- bufpush(0x1E61);
- break;
- case 0x1EA0:
- bufpush(0x1EA1);
- break;
- case 0x1EA2:
- bufpush(0x1EA3);
- break;
- case 0x1EA4:
- bufpush(0x1EA5);
- break;
- case 0x1EA6:
- bufpush(0x1EA7);
- break;
- case 0x1EA8:
- bufpush(0x1EA9);
- break;
- case 0x1EAA:
- bufpush(0x1EAB);
- break;
- case 0x1EAC:
- bufpush(0x1EAD);
- break;
- case 0x1EAE:
- bufpush(0x1EAF);
- break;
- case 0x1EB0:
- bufpush(0x1EB1);
- break;
- case 0x1EB2:
- bufpush(0x1EB3);
- break;
- case 0x1EB4:
- bufpush(0x1EB5);
- break;
- case 0x1EB6:
- bufpush(0x1EB7);
- break;
- case 0x1EB8:
- bufpush(0x1EB9);
- break;
- case 0x1EBA:
- bufpush(0x1EBB);
- break;
- case 0x1EBC:
- bufpush(0x1EBD);
- break;
- case 0x1EBE:
- bufpush(0x1EBF);
- break;
- case 0x1EC0:
- bufpush(0x1EC1);
- break;
- case 0x1EC2:
- bufpush(0x1EC3);
- break;
- case 0x1EC4:
- bufpush(0x1EC5);
- break;
- case 0x1EC6:
- bufpush(0x1EC7);
- break;
- case 0x1EC8:
- bufpush(0x1EC9);
- break;
- case 0x1ECA:
- bufpush(0x1ECB);
- break;
- case 0x1ECC:
- bufpush(0x1ECD);
- break;
- case 0x1ECE:
- bufpush(0x1ECF);
- break;
- case 0x1ED0:
- bufpush(0x1ED1);
- break;
- case 0x1ED2:
- bufpush(0x1ED3);
- break;
- case 0x1ED4:
- bufpush(0x1ED5);
- break;
- case 0x1ED6:
- bufpush(0x1ED7);
- break;
- case 0x1ED8:
- bufpush(0x1ED9);
- break;
- case 0x1EDA:
- bufpush(0x1EDB);
- break;
- case 0x1EDC:
- bufpush(0x1EDD);
- break;
- case 0x1EDE:
- bufpush(0x1EDF);
- break;
- case 0x1EE0:
- bufpush(0x1EE1);
- break;
- case 0x1EE2:
- bufpush(0x1EE3);
- break;
- case 0x1EE4:
- bufpush(0x1EE5);
- break;
- case 0x1EE6:
- bufpush(0x1EE7);
- break;
- case 0x1EE8:
- bufpush(0x1EE9);
- break;
- case 0x1EEA:
- bufpush(0x1EEB);
- break;
- case 0x1EEC:
- bufpush(0x1EED);
- break;
- case 0x1EEE:
- bufpush(0x1EEF);
- break;
- case 0x1EF0:
- bufpush(0x1EF1);
- break;
- case 0x1EF2:
- bufpush(0x1EF3);
- break;
- case 0x1EF4:
- bufpush(0x1EF5);
- break;
- case 0x1EF6:
- bufpush(0x1EF7);
- break;
- case 0x1EF8:
- bufpush(0x1EF9);
- break;
- case 0x1F08:
- bufpush(0x1F00);
- break;
- case 0x1F09:
- bufpush(0x1F01);
- break;
- case 0x1F0A:
- bufpush(0x1F02);
- break;
- case 0x1F0B:
- bufpush(0x1F03);
- break;
- case 0x1F0C:
- bufpush(0x1F04);
- break;
- case 0x1F0D:
- bufpush(0x1F05);
- break;
- case 0x1F0E:
- bufpush(0x1F06);
- break;
- case 0x1F0F:
- bufpush(0x1F07);
- break;
- case 0x1F18:
- bufpush(0x1F10);
- break;
- case 0x1F19:
- bufpush(0x1F11);
- break;
- case 0x1F1A:
- bufpush(0x1F12);
- break;
- case 0x1F1B:
- bufpush(0x1F13);
- break;
- case 0x1F1C:
- bufpush(0x1F14);
- break;
- case 0x1F1D:
- bufpush(0x1F15);
- break;
- case 0x1F28:
- bufpush(0x1F20);
- break;
- case 0x1F29:
- bufpush(0x1F21);
- break;
- case 0x1F2A:
- bufpush(0x1F22);
- break;
- case 0x1F2B:
- bufpush(0x1F23);
- break;
- case 0x1F2C:
- bufpush(0x1F24);
- break;
- case 0x1F2D:
- bufpush(0x1F25);
- break;
- case 0x1F2E:
- bufpush(0x1F26);
- break;
- case 0x1F2F:
- bufpush(0x1F27);
- break;
- case 0x1F38:
- bufpush(0x1F30);
- break;
- case 0x1F39:
- bufpush(0x1F31);
- break;
- case 0x1F3A:
- bufpush(0x1F32);
- break;
- case 0x1F3B:
- bufpush(0x1F33);
- break;
- case 0x1F3C:
- bufpush(0x1F34);
- break;
- case 0x1F3D:
- bufpush(0x1F35);
- break;
- case 0x1F3E:
- bufpush(0x1F36);
- break;
- case 0x1F3F:
- bufpush(0x1F37);
- break;
- case 0x1F48:
- bufpush(0x1F40);
- break;
- case 0x1F49:
- bufpush(0x1F41);
- break;
- case 0x1F4A:
- bufpush(0x1F42);
- break;
- case 0x1F4B:
- bufpush(0x1F43);
- break;
- case 0x1F4C:
- bufpush(0x1F44);
- break;
- case 0x1F4D:
- bufpush(0x1F45);
- break;
- case 0x1F50:
- bufpush(0x03C5);
- bufpush(0x0313);
- break;
- case 0x1F52:
- bufpush(0x03C5);
- bufpush(0x0313);
- bufpush(0x0300);
- break;
- case 0x1F54:
- bufpush(0x03C5);
- bufpush(0x0313);
- bufpush(0x0301);
- break;
- case 0x1F56:
- bufpush(0x03C5);
- bufpush(0x0313);
- bufpush(0x0342);
- break;
- case 0x1F59:
- bufpush(0x1F51);
- break;
- case 0x1F5B:
- bufpush(0x1F53);
- break;
- case 0x1F5D:
- bufpush(0x1F55);
- break;
- case 0x1F5F:
- bufpush(0x1F57);
- break;
- case 0x1F68:
- bufpush(0x1F60);
- break;
- case 0x1F69:
- bufpush(0x1F61);
- break;
- case 0x1F6A:
- bufpush(0x1F62);
- break;
- case 0x1F6B:
- bufpush(0x1F63);
- break;
- case 0x1F6C:
- bufpush(0x1F64);
- break;
- case 0x1F6D:
- bufpush(0x1F65);
- break;
- case 0x1F6E:
- bufpush(0x1F66);
- break;
- case 0x1F6F:
- bufpush(0x1F67);
- break;
- case 0x1F80:
- bufpush(0x1F00);
- bufpush(0x03B9);
- break;
- case 0x1F81:
- bufpush(0x1F01);
- bufpush(0x03B9);
- break;
- case 0x1F82:
- bufpush(0x1F02);
- bufpush(0x03B9);
- break;
- case 0x1F83:
- bufpush(0x1F03);
- bufpush(0x03B9);
- break;
- case 0x1F84:
- bufpush(0x1F04);
- bufpush(0x03B9);
- break;
- case 0x1F85:
- bufpush(0x1F05);
- bufpush(0x03B9);
- break;
- case 0x1F86:
- bufpush(0x1F06);
- bufpush(0x03B9);
- break;
- case 0x1F87:
- bufpush(0x1F07);
- bufpush(0x03B9);
- break;
- case 0x1F88:
- bufpush(0x1F00);
- bufpush(0x03B9);
- break;
- case 0x1F89:
- bufpush(0x1F01);
- bufpush(0x03B9);
- break;
- case 0x1F8A:
- bufpush(0x1F02);
- bufpush(0x03B9);
- break;
- case 0x1F8B:
- bufpush(0x1F03);
- bufpush(0x03B9);
- break;
- case 0x1F8C:
- bufpush(0x1F04);
- bufpush(0x03B9);
- break;
- case 0x1F8D:
- bufpush(0x1F05);
- bufpush(0x03B9);
- break;
- case 0x1F8E:
- bufpush(0x1F06);
- bufpush(0x03B9);
- break;
- case 0x1F8F:
- bufpush(0x1F07);
- bufpush(0x03B9);
- break;
- case 0x1F90:
- bufpush(0x1F20);
- bufpush(0x03B9);
- break;
- case 0x1F91:
- bufpush(0x1F21);
- bufpush(0x03B9);
- break;
- case 0x1F92:
- bufpush(0x1F22);
- bufpush(0x03B9);
- break;
- case 0x1F93:
- bufpush(0x1F23);
- bufpush(0x03B9);
- break;
- case 0x1F94:
- bufpush(0x1F24);
- bufpush(0x03B9);
- break;
- case 0x1F95:
- bufpush(0x1F25);
- bufpush(0x03B9);
- break;
- case 0x1F96:
- bufpush(0x1F26);
- bufpush(0x03B9);
- break;
- case 0x1F97:
- bufpush(0x1F27);
- bufpush(0x03B9);
- break;
- case 0x1F98:
- bufpush(0x1F20);
- bufpush(0x03B9);
- break;
- case 0x1F99:
- bufpush(0x1F21);
- bufpush(0x03B9);
- break;
- case 0x1F9A:
- bufpush(0x1F22);
- bufpush(0x03B9);
- break;
- case 0x1F9B:
- bufpush(0x1F23);
- bufpush(0x03B9);
- break;
- case 0x1F9C:
- bufpush(0x1F24);
- bufpush(0x03B9);
- break;
- case 0x1F9D:
- bufpush(0x1F25);
- bufpush(0x03B9);
- break;
- case 0x1F9E:
- bufpush(0x1F26);
- bufpush(0x03B9);
- break;
- case 0x1F9F:
- bufpush(0x1F27);
- bufpush(0x03B9);
- break;
- case 0x1FA0:
- bufpush(0x1F60);
- bufpush(0x03B9);
- break;
- case 0x1FA1:
- bufpush(0x1F61);
- bufpush(0x03B9);
- break;
- case 0x1FA2:
- bufpush(0x1F62);
- bufpush(0x03B9);
- break;
- case 0x1FA3:
- bufpush(0x1F63);
- bufpush(0x03B9);
- break;
- case 0x1FA4:
- bufpush(0x1F64);
- bufpush(0x03B9);
- break;
- case 0x1FA5:
- bufpush(0x1F65);
- bufpush(0x03B9);
- break;
- case 0x1FA6:
- bufpush(0x1F66);
- bufpush(0x03B9);
- break;
- case 0x1FA7:
- bufpush(0x1F67);
- bufpush(0x03B9);
- break;
- case 0x1FA8:
- bufpush(0x1F60);
- bufpush(0x03B9);
- break;
- case 0x1FA9:
- bufpush(0x1F61);
- bufpush(0x03B9);
- break;
- case 0x1FAA:
- bufpush(0x1F62);
- bufpush(0x03B9);
- break;
- case 0x1FAB:
- bufpush(0x1F63);
- bufpush(0x03B9);
- break;
- case 0x1FAC:
- bufpush(0x1F64);
- bufpush(0x03B9);
- break;
- case 0x1FAD:
- bufpush(0x1F65);
- bufpush(0x03B9);
- break;
- case 0x1FAE:
- bufpush(0x1F66);
- bufpush(0x03B9);
- break;
- case 0x1FAF:
- bufpush(0x1F67);
- bufpush(0x03B9);
- break;
- case 0x1FB2:
- bufpush(0x1F70);
- bufpush(0x03B9);
- break;
- case 0x1FB3:
- bufpush(0x03B1);
- bufpush(0x03B9);
- break;
- case 0x1FB4:
- bufpush(0x03AC);
- bufpush(0x03B9);
- break;
- case 0x1FB6:
- bufpush(0x03B1);
- bufpush(0x0342);
- break;
- case 0x1FB7:
- bufpush(0x03B1);
- bufpush(0x0342);
- bufpush(0x03B9);
- break;
- case 0x1FB8:
- bufpush(0x1FB0);
- break;
- case 0x1FB9:
- bufpush(0x1FB1);
- break;
- case 0x1FBA:
- bufpush(0x1F70);
- break;
- case 0x1FBB:
- bufpush(0x1F71);
- break;
- case 0x1FBC:
- bufpush(0x03B1);
- bufpush(0x03B9);
- break;
- case 0x1FBE:
- bufpush(0x03B9);
- break;
- case 0x1FC2:
- bufpush(0x1F74);
- bufpush(0x03B9);
- break;
- case 0x1FC3:
- bufpush(0x03B7);
- bufpush(0x03B9);
- break;
- case 0x1FC4:
- bufpush(0x03AE);
- bufpush(0x03B9);
- break;
- case 0x1FC6:
- bufpush(0x03B7);
- bufpush(0x0342);
- break;
- case 0x1FC7:
- bufpush(0x03B7);
- bufpush(0x0342);
- bufpush(0x03B9);
- break;
- case 0x1FC8:
- bufpush(0x1F72);
- break;
- case 0x1FC9:
- bufpush(0x1F73);
- break;
- case 0x1FCA:
- bufpush(0x1F74);
- break;
- case 0x1FCB:
- bufpush(0x1F75);
- break;
- case 0x1FCC:
- bufpush(0x03B7);
- bufpush(0x03B9);
- break;
- case 0x1FD2:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0300);
- break;
- case 0x1FD3:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x1FD6:
- bufpush(0x03B9);
- bufpush(0x0342);
- break;
- case 0x1FD7:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0342);
- break;
- case 0x1FD8:
- bufpush(0x1FD0);
- break;
- case 0x1FD9:
- bufpush(0x1FD1);
- break;
- case 0x1FDA:
- bufpush(0x1F76);
- break;
- case 0x1FDB:
- bufpush(0x1F77);
- break;
- case 0x1FE2:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0300);
- break;
- case 0x1FE3:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x1FE4:
- bufpush(0x03C1);
- bufpush(0x0313);
- break;
- case 0x1FE6:
- bufpush(0x03C5);
- bufpush(0x0342);
- break;
- case 0x1FE7:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0342);
- break;
- case 0x1FE8:
- bufpush(0x1FE0);
- break;
- case 0x1FE9:
- bufpush(0x1FE1);
- break;
- case 0x1FEA:
- bufpush(0x1F7A);
- break;
- case 0x1FEB:
- bufpush(0x1F7B);
- break;
- case 0x1FEC:
- bufpush(0x1FE5);
- break;
- case 0x1FF2:
- bufpush(0x1F7C);
- bufpush(0x03B9);
- break;
- case 0x1FF3:
- bufpush(0x03C9);
- bufpush(0x03B9);
- break;
- case 0x1FF4:
- bufpush(0x03CE);
- bufpush(0x03B9);
- break;
- case 0x1FF6:
- bufpush(0x03C9);
- bufpush(0x0342);
- break;
- case 0x1FF7:
- bufpush(0x03C9);
- bufpush(0x0342);
- bufpush(0x03B9);
- break;
- case 0x1FF8:
- bufpush(0x1F78);
- break;
- case 0x1FF9:
- bufpush(0x1F79);
- break;
- case 0x1FFA:
- bufpush(0x1F7C);
- break;
- case 0x1FFB:
- bufpush(0x1F7D);
- break;
- case 0x1FFC:
- bufpush(0x03C9);
- bufpush(0x03B9);
- break;
- case 0x2126:
- bufpush(0x03C9);
- break;
- case 0x212A:
- bufpush(0x006B);
- break;
- case 0x212B:
- bufpush(0x00E5);
- break;
- case 0x2160:
- bufpush(0x2170);
- break;
- case 0x2161:
- bufpush(0x2171);
- break;
- case 0x2162:
- bufpush(0x2172);
- break;
- case 0x2163:
- bufpush(0x2173);
- break;
- case 0x2164:
- bufpush(0x2174);
- break;
- case 0x2165:
- bufpush(0x2175);
- break;
- case 0x2166:
- bufpush(0x2176);
- break;
- case 0x2167:
- bufpush(0x2177);
- break;
- case 0x2168:
- bufpush(0x2178);
- break;
- case 0x2169:
- bufpush(0x2179);
- break;
- case 0x216A:
- bufpush(0x217A);
- break;
- case 0x216B:
- bufpush(0x217B);
- break;
- case 0x216C:
- bufpush(0x217C);
- break;
- case 0x216D:
- bufpush(0x217D);
- break;
- case 0x216E:
- bufpush(0x217E);
- break;
- case 0x216F:
- bufpush(0x217F);
- break;
- case 0x24B6:
- bufpush(0x24D0);
- break;
- case 0x24B7:
- bufpush(0x24D1);
- break;
- case 0x24B8:
- bufpush(0x24D2);
- break;
- case 0x24B9:
- bufpush(0x24D3);
- break;
- case 0x24BA:
- bufpush(0x24D4);
- break;
- case 0x24BB:
- bufpush(0x24D5);
- break;
- case 0x24BC:
- bufpush(0x24D6);
- break;
- case 0x24BD:
- bufpush(0x24D7);
- break;
- case 0x24BE:
- bufpush(0x24D8);
- break;
- case 0x24BF:
- bufpush(0x24D9);
- break;
- case 0x24C0:
- bufpush(0x24DA);
- break;
- case 0x24C1:
- bufpush(0x24DB);
- break;
- case 0x24C2:
- bufpush(0x24DC);
- break;
- case 0x24C3:
- bufpush(0x24DD);
- break;
- case 0x24C4:
- bufpush(0x24DE);
- break;
- case 0x24C5:
- bufpush(0x24DF);
- break;
- case 0x24C6:
- bufpush(0x24E0);
- break;
- case 0x24C7:
- bufpush(0x24E1);
- break;
- case 0x24C8:
- bufpush(0x24E2);
- break;
- case 0x24C9:
- bufpush(0x24E3);
- break;
- case 0x24CA:
- bufpush(0x24E4);
- break;
- case 0x24CB:
- bufpush(0x24E5);
- break;
- case 0x24CC:
- bufpush(0x24E6);
- break;
- case 0x24CD:
- bufpush(0x24E7);
- break;
- case 0x24CE:
- bufpush(0x24E8);
- break;
- case 0x24CF:
- bufpush(0x24E9);
- break;
- case 0xFB00:
- bufpush(0x0066);
- bufpush(0x0066);
- break;
- case 0xFB01:
- bufpush(0x0066);
- bufpush(0x0069);
- break;
- case 0xFB02:
- bufpush(0x0066);
- bufpush(0x006C);
- break;
- case 0xFB03:
- bufpush(0x0066);
- bufpush(0x0066);
- bufpush(0x0069);
- break;
- case 0xFB04:
- bufpush(0x0066);
- bufpush(0x0066);
- bufpush(0x006C);
- break;
- case 0xFB05:
- bufpush(0x0073);
- bufpush(0x0074);
- break;
- case 0xFB06:
- bufpush(0x0073);
- bufpush(0x0074);
- break;
- case 0xFB13:
- bufpush(0x0574);
- bufpush(0x0576);
- break;
- case 0xFB14:
- bufpush(0x0574);
- bufpush(0x0565);
- break;
- case 0xFB15:
- bufpush(0x0574);
- bufpush(0x056B);
- break;
- case 0xFB16:
- bufpush(0x057E);
- bufpush(0x0576);
- break;
- case 0xFB17:
- bufpush(0x0574);
- bufpush(0x056D);
- break;
- case 0xFF21:
- bufpush(0xFF41);
- break;
- case 0xFF22:
- bufpush(0xFF42);
- break;
- case 0xFF23:
- bufpush(0xFF43);
- break;
- case 0xFF24:
- bufpush(0xFF44);
- break;
- case 0xFF25:
- bufpush(0xFF45);
- break;
- case 0xFF26:
- bufpush(0xFF46);
- break;
- case 0xFF27:
- bufpush(0xFF47);
- break;
- case 0xFF28:
- bufpush(0xFF48);
- break;
- case 0xFF29:
- bufpush(0xFF49);
- break;
- case 0xFF2A:
- bufpush(0xFF4A);
- break;
- case 0xFF2B:
- bufpush(0xFF4B);
- break;
- case 0xFF2C:
- bufpush(0xFF4C);
- break;
- case 0xFF2D:
- bufpush(0xFF4D);
- break;
- case 0xFF2E:
- bufpush(0xFF4E);
- break;
- case 0xFF2F:
- bufpush(0xFF4F);
- break;
- case 0xFF30:
- bufpush(0xFF50);
- break;
- case 0xFF31:
- bufpush(0xFF51);
- break;
- case 0xFF32:
- bufpush(0xFF52);
- break;
- case 0xFF33:
- bufpush(0xFF53);
- break;
- case 0xFF34:
- bufpush(0xFF54);
- break;
- case 0xFF35:
- bufpush(0xFF55);
- break;
- case 0xFF36:
- bufpush(0xFF56);
- break;
- case 0xFF37:
- bufpush(0xFF57);
- break;
- case 0xFF38:
- bufpush(0xFF58);
- break;
- case 0xFF39:
- bufpush(0xFF59);
- break;
- case 0xFF3A:
- bufpush(0xFF5A);
- break;
- case 0x10400:
- bufpush(0x10428);
- break;
- case 0x10401:
- bufpush(0x10429);
- break;
- case 0x10402:
- bufpush(0x1042A);
- break;
- case 0x10403:
- bufpush(0x1042B);
- break;
- case 0x10404:
- bufpush(0x1042C);
- break;
- case 0x10405:
- bufpush(0x1042D);
- break;
- case 0x10406:
- bufpush(0x1042E);
- break;
- case 0x10407:
- bufpush(0x1042F);
- break;
- case 0x10408:
- bufpush(0x10430);
- break;
- case 0x10409:
- bufpush(0x10431);
- break;
- case 0x1040A:
- bufpush(0x10432);
- break;
- case 0x1040B:
- bufpush(0x10433);
- break;
- case 0x1040C:
- bufpush(0x10434);
- break;
- case 0x1040D:
- bufpush(0x10435);
- break;
- case 0x1040E:
- bufpush(0x10436);
- break;
- case 0x1040F:
- bufpush(0x10437);
- break;
- case 0x10410:
- bufpush(0x10438);
- break;
- case 0x10411:
- bufpush(0x10439);
- break;
- case 0x10412:
- bufpush(0x1043A);
- break;
- case 0x10413:
- bufpush(0x1043B);
- break;
- case 0x10414:
- bufpush(0x1043C);
- break;
- case 0x10415:
- bufpush(0x1043D);
- break;
- case 0x10416:
- bufpush(0x1043E);
- break;
- case 0x10417:
- bufpush(0x1043F);
- break;
- case 0x10418:
- bufpush(0x10440);
- break;
- case 0x10419:
- bufpush(0x10441);
- break;
- case 0x1041A:
- bufpush(0x10442);
- break;
- case 0x1041B:
- bufpush(0x10443);
- break;
- case 0x1041C:
- bufpush(0x10444);
- break;
- case 0x1041D:
- bufpush(0x10445);
- break;
- case 0x1041E:
- bufpush(0x10446);
- break;
- case 0x1041F:
- bufpush(0x10447);
- break;
- case 0x10420:
- bufpush(0x10448);
- break;
- case 0x10421:
- bufpush(0x10449);
- break;
- case 0x10422:
- bufpush(0x1044A);
- break;
- case 0x10423:
- bufpush(0x1044B);
- break;
- case 0x10424:
- bufpush(0x1044C);
- break;
- case 0x10425:
- bufpush(0x1044D);
- break;
- default:
- bufpush(c);
- }
diff --git a/src/case_fold_switch.inc b/src/case_fold_switch.inc
new file mode 100644
index 0000000..70fdd75
--- /dev/null
+++ b/src/case_fold_switch.inc
@@ -0,0 +1,2637 @@
+ switch (c) {
+ case 0x0041:
+ bufpush(0x0061);
+ break;
+ case 0x0042:
+ bufpush(0x0062);
+ break;
+ case 0x0043:
+ bufpush(0x0063);
+ break;
+ case 0x0044:
+ bufpush(0x0064);
+ break;
+ case 0x0045:
+ bufpush(0x0065);
+ break;
+ case 0x0046:
+ bufpush(0x0066);
+ break;
+ case 0x0047:
+ bufpush(0x0067);
+ break;
+ case 0x0048:
+ bufpush(0x0068);
+ break;
+ case 0x0049:
+ bufpush(0x0069);
+ break;
+ case 0x004A:
+ bufpush(0x006A);
+ break;
+ case 0x004B:
+ bufpush(0x006B);
+ break;
+ case 0x004C:
+ bufpush(0x006C);
+ break;
+ case 0x004D:
+ bufpush(0x006D);
+ break;
+ case 0x004E:
+ bufpush(0x006E);
+ break;
+ case 0x004F:
+ bufpush(0x006F);
+ break;
+ case 0x0050:
+ bufpush(0x0070);
+ break;
+ case 0x0051:
+ bufpush(0x0071);
+ break;
+ case 0x0052:
+ bufpush(0x0072);
+ break;
+ case 0x0053:
+ bufpush(0x0073);
+ break;
+ case 0x0054:
+ bufpush(0x0074);
+ break;
+ case 0x0055:
+ bufpush(0x0075);
+ break;
+ case 0x0056:
+ bufpush(0x0076);
+ break;
+ case 0x0057:
+ bufpush(0x0077);
+ break;
+ case 0x0058:
+ bufpush(0x0078);
+ break;
+ case 0x0059:
+ bufpush(0x0079);
+ break;
+ case 0x005A:
+ bufpush(0x007A);
+ break;
+ case 0x00B5:
+ bufpush(0x03BC);
+ break;
+ case 0x00C0:
+ bufpush(0x00E0);
+ break;
+ case 0x00C1:
+ bufpush(0x00E1);
+ break;
+ case 0x00C2:
+ bufpush(0x00E2);
+ break;
+ case 0x00C3:
+ bufpush(0x00E3);
+ break;
+ case 0x00C4:
+ bufpush(0x00E4);
+ break;
+ case 0x00C5:
+ bufpush(0x00E5);
+ break;
+ case 0x00C6:
+ bufpush(0x00E6);
+ break;
+ case 0x00C7:
+ bufpush(0x00E7);
+ break;
+ case 0x00C8:
+ bufpush(0x00E8);
+ break;
+ case 0x00C9:
+ bufpush(0x00E9);
+ break;
+ case 0x00CA:
+ bufpush(0x00EA);
+ break;
+ case 0x00CB:
+ bufpush(0x00EB);
+ break;
+ case 0x00CC:
+ bufpush(0x00EC);
+ break;
+ case 0x00CD:
+ bufpush(0x00ED);
+ break;
+ case 0x00CE:
+ bufpush(0x00EE);
+ break;
+ case 0x00CF:
+ bufpush(0x00EF);
+ break;
+ case 0x00D0:
+ bufpush(0x00F0);
+ break;
+ case 0x00D1:
+ bufpush(0x00F1);
+ break;
+ case 0x00D2:
+ bufpush(0x00F2);
+ break;
+ case 0x00D3:
+ bufpush(0x00F3);
+ break;
+ case 0x00D4:
+ bufpush(0x00F4);
+ break;
+ case 0x00D5:
+ bufpush(0x00F5);
+ break;
+ case 0x00D6:
+ bufpush(0x00F6);
+ break;
+ case 0x00D8:
+ bufpush(0x00F8);
+ break;
+ case 0x00D9:
+ bufpush(0x00F9);
+ break;
+ case 0x00DA:
+ bufpush(0x00FA);
+ break;
+ case 0x00DB:
+ bufpush(0x00FB);
+ break;
+ case 0x00DC:
+ bufpush(0x00FC);
+ break;
+ case 0x00DD:
+ bufpush(0x00FD);
+ break;
+ case 0x00DE:
+ bufpush(0x00FE);
+ break;
+ case 0x00DF:
+ bufpush(0x0073);
+ bufpush(0x0073);
+ break;
+ case 0x0100:
+ bufpush(0x0101);
+ break;
+ case 0x0102:
+ bufpush(0x0103);
+ break;
+ case 0x0104:
+ bufpush(0x0105);
+ break;
+ case 0x0106:
+ bufpush(0x0107);
+ break;
+ case 0x0108:
+ bufpush(0x0109);
+ break;
+ case 0x010A:
+ bufpush(0x010B);
+ break;
+ case 0x010C:
+ bufpush(0x010D);
+ break;
+ case 0x010E:
+ bufpush(0x010F);
+ break;
+ case 0x0110:
+ bufpush(0x0111);
+ break;
+ case 0x0112:
+ bufpush(0x0113);
+ break;
+ case 0x0114:
+ bufpush(0x0115);
+ break;
+ case 0x0116:
+ bufpush(0x0117);
+ break;
+ case 0x0118:
+ bufpush(0x0119);
+ break;
+ case 0x011A:
+ bufpush(0x011B);
+ break;
+ case 0x011C:
+ bufpush(0x011D);
+ break;
+ case 0x011E:
+ bufpush(0x011F);
+ break;
+ case 0x0120:
+ bufpush(0x0121);
+ break;
+ case 0x0122:
+ bufpush(0x0123);
+ break;
+ case 0x0124:
+ bufpush(0x0125);
+ break;
+ case 0x0126:
+ bufpush(0x0127);
+ break;
+ case 0x0128:
+ bufpush(0x0129);
+ break;
+ case 0x012A:
+ bufpush(0x012B);
+ break;
+ case 0x012C:
+ bufpush(0x012D);
+ break;
+ case 0x012E:
+ bufpush(0x012F);
+ break;
+ case 0x0130:
+ bufpush(0x0069);
+ bufpush(0x0307);
+ break;
+ case 0x0132:
+ bufpush(0x0133);
+ break;
+ case 0x0134:
+ bufpush(0x0135);
+ break;
+ case 0x0136:
+ bufpush(0x0137);
+ break;
+ case 0x0139:
+ bufpush(0x013A);
+ break;
+ case 0x013B:
+ bufpush(0x013C);
+ break;
+ case 0x013D:
+ bufpush(0x013E);
+ break;
+ case 0x013F:
+ bufpush(0x0140);
+ break;
+ case 0x0141:
+ bufpush(0x0142);
+ break;
+ case 0x0143:
+ bufpush(0x0144);
+ break;
+ case 0x0145:
+ bufpush(0x0146);
+ break;
+ case 0x0147:
+ bufpush(0x0148);
+ break;
+ case 0x0149:
+ bufpush(0x02BC);
+ bufpush(0x006E);
+ break;
+ case 0x014A:
+ bufpush(0x014B);
+ break;
+ case 0x014C:
+ bufpush(0x014D);
+ break;
+ case 0x014E:
+ bufpush(0x014F);
+ break;
+ case 0x0150:
+ bufpush(0x0151);
+ break;
+ case 0x0152:
+ bufpush(0x0153);
+ break;
+ case 0x0154:
+ bufpush(0x0155);
+ break;
+ case 0x0156:
+ bufpush(0x0157);
+ break;
+ case 0x0158:
+ bufpush(0x0159);
+ break;
+ case 0x015A:
+ bufpush(0x015B);
+ break;
+ case 0x015C:
+ bufpush(0x015D);
+ break;
+ case 0x015E:
+ bufpush(0x015F);
+ break;
+ case 0x0160:
+ bufpush(0x0161);
+ break;
+ case 0x0162:
+ bufpush(0x0163);
+ break;
+ case 0x0164:
+ bufpush(0x0165);
+ break;
+ case 0x0166:
+ bufpush(0x0167);
+ break;
+ case 0x0168:
+ bufpush(0x0169);
+ break;
+ case 0x016A:
+ bufpush(0x016B);
+ break;
+ case 0x016C:
+ bufpush(0x016D);
+ break;
+ case 0x016E:
+ bufpush(0x016F);
+ break;
+ case 0x0170:
+ bufpush(0x0171);
+ break;
+ case 0x0172:
+ bufpush(0x0173);
+ break;
+ case 0x0174:
+ bufpush(0x0175);
+ break;
+ case 0x0176:
+ bufpush(0x0177);
+ break;
+ case 0x0178:
+ bufpush(0x00FF);
+ break;
+ case 0x0179:
+ bufpush(0x017A);
+ break;
+ case 0x017B:
+ bufpush(0x017C);
+ break;
+ case 0x017D:
+ bufpush(0x017E);
+ break;
+ case 0x017F:
+ bufpush(0x0073);
+ break;
+ case 0x0181:
+ bufpush(0x0253);
+ break;
+ case 0x0182:
+ bufpush(0x0183);
+ break;
+ case 0x0184:
+ bufpush(0x0185);
+ break;
+ case 0x0186:
+ bufpush(0x0254);
+ break;
+ case 0x0187:
+ bufpush(0x0188);
+ break;
+ case 0x0189:
+ bufpush(0x0256);
+ break;
+ case 0x018A:
+ bufpush(0x0257);
+ break;
+ case 0x018B:
+ bufpush(0x018C);
+ break;
+ case 0x018E:
+ bufpush(0x01DD);
+ break;
+ case 0x018F:
+ bufpush(0x0259);
+ break;
+ case 0x0190:
+ bufpush(0x025B);
+ break;
+ case 0x0191:
+ bufpush(0x0192);
+ break;
+ case 0x0193:
+ bufpush(0x0260);
+ break;
+ case 0x0194:
+ bufpush(0x0263);
+ break;
+ case 0x0196:
+ bufpush(0x0269);
+ break;
+ case 0x0197:
+ bufpush(0x0268);
+ break;
+ case 0x0198:
+ bufpush(0x0199);
+ break;
+ case 0x019C:
+ bufpush(0x026F);
+ break;
+ case 0x019D:
+ bufpush(0x0272);
+ break;
+ case 0x019F:
+ bufpush(0x0275);
+ break;
+ case 0x01A0:
+ bufpush(0x01A1);
+ break;
+ case 0x01A2:
+ bufpush(0x01A3);
+ break;
+ case 0x01A4:
+ bufpush(0x01A5);
+ break;
+ case 0x01A6:
+ bufpush(0x0280);
+ break;
+ case 0x01A7:
+ bufpush(0x01A8);
+ break;
+ case 0x01A9:
+ bufpush(0x0283);
+ break;
+ case 0x01AC:
+ bufpush(0x01AD);
+ break;
+ case 0x01AE:
+ bufpush(0x0288);
+ break;
+ case 0x01AF:
+ bufpush(0x01B0);
+ break;
+ case 0x01B1:
+ bufpush(0x028A);
+ break;
+ case 0x01B2:
+ bufpush(0x028B);
+ break;
+ case 0x01B3:
+ bufpush(0x01B4);
+ break;
+ case 0x01B5:
+ bufpush(0x01B6);
+ break;
+ case 0x01B7:
+ bufpush(0x0292);
+ break;
+ case 0x01B8:
+ bufpush(0x01B9);
+ break;
+ case 0x01BC:
+ bufpush(0x01BD);
+ break;
+ case 0x01C4:
+ bufpush(0x01C6);
+ break;
+ case 0x01C5:
+ bufpush(0x01C6);
+ break;
+ case 0x01C7:
+ bufpush(0x01C9);
+ break;
+ case 0x01C8:
+ bufpush(0x01C9);
+ break;
+ case 0x01CA:
+ bufpush(0x01CC);
+ break;
+ case 0x01CB:
+ bufpush(0x01CC);
+ break;
+ case 0x01CD:
+ bufpush(0x01CE);
+ break;
+ case 0x01CF:
+ bufpush(0x01D0);
+ break;
+ case 0x01D1:
+ bufpush(0x01D2);
+ break;
+ case 0x01D3:
+ bufpush(0x01D4);
+ break;
+ case 0x01D5:
+ bufpush(0x01D6);
+ break;
+ case 0x01D7:
+ bufpush(0x01D8);
+ break;
+ case 0x01D9:
+ bufpush(0x01DA);
+ break;
+ case 0x01DB:
+ bufpush(0x01DC);
+ break;
+ case 0x01DE:
+ bufpush(0x01DF);
+ break;
+ case 0x01E0:
+ bufpush(0x01E1);
+ break;
+ case 0x01E2:
+ bufpush(0x01E3);
+ break;
+ case 0x01E4:
+ bufpush(0x01E5);
+ break;
+ case 0x01E6:
+ bufpush(0x01E7);
+ break;
+ case 0x01E8:
+ bufpush(0x01E9);
+ break;
+ case 0x01EA:
+ bufpush(0x01EB);
+ break;
+ case 0x01EC:
+ bufpush(0x01ED);
+ break;
+ case 0x01EE:
+ bufpush(0x01EF);
+ break;
+ case 0x01F0:
+ bufpush(0x006A);
+ bufpush(0x030C);
+ break;
+ case 0x01F1:
+ bufpush(0x01F3);
+ break;
+ case 0x01F2:
+ bufpush(0x01F3);
+ break;
+ case 0x01F4:
+ bufpush(0x01F5);
+ break;
+ case 0x01F6:
+ bufpush(0x0195);
+ break;
+ case 0x01F7:
+ bufpush(0x01BF);
+ break;
+ case 0x01F8:
+ bufpush(0x01F9);
+ break;
+ case 0x01FA:
+ bufpush(0x01FB);
+ break;
+ case 0x01FC:
+ bufpush(0x01FD);
+ break;
+ case 0x01FE:
+ bufpush(0x01FF);
+ break;
+ case 0x0200:
+ bufpush(0x0201);
+ break;
+ case 0x0202:
+ bufpush(0x0203);
+ break;
+ case 0x0204:
+ bufpush(0x0205);
+ break;
+ case 0x0206:
+ bufpush(0x0207);
+ break;
+ case 0x0208:
+ bufpush(0x0209);
+ break;
+ case 0x020A:
+ bufpush(0x020B);
+ break;
+ case 0x020C:
+ bufpush(0x020D);
+ break;
+ case 0x020E:
+ bufpush(0x020F);
+ break;
+ case 0x0210:
+ bufpush(0x0211);
+ break;
+ case 0x0212:
+ bufpush(0x0213);
+ break;
+ case 0x0214:
+ bufpush(0x0215);
+ break;
+ case 0x0216:
+ bufpush(0x0217);
+ break;
+ case 0x0218:
+ bufpush(0x0219);
+ break;
+ case 0x021A:
+ bufpush(0x021B);
+ break;
+ case 0x021C:
+ bufpush(0x021D);
+ break;
+ case 0x021E:
+ bufpush(0x021F);
+ break;
+ case 0x0220:
+ bufpush(0x019E);
+ break;
+ case 0x0222:
+ bufpush(0x0223);
+ break;
+ case 0x0224:
+ bufpush(0x0225);
+ break;
+ case 0x0226:
+ bufpush(0x0227);
+ break;
+ case 0x0228:
+ bufpush(0x0229);
+ break;
+ case 0x022A:
+ bufpush(0x022B);
+ break;
+ case 0x022C:
+ bufpush(0x022D);
+ break;
+ case 0x022E:
+ bufpush(0x022F);
+ break;
+ case 0x0230:
+ bufpush(0x0231);
+ break;
+ case 0x0232:
+ bufpush(0x0233);
+ break;
+ case 0x0345:
+ bufpush(0x03B9);
+ break;
+ case 0x0386:
+ bufpush(0x03AC);
+ break;
+ case 0x0388:
+ bufpush(0x03AD);
+ break;
+ case 0x0389:
+ bufpush(0x03AE);
+ break;
+ case 0x038A:
+ bufpush(0x03AF);
+ break;
+ case 0x038C:
+ bufpush(0x03CC);
+ break;
+ case 0x038E:
+ bufpush(0x03CD);
+ break;
+ case 0x038F:
+ bufpush(0x03CE);
+ break;
+ case 0x0390:
+ bufpush(0x03B9);
+ bufpush(0x0308);
+ bufpush(0x0301);
+ break;
+ case 0x0391:
+ bufpush(0x03B1);
+ break;
+ case 0x0392:
+ bufpush(0x03B2);
+ break;
+ case 0x0393:
+ bufpush(0x03B3);
+ break;
+ case 0x0394:
+ bufpush(0x03B4);
+ break;
+ case 0x0395:
+ bufpush(0x03B5);
+ break;
+ case 0x0396:
+ bufpush(0x03B6);
+ break;
+ case 0x0397:
+ bufpush(0x03B7);
+ break;
+ case 0x0398:
+ bufpush(0x03B8);
+ break;
+ case 0x0399:
+ bufpush(0x03B9);
+ break;
+ case 0x039A:
+ bufpush(0x03BA);
+ break;
+ case 0x039B:
+ bufpush(0x03BB);
+ break;
+ case 0x039C:
+ bufpush(0x03BC);
+ break;
+ case 0x039D:
+ bufpush(0x03BD);
+ break;
+ case 0x039E:
+ bufpush(0x03BE);
+ break;
+ case 0x039F:
+ bufpush(0x03BF);
+ break;
+ case 0x03A0:
+ bufpush(0x03C0);
+ break;
+ case 0x03A1:
+ bufpush(0x03C1);
+ break;
+ case 0x03A3:
+ bufpush(0x03C3);
+ break;
+ case 0x03A4:
+ bufpush(0x03C4);
+ break;
+ case 0x03A5:
+ bufpush(0x03C5);
+ break;
+ case 0x03A6:
+ bufpush(0x03C6);
+ break;
+ case 0x03A7:
+ bufpush(0x03C7);
+ break;
+ case 0x03A8:
+ bufpush(0x03C8);
+ break;
+ case 0x03A9:
+ bufpush(0x03C9);
+ break;
+ case 0x03AA:
+ bufpush(0x03CA);
+ break;
+ case 0x03AB:
+ bufpush(0x03CB);
+ break;
+ case 0x03B0:
+ bufpush(0x03C5);
+ bufpush(0x0308);
+ bufpush(0x0301);
+ break;
+ case 0x03C2:
+ bufpush(0x03C3);
+ break;
+ case 0x03D0:
+ bufpush(0x03B2);
+ break;
+ case 0x03D1:
+ bufpush(0x03B8);
+ break;
+ case 0x03D5:
+ bufpush(0x03C6);
+ break;
+ case 0x03D6:
+ bufpush(0x03C0);
+ break;
+ case 0x03D8:
+ bufpush(0x03D9);
+ break;
+ case 0x03DA:
+ bufpush(0x03DB);
+ break;
+ case 0x03DC:
+ bufpush(0x03DD);
+ break;
+ case 0x03DE:
+ bufpush(0x03DF);
+ break;
+ case 0x03E0:
+ bufpush(0x03E1);
+ break;
+ case 0x03E2:
+ bufpush(0x03E3);
+ break;
+ case 0x03E4:
+ bufpush(0x03E5);
+ break;
+ case 0x03E6:
+ bufpush(0x03E7);
+ break;
+ case 0x03E8:
+ bufpush(0x03E9);
+ break;
+ case 0x03EA:
+ bufpush(0x03EB);
+ break;
+ case 0x03EC:
+ bufpush(0x03ED);
+ break;
+ case 0x03EE:
+ bufpush(0x03EF);
+ break;
+ case 0x03F0:
+ bufpush(0x03BA);
+ break;
+ case 0x03F1:
+ bufpush(0x03C1);
+ break;
+ case 0x03F2:
+ bufpush(0x03C3);
+ break;
+ case 0x03F4:
+ bufpush(0x03B8);
+ break;
+ case 0x03F5:
+ bufpush(0x03B5);
+ break;
+ case 0x0400:
+ bufpush(0x0450);
+ break;
+ case 0x0401:
+ bufpush(0x0451);
+ break;
+ case 0x0402:
+ bufpush(0x0452);
+ break;
+ case 0x0403:
+ bufpush(0x0453);
+ break;
+ case 0x0404:
+ bufpush(0x0454);
+ break;
+ case 0x0405:
+ bufpush(0x0455);
+ break;
+ case 0x0406:
+ bufpush(0x0456);
+ break;
+ case 0x0407:
+ bufpush(0x0457);
+ break;
+ case 0x0408:
+ bufpush(0x0458);
+ break;
+ case 0x0409:
+ bufpush(0x0459);
+ break;
+ case 0x040A:
+ bufpush(0x045A);
+ break;
+ case 0x040B:
+ bufpush(0x045B);
+ break;
+ case 0x040C:
+ bufpush(0x045C);
+ break;
+ case 0x040D:
+ bufpush(0x045D);
+ break;
+ case 0x040E:
+ bufpush(0x045E);
+ break;
+ case 0x040F:
+ bufpush(0x045F);
+ break;
+ case 0x0410:
+ bufpush(0x0430);
+ break;
+ case 0x0411:
+ bufpush(0x0431);
+ break;
+ case 0x0412:
+ bufpush(0x0432);
+ break;
+ case 0x0413:
+ bufpush(0x0433);
+ break;
+ case 0x0414:
+ bufpush(0x0434);
+ break;
+ case 0x0415:
+ bufpush(0x0435);
+ break;
+ case 0x0416:
+ bufpush(0x0436);
+ break;
+ case 0x0417:
+ bufpush(0x0437);
+ break;
+ case 0x0418:
+ bufpush(0x0438);
+ break;
+ case 0x0419:
+ bufpush(0x0439);
+ break;
+ case 0x041A:
+ bufpush(0x043A);
+ break;
+ case 0x041B:
+ bufpush(0x043B);
+ break;
+ case 0x041C:
+ bufpush(0x043C);
+ break;
+ case 0x041D:
+ bufpush(0x043D);
+ break;
+ case 0x041E:
+ bufpush(0x043E);
+ break;
+ case 0x041F:
+ bufpush(0x043F);
+ break;
+ case 0x0420:
+ bufpush(0x0440);
+ break;
+ case 0x0421:
+ bufpush(0x0441);
+ break;
+ case 0x0422:
+ bufpush(0x0442);
+ break;
+ case 0x0423:
+ bufpush(0x0443);
+ break;
+ case 0x0424:
+ bufpush(0x0444);
+ break;
+ case 0x0425:
+ bufpush(0x0445);
+ break;
+ case 0x0426:
+ bufpush(0x0446);
+ break;
+ case 0x0427:
+ bufpush(0x0447);
+ break;
+ case 0x0428:
+ bufpush(0x0448);
+ break;
+ case 0x0429:
+ bufpush(0x0449);
+ break;
+ case 0x042A:
+ bufpush(0x044A);
+ break;
+ case 0x042B:
+ bufpush(0x044B);
+ break;
+ case 0x042C:
+ bufpush(0x044C);
+ break;
+ case 0x042D:
+ bufpush(0x044D);
+ break;
+ case 0x042E:
+ bufpush(0x044E);
+ break;
+ case 0x042F:
+ bufpush(0x044F);
+ break;
+ case 0x0460:
+ bufpush(0x0461);
+ break;
+ case 0x0462:
+ bufpush(0x0463);
+ break;
+ case 0x0464:
+ bufpush(0x0465);
+ break;
+ case 0x0466:
+ bufpush(0x0467);
+ break;
+ case 0x0468:
+ bufpush(0x0469);
+ break;
+ case 0x046A:
+ bufpush(0x046B);
+ break;
+ case 0x046C:
+ bufpush(0x046D);
+ break;
+ case 0x046E:
+ bufpush(0x046F);
+ break;
+ case 0x0470:
+ bufpush(0x0471);
+ break;
+ case 0x0472:
+ bufpush(0x0473);
+ break;
+ case 0x0474:
+ bufpush(0x0475);
+ break;
+ case 0x0476:
+ bufpush(0x0477);
+ break;
+ case 0x0478:
+ bufpush(0x0479);
+ break;
+ case 0x047A:
+ bufpush(0x047B);
+ break;
+ case 0x047C:
+ bufpush(0x047D);
+ break;
+ case 0x047E:
+ bufpush(0x047F);
+ break;
+ case 0x0480:
+ bufpush(0x0481);
+ break;
+ case 0x048A:
+ bufpush(0x048B);
+ break;
+ case 0x048C:
+ bufpush(0x048D);
+ break;
+ case 0x048E:
+ bufpush(0x048F);
+ break;
+ case 0x0490:
+ bufpush(0x0491);
+ break;
+ case 0x0492:
+ bufpush(0x0493);
+ break;
+ case 0x0494:
+ bufpush(0x0495);
+ break;
+ case 0x0496:
+ bufpush(0x0497);
+ break;
+ case 0x0498:
+ bufpush(0x0499);
+ break;
+ case 0x049A:
+ bufpush(0x049B);
+ break;
+ case 0x049C:
+ bufpush(0x049D);
+ break;
+ case 0x049E:
+ bufpush(0x049F);
+ break;
+ case 0x04A0:
+ bufpush(0x04A1);
+ break;
+ case 0x04A2:
+ bufpush(0x04A3);
+ break;
+ case 0x04A4:
+ bufpush(0x04A5);
+ break;
+ case 0x04A6:
+ bufpush(0x04A7);
+ break;
+ case 0x04A8:
+ bufpush(0x04A9);
+ break;
+ case 0x04AA:
+ bufpush(0x04AB);
+ break;
+ case 0x04AC:
+ bufpush(0x04AD);
+ break;
+ case 0x04AE:
+ bufpush(0x04AF);
+ break;
+ case 0x04B0:
+ bufpush(0x04B1);
+ break;
+ case 0x04B2:
+ bufpush(0x04B3);
+ break;
+ case 0x04B4:
+ bufpush(0x04B5);
+ break;
+ case 0x04B6:
+ bufpush(0x04B7);
+ break;
+ case 0x04B8:
+ bufpush(0x04B9);
+ break;
+ case 0x04BA:
+ bufpush(0x04BB);
+ break;
+ case 0x04BC:
+ bufpush(0x04BD);
+ break;
+ case 0x04BE:
+ bufpush(0x04BF);
+ break;
+ case 0x04C1:
+ bufpush(0x04C2);
+ break;
+ case 0x04C3:
+ bufpush(0x04C4);
+ break;
+ case 0x04C5:
+ bufpush(0x04C6);
+ break;
+ case 0x04C7:
+ bufpush(0x04C8);
+ break;
+ case 0x04C9:
+ bufpush(0x04CA);
+ break;
+ case 0x04CB:
+ bufpush(0x04CC);
+ break;
+ case 0x04CD:
+ bufpush(0x04CE);
+ break;
+ case 0x04D0:
+ bufpush(0x04D1);
+ break;
+ case 0x04D2:
+ bufpush(0x04D3);
+ break;
+ case 0x04D4:
+ bufpush(0x04D5);
+ break;
+ case 0x04D6:
+ bufpush(0x04D7);
+ break;
+ case 0x04D8:
+ bufpush(0x04D9);
+ break;
+ case 0x04DA:
+ bufpush(0x04DB);
+ break;
+ case 0x04DC:
+ bufpush(0x04DD);
+ break;
+ case 0x04DE:
+ bufpush(0x04DF);
+ break;
+ case 0x04E0:
+ bufpush(0x04E1);
+ break;
+ case 0x04E2:
+ bufpush(0x04E3);
+ break;
+ case 0x04E4:
+ bufpush(0x04E5);
+ break;
+ case 0x04E6:
+ bufpush(0x04E7);
+ break;
+ case 0x04E8:
+ bufpush(0x04E9);
+ break;
+ case 0x04EA:
+ bufpush(0x04EB);
+ break;
+ case 0x04EC:
+ bufpush(0x04ED);
+ break;
+ case 0x04EE:
+ bufpush(0x04EF);
+ break;
+ case 0x04F0:
+ bufpush(0x04F1);
+ break;
+ case 0x04F2:
+ bufpush(0x04F3);
+ break;
+ case 0x04F4:
+ bufpush(0x04F5);
+ break;
+ case 0x04F8:
+ bufpush(0x04F9);
+ break;
+ case 0x0500:
+ bufpush(0x0501);
+ break;
+ case 0x0502:
+ bufpush(0x0503);
+ break;
+ case 0x0504:
+ bufpush(0x0505);
+ break;
+ case 0x0506:
+ bufpush(0x0507);
+ break;
+ case 0x0508:
+ bufpush(0x0509);
+ break;
+ case 0x050A:
+ bufpush(0x050B);
+ break;
+ case 0x050C:
+ bufpush(0x050D);
+ break;
+ case 0x050E:
+ bufpush(0x050F);
+ break;
+ case 0x0531:
+ bufpush(0x0561);
+ break;
+ case 0x0532:
+ bufpush(0x0562);
+ break;
+ case 0x0533:
+ bufpush(0x0563);
+ break;
+ case 0x0534:
+ bufpush(0x0564);
+ break;
+ case 0x0535:
+ bufpush(0x0565);
+ break;
+ case 0x0536:
+ bufpush(0x0566);
+ break;
+ case 0x0537:
+ bufpush(0x0567);
+ break;
+ case 0x0538:
+ bufpush(0x0568);
+ break;
+ case 0x0539:
+ bufpush(0x0569);
+ break;
+ case 0x053A:
+ bufpush(0x056A);
+ break;
+ case 0x053B:
+ bufpush(0x056B);
+ break;
+ case 0x053C:
+ bufpush(0x056C);
+ break;
+ case 0x053D:
+ bufpush(0x056D);
+ break;
+ case 0x053E:
+ bufpush(0x056E);
+ break;
+ case 0x053F:
+ bufpush(0x056F);
+ break;
+ case 0x0540:
+ bufpush(0x0570);
+ break;
+ case 0x0541:
+ bufpush(0x0571);
+ break;
+ case 0x0542:
+ bufpush(0x0572);
+ break;
+ case 0x0543:
+ bufpush(0x0573);
+ break;
+ case 0x0544:
+ bufpush(0x0574);
+ break;
+ case 0x0545:
+ bufpush(0x0575);
+ break;
+ case 0x0546:
+ bufpush(0x0576);
+ break;
+ case 0x0547:
+ bufpush(0x0577);
+ break;
+ case 0x0548:
+ bufpush(0x0578);
+ break;
+ case 0x0549:
+ bufpush(0x0579);
+ break;
+ case 0x054A:
+ bufpush(0x057A);
+ break;
+ case 0x054B:
+ bufpush(0x057B);
+ break;
+ case 0x054C:
+ bufpush(0x057C);
+ break;
+ case 0x054D:
+ bufpush(0x057D);
+ break;
+ case 0x054E:
+ bufpush(0x057E);
+ break;
+ case 0x054F:
+ bufpush(0x057F);
+ break;
+ case 0x0550:
+ bufpush(0x0580);
+ break;
+ case 0x0551:
+ bufpush(0x0581);
+ break;
+ case 0x0552:
+ bufpush(0x0582);
+ break;
+ case 0x0553:
+ bufpush(0x0583);
+ break;
+ case 0x0554:
+ bufpush(0x0584);
+ break;
+ case 0x0555:
+ bufpush(0x0585);
+ break;
+ case 0x0556:
+ bufpush(0x0586);
+ break;
+ case 0x0587:
+ bufpush(0x0565);
+ bufpush(0x0582);
+ break;
+ case 0x1E00:
+ bufpush(0x1E01);
+ break;
+ case 0x1E02:
+ bufpush(0x1E03);
+ break;
+ case 0x1E04:
+ bufpush(0x1E05);
+ break;
+ case 0x1E06:
+ bufpush(0x1E07);
+ break;
+ case 0x1E08:
+ bufpush(0x1E09);
+ break;
+ case 0x1E0A:
+ bufpush(0x1E0B);
+ break;
+ case 0x1E0C:
+ bufpush(0x1E0D);
+ break;
+ case 0x1E0E:
+ bufpush(0x1E0F);
+ break;
+ case 0x1E10:
+ bufpush(0x1E11);
+ break;
+ case 0x1E12:
+ bufpush(0x1E13);
+ break;
+ case 0x1E14:
+ bufpush(0x1E15);
+ break;
+ case 0x1E16:
+ bufpush(0x1E17);
+ break;
+ case 0x1E18:
+ bufpush(0x1E19);
+ break;
+ case 0x1E1A:
+ bufpush(0x1E1B);
+ break;
+ case 0x1E1C:
+ bufpush(0x1E1D);
+ break;
+ case 0x1E1E:
+ bufpush(0x1E1F);
+ break;
+ case 0x1E20:
+ bufpush(0x1E21);
+ break;
+ case 0x1E22:
+ bufpush(0x1E23);
+ break;
+ case 0x1E24:
+ bufpush(0x1E25);
+ break;
+ case 0x1E26:
+ bufpush(0x1E27);
+ break;
+ case 0x1E28:
+ bufpush(0x1E29);
+ break;
+ case 0x1E2A:
+ bufpush(0x1E2B);
+ break;
+ case 0x1E2C:
+ bufpush(0x1E2D);
+ break;
+ case 0x1E2E:
+ bufpush(0x1E2F);
+ break;
+ case 0x1E30:
+ bufpush(0x1E31);
+ break;
+ case 0x1E32:
+ bufpush(0x1E33);
+ break;
+ case 0x1E34:
+ bufpush(0x1E35);
+ break;
+ case 0x1E36:
+ bufpush(0x1E37);
+ break;
+ case 0x1E38:
+ bufpush(0x1E39);
+ break;
+ case 0x1E3A:
+ bufpush(0x1E3B);
+ break;
+ case 0x1E3C:
+ bufpush(0x1E3D);
+ break;
+ case 0x1E3E:
+ bufpush(0x1E3F);
+ break;
+ case 0x1E40:
+ bufpush(0x1E41);
+ break;
+ case 0x1E42:
+ bufpush(0x1E43);
+ break;
+ case 0x1E44:
+ bufpush(0x1E45);
+ break;
+ case 0x1E46:
+ bufpush(0x1E47);
+ break;
+ case 0x1E48:
+ bufpush(0x1E49);
+ break;
+ case 0x1E4A:
+ bufpush(0x1E4B);
+ break;
+ case 0x1E4C:
+ bufpush(0x1E4D);
+ break;
+ case 0x1E4E:
+ bufpush(0x1E4F);
+ break;
+ case 0x1E50:
+ bufpush(0x1E51);
+ break;
+ case 0x1E52:
+ bufpush(0x1E53);
+ break;
+ case 0x1E54:
+ bufpush(0x1E55);
+ break;
+ case 0x1E56:
+ bufpush(0x1E57);
+ break;
+ case 0x1E58:
+ bufpush(0x1E59);
+ break;
+ case 0x1E5A:
+ bufpush(0x1E5B);
+ break;
+ case 0x1E5C:
+ bufpush(0x1E5D);
+ break;
+ case 0x1E5E:
+ bufpush(0x1E5F);
+ break;
+ case 0x1E60:
+ bufpush(0x1E61);
+ break;
+ case 0x1E62:
+ bufpush(0x1E63);
+ break;
+ case 0x1E64:
+ bufpush(0x1E65);
+ break;
+ case 0x1E66:
+ bufpush(0x1E67);
+ break;
+ case 0x1E68:
+ bufpush(0x1E69);
+ break;
+ case 0x1E6A:
+ bufpush(0x1E6B);
+ break;
+ case 0x1E6C:
+ bufpush(0x1E6D);
+ break;
+ case 0x1E6E:
+ bufpush(0x1E6F);
+ break;
+ case 0x1E70:
+ bufpush(0x1E71);
+ break;
+ case 0x1E72:
+ bufpush(0x1E73);
+ break;
+ case 0x1E74:
+ bufpush(0x1E75);
+ break;
+ case 0x1E76:
+ bufpush(0x1E77);
+ break;
+ case 0x1E78:
+ bufpush(0x1E79);
+ break;
+ case 0x1E7A:
+ bufpush(0x1E7B);
+ break;
+ case 0x1E7C:
+ bufpush(0x1E7D);
+ break;
+ case 0x1E7E:
+ bufpush(0x1E7F);
+ break;
+ case 0x1E80:
+ bufpush(0x1E81);
+ break;
+ case 0x1E82:
+ bufpush(0x1E83);
+ break;
+ case 0x1E84:
+ bufpush(0x1E85);
+ break;
+ case 0x1E86:
+ bufpush(0x1E87);
+ break;
+ case 0x1E88:
+ bufpush(0x1E89);
+ break;
+ case 0x1E8A:
+ bufpush(0x1E8B);
+ break;
+ case 0x1E8C:
+ bufpush(0x1E8D);
+ break;
+ case 0x1E8E:
+ bufpush(0x1E8F);
+ break;
+ case 0x1E90:
+ bufpush(0x1E91);
+ break;
+ case 0x1E92:
+ bufpush(0x1E93);
+ break;
+ case 0x1E94:
+ bufpush(0x1E95);
+ break;
+ case 0x1E96:
+ bufpush(0x0068);
+ bufpush(0x0331);
+ break;
+ case 0x1E97:
+ bufpush(0x0074);
+ bufpush(0x0308);
+ break;
+ case 0x1E98:
+ bufpush(0x0077);
+ bufpush(0x030A);
+ break;
+ case 0x1E99:
+ bufpush(0x0079);
+ bufpush(0x030A);
+ break;
+ case 0x1E9A:
+ bufpush(0x0061);
+ bufpush(0x02BE);
+ break;
+ case 0x1E9B:
+ bufpush(0x1E61);
+ break;
+ case 0x1EA0:
+ bufpush(0x1EA1);
+ break;
+ case 0x1EA2:
+ bufpush(0x1EA3);
+ break;
+ case 0x1EA4:
+ bufpush(0x1EA5);
+ break;
+ case 0x1EA6:
+ bufpush(0x1EA7);
+ break;
+ case 0x1EA8:
+ bufpush(0x1EA9);
+ break;
+ case 0x1EAA:
+ bufpush(0x1EAB);
+ break;
+ case 0x1EAC:
+ bufpush(0x1EAD);
+ break;
+ case 0x1EAE:
+ bufpush(0x1EAF);
+ break;
+ case 0x1EB0:
+ bufpush(0x1EB1);
+ break;
+ case 0x1EB2:
+ bufpush(0x1EB3);
+ break;
+ case 0x1EB4:
+ bufpush(0x1EB5);
+ break;
+ case 0x1EB6:
+ bufpush(0x1EB7);
+ break;
+ case 0x1EB8:
+ bufpush(0x1EB9);
+ break;
+ case 0x1EBA:
+ bufpush(0x1EBB);
+ break;
+ case 0x1EBC:
+ bufpush(0x1EBD);
+ break;
+ case 0x1EBE:
+ bufpush(0x1EBF);
+ break;
+ case 0x1EC0:
+ bufpush(0x1EC1);
+ break;
+ case 0x1EC2:
+ bufpush(0x1EC3);
+ break;
+ case 0x1EC4:
+ bufpush(0x1EC5);
+ break;
+ case 0x1EC6:
+ bufpush(0x1EC7);
+ break;
+ case 0x1EC8:
+ bufpush(0x1EC9);
+ break;
+ case 0x1ECA:
+ bufpush(0x1ECB);
+ break;
+ case 0x1ECC:
+ bufpush(0x1ECD);
+ break;
+ case 0x1ECE:
+ bufpush(0x1ECF);
+ break;
+ case 0x1ED0:
+ bufpush(0x1ED1);
+ break;
+ case 0x1ED2:
+ bufpush(0x1ED3);
+ break;
+ case 0x1ED4:
+ bufpush(0x1ED5);
+ break;
+ case 0x1ED6:
+ bufpush(0x1ED7);
+ break;
+ case 0x1ED8:
+ bufpush(0x1ED9);
+ break;
+ case 0x1EDA:
+ bufpush(0x1EDB);
+ break;
+ case 0x1EDC:
+ bufpush(0x1EDD);
+ break;
+ case 0x1EDE:
+ bufpush(0x1EDF);
+ break;
+ case 0x1EE0:
+ bufpush(0x1EE1);
+ break;
+ case 0x1EE2:
+ bufpush(0x1EE3);
+ break;
+ case 0x1EE4:
+ bufpush(0x1EE5);
+ break;
+ case 0x1EE6:
+ bufpush(0x1EE7);
+ break;
+ case 0x1EE8:
+ bufpush(0x1EE9);
+ break;
+ case 0x1EEA:
+ bufpush(0x1EEB);
+ break;
+ case 0x1EEC:
+ bufpush(0x1EED);
+ break;
+ case 0x1EEE:
+ bufpush(0x1EEF);
+ break;
+ case 0x1EF0:
+ bufpush(0x1EF1);
+ break;
+ case 0x1EF2:
+ bufpush(0x1EF3);
+ break;
+ case 0x1EF4:
+ bufpush(0x1EF5);
+ break;
+ case 0x1EF6:
+ bufpush(0x1EF7);
+ break;
+ case 0x1EF8:
+ bufpush(0x1EF9);
+ break;
+ case 0x1F08:
+ bufpush(0x1F00);
+ break;
+ case 0x1F09:
+ bufpush(0x1F01);
+ break;
+ case 0x1F0A:
+ bufpush(0x1F02);
+ break;
+ case 0x1F0B:
+ bufpush(0x1F03);
+ break;
+ case 0x1F0C:
+ bufpush(0x1F04);
+ break;
+ case 0x1F0D:
+ bufpush(0x1F05);
+ break;
+ case 0x1F0E:
+ bufpush(0x1F06);
+ break;
+ case 0x1F0F:
+ bufpush(0x1F07);
+ break;
+ case 0x1F18:
+ bufpush(0x1F10);
+ break;
+ case 0x1F19:
+ bufpush(0x1F11);
+ break;
+ case 0x1F1A:
+ bufpush(0x1F12);
+ break;
+ case 0x1F1B:
+ bufpush(0x1F13);
+ break;
+ case 0x1F1C:
+ bufpush(0x1F14);
+ break;
+ case 0x1F1D:
+ bufpush(0x1F15);
+ break;
+ case 0x1F28:
+ bufpush(0x1F20);
+ break;
+ case 0x1F29:
+ bufpush(0x1F21);
+ break;
+ case 0x1F2A:
+ bufpush(0x1F22);
+ break;
+ case 0x1F2B:
+ bufpush(0x1F23);
+ break;
+ case 0x1F2C:
+ bufpush(0x1F24);
+ break;
+ case 0x1F2D:
+ bufpush(0x1F25);
+ break;
+ case 0x1F2E:
+ bufpush(0x1F26);
+ break;
+ case 0x1F2F:
+ bufpush(0x1F27);
+ break;
+ case 0x1F38:
+ bufpush(0x1F30);
+ break;
+ case 0x1F39:
+ bufpush(0x1F31);
+ break;
+ case 0x1F3A:
+ bufpush(0x1F32);
+ break;
+ case 0x1F3B:
+ bufpush(0x1F33);
+ break;
+ case 0x1F3C:
+ bufpush(0x1F34);
+ break;
+ case 0x1F3D:
+ bufpush(0x1F35);
+ break;
+ case 0x1F3E:
+ bufpush(0x1F36);
+ break;
+ case 0x1F3F:
+ bufpush(0x1F37);
+ break;
+ case 0x1F48:
+ bufpush(0x1F40);
+ break;
+ case 0x1F49:
+ bufpush(0x1F41);
+ break;
+ case 0x1F4A:
+ bufpush(0x1F42);
+ break;
+ case 0x1F4B:
+ bufpush(0x1F43);
+ break;
+ case 0x1F4C:
+ bufpush(0x1F44);
+ break;
+ case 0x1F4D:
+ bufpush(0x1F45);
+ break;
+ case 0x1F50:
+ bufpush(0x03C5);
+ bufpush(0x0313);
+ break;
+ case 0x1F52:
+ bufpush(0x03C5);
+ bufpush(0x0313);
+ bufpush(0x0300);
+ break;
+ case 0x1F54:
+ bufpush(0x03C5);
+ bufpush(0x0313);
+ bufpush(0x0301);
+ break;
+ case 0x1F56:
+ bufpush(0x03C5);
+ bufpush(0x0313);
+ bufpush(0x0342);
+ break;
+ case 0x1F59:
+ bufpush(0x1F51);
+ break;
+ case 0x1F5B:
+ bufpush(0x1F53);
+ break;
+ case 0x1F5D:
+ bufpush(0x1F55);
+ break;
+ case 0x1F5F:
+ bufpush(0x1F57);
+ break;
+ case 0x1F68:
+ bufpush(0x1F60);
+ break;
+ case 0x1F69:
+ bufpush(0x1F61);
+ break;
+ case 0x1F6A:
+ bufpush(0x1F62);
+ break;
+ case 0x1F6B:
+ bufpush(0x1F63);
+ break;
+ case 0x1F6C:
+ bufpush(0x1F64);
+ break;
+ case 0x1F6D:
+ bufpush(0x1F65);
+ break;
+ case 0x1F6E:
+ bufpush(0x1F66);
+ break;
+ case 0x1F6F:
+ bufpush(0x1F67);
+ break;
+ case 0x1F80:
+ bufpush(0x1F00);
+ bufpush(0x03B9);
+ break;
+ case 0x1F81:
+ bufpush(0x1F01);
+ bufpush(0x03B9);
+ break;
+ case 0x1F82:
+ bufpush(0x1F02);
+ bufpush(0x03B9);
+ break;
+ case 0x1F83:
+ bufpush(0x1F03);
+ bufpush(0x03B9);
+ break;
+ case 0x1F84:
+ bufpush(0x1F04);
+ bufpush(0x03B9);
+ break;
+ case 0x1F85:
+ bufpush(0x1F05);
+ bufpush(0x03B9);
+ break;
+ case 0x1F86:
+ bufpush(0x1F06);
+ bufpush(0x03B9);
+ break;
+ case 0x1F87:
+ bufpush(0x1F07);
+ bufpush(0x03B9);
+ break;
+ case 0x1F88:
+ bufpush(0x1F00);
+ bufpush(0x03B9);
+ break;
+ case 0x1F89:
+ bufpush(0x1F01);
+ bufpush(0x03B9);
+ break;
+ case 0x1F8A:
+ bufpush(0x1F02);
+ bufpush(0x03B9);
+ break;
+ case 0x1F8B:
+ bufpush(0x1F03);
+ bufpush(0x03B9);
+ break;
+ case 0x1F8C:
+ bufpush(0x1F04);
+ bufpush(0x03B9);
+ break;
+ case 0x1F8D:
+ bufpush(0x1F05);
+ bufpush(0x03B9);
+ break;
+ case 0x1F8E:
+ bufpush(0x1F06);
+ bufpush(0x03B9);
+ break;
+ case 0x1F8F:
+ bufpush(0x1F07);
+ bufpush(0x03B9);
+ break;
+ case 0x1F90:
+ bufpush(0x1F20);
+ bufpush(0x03B9);
+ break;
+ case 0x1F91:
+ bufpush(0x1F21);
+ bufpush(0x03B9);
+ break;
+ case 0x1F92:
+ bufpush(0x1F22);
+ bufpush(0x03B9);
+ break;
+ case 0x1F93:
+ bufpush(0x1F23);
+ bufpush(0x03B9);
+ break;
+ case 0x1F94:
+ bufpush(0x1F24);
+ bufpush(0x03B9);
+ break;
+ case 0x1F95:
+ bufpush(0x1F25);
+ bufpush(0x03B9);
+ break;
+ case 0x1F96:
+ bufpush(0x1F26);
+ bufpush(0x03B9);
+ break;
+ case 0x1F97:
+ bufpush(0x1F27);
+ bufpush(0x03B9);
+ break;
+ case 0x1F98:
+ bufpush(0x1F20);
+ bufpush(0x03B9);
+ break;
+ case 0x1F99:
+ bufpush(0x1F21);
+ bufpush(0x03B9);
+ break;
+ case 0x1F9A:
+ bufpush(0x1F22);
+ bufpush(0x03B9);
+ break;
+ case 0x1F9B:
+ bufpush(0x1F23);
+ bufpush(0x03B9);
+ break;
+ case 0x1F9C:
+ bufpush(0x1F24);
+ bufpush(0x03B9);
+ break;
+ case 0x1F9D:
+ bufpush(0x1F25);
+ bufpush(0x03B9);
+ break;
+ case 0x1F9E:
+ bufpush(0x1F26);
+ bufpush(0x03B9);
+ break;
+ case 0x1F9F:
+ bufpush(0x1F27);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA0:
+ bufpush(0x1F60);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA1:
+ bufpush(0x1F61);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA2:
+ bufpush(0x1F62);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA3:
+ bufpush(0x1F63);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA4:
+ bufpush(0x1F64);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA5:
+ bufpush(0x1F65);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA6:
+ bufpush(0x1F66);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA7:
+ bufpush(0x1F67);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA8:
+ bufpush(0x1F60);
+ bufpush(0x03B9);
+ break;
+ case 0x1FA9:
+ bufpush(0x1F61);
+ bufpush(0x03B9);
+ break;
+ case 0x1FAA:
+ bufpush(0x1F62);
+ bufpush(0x03B9);
+ break;
+ case 0x1FAB:
+ bufpush(0x1F63);
+ bufpush(0x03B9);
+ break;
+ case 0x1FAC:
+ bufpush(0x1F64);
+ bufpush(0x03B9);
+ break;
+ case 0x1FAD:
+ bufpush(0x1F65);
+ bufpush(0x03B9);
+ break;
+ case 0x1FAE:
+ bufpush(0x1F66);
+ bufpush(0x03B9);
+ break;
+ case 0x1FAF:
+ bufpush(0x1F67);
+ bufpush(0x03B9);
+ break;
+ case 0x1FB2:
+ bufpush(0x1F70);
+ bufpush(0x03B9);
+ break;
+ case 0x1FB3:
+ bufpush(0x03B1);
+ bufpush(0x03B9);
+ break;
+ case 0x1FB4:
+ bufpush(0x03AC);
+ bufpush(0x03B9);
+ break;
+ case 0x1FB6:
+ bufpush(0x03B1);
+ bufpush(0x0342);
+ break;
+ case 0x1FB7:
+ bufpush(0x03B1);
+ bufpush(0x0342);
+ bufpush(0x03B9);
+ break;
+ case 0x1FB8:
+ bufpush(0x1FB0);
+ break;
+ case 0x1FB9:
+ bufpush(0x1FB1);
+ break;
+ case 0x1FBA:
+ bufpush(0x1F70);
+ break;
+ case 0x1FBB:
+ bufpush(0x1F71);
+ break;
+ case 0x1FBC:
+ bufpush(0x03B1);
+ bufpush(0x03B9);
+ break;
+ case 0x1FBE:
+ bufpush(0x03B9);
+ break;
+ case 0x1FC2:
+ bufpush(0x1F74);
+ bufpush(0x03B9);
+ break;
+ case 0x1FC3:
+ bufpush(0x03B7);
+ bufpush(0x03B9);
+ break;
+ case 0x1FC4:
+ bufpush(0x03AE);
+ bufpush(0x03B9);
+ break;
+ case 0x1FC6:
+ bufpush(0x03B7);
+ bufpush(0x0342);
+ break;
+ case 0x1FC7:
+ bufpush(0x03B7);
+ bufpush(0x0342);
+ bufpush(0x03B9);
+ break;
+ case 0x1FC8:
+ bufpush(0x1F72);
+ break;
+ case 0x1FC9:
+ bufpush(0x1F73);
+ break;
+ case 0x1FCA:
+ bufpush(0x1F74);
+ break;
+ case 0x1FCB:
+ bufpush(0x1F75);
+ break;
+ case 0x1FCC:
+ bufpush(0x03B7);
+ bufpush(0x03B9);
+ break;
+ case 0x1FD2:
+ bufpush(0x03B9);
+ bufpush(0x0308);
+ bufpush(0x0300);
+ break;
+ case 0x1FD3:
+ bufpush(0x03B9);
+ bufpush(0x0308);
+ bufpush(0x0301);
+ break;
+ case 0x1FD6:
+ bufpush(0x03B9);
+ bufpush(0x0342);
+ break;
+ case 0x1FD7:
+ bufpush(0x03B9);
+ bufpush(0x0308);
+ bufpush(0x0342);
+ break;
+ case 0x1FD8:
+ bufpush(0x1FD0);
+ break;
+ case 0x1FD9:
+ bufpush(0x1FD1);
+ break;
+ case 0x1FDA:
+ bufpush(0x1F76);
+ break;
+ case 0x1FDB:
+ bufpush(0x1F77);
+ break;
+ case 0x1FE2:
+ bufpush(0x03C5);
+ bufpush(0x0308);
+ bufpush(0x0300);
+ break;
+ case 0x1FE3:
+ bufpush(0x03C5);
+ bufpush(0x0308);
+ bufpush(0x0301);
+ break;
+ case 0x1FE4:
+ bufpush(0x03C1);
+ bufpush(0x0313);
+ break;
+ case 0x1FE6:
+ bufpush(0x03C5);
+ bufpush(0x0342);
+ break;
+ case 0x1FE7:
+ bufpush(0x03C5);
+ bufpush(0x0308);
+ bufpush(0x0342);
+ break;
+ case 0x1FE8:
+ bufpush(0x1FE0);
+ break;
+ case 0x1FE9:
+ bufpush(0x1FE1);
+ break;
+ case 0x1FEA:
+ bufpush(0x1F7A);
+ break;
+ case 0x1FEB:
+ bufpush(0x1F7B);
+ break;
+ case 0x1FEC:
+ bufpush(0x1FE5);
+ break;
+ case 0x1FF2:
+ bufpush(0x1F7C);
+ bufpush(0x03B9);
+ break;
+ case 0x1FF3:
+ bufpush(0x03C9);
+ bufpush(0x03B9);
+ break;
+ case 0x1FF4:
+ bufpush(0x03CE);
+ bufpush(0x03B9);
+ break;
+ case 0x1FF6:
+ bufpush(0x03C9);
+ bufpush(0x0342);
+ break;
+ case 0x1FF7:
+ bufpush(0x03C9);
+ bufpush(0x0342);
+ bufpush(0x03B9);
+ break;
+ case 0x1FF8:
+ bufpush(0x1F78);
+ break;
+ case 0x1FF9:
+ bufpush(0x1F79);
+ break;
+ case 0x1FFA:
+ bufpush(0x1F7C);
+ break;
+ case 0x1FFB:
+ bufpush(0x1F7D);
+ break;
+ case 0x1FFC:
+ bufpush(0x03C9);
+ bufpush(0x03B9);
+ break;
+ case 0x2126:
+ bufpush(0x03C9);
+ break;
+ case 0x212A:
+ bufpush(0x006B);
+ break;
+ case 0x212B:
+ bufpush(0x00E5);
+ break;
+ case 0x2160:
+ bufpush(0x2170);
+ break;
+ case 0x2161:
+ bufpush(0x2171);
+ break;
+ case 0x2162:
+ bufpush(0x2172);
+ break;
+ case 0x2163:
+ bufpush(0x2173);
+ break;
+ case 0x2164:
+ bufpush(0x2174);
+ break;
+ case 0x2165:
+ bufpush(0x2175);
+ break;
+ case 0x2166:
+ bufpush(0x2176);
+ break;
+ case 0x2167:
+ bufpush(0x2177);
+ break;
+ case 0x2168:
+ bufpush(0x2178);
+ break;
+ case 0x2169:
+ bufpush(0x2179);
+ break;
+ case 0x216A:
+ bufpush(0x217A);
+ break;
+ case 0x216B:
+ bufpush(0x217B);
+ break;
+ case 0x216C:
+ bufpush(0x217C);
+ break;
+ case 0x216D:
+ bufpush(0x217D);
+ break;
+ case 0x216E:
+ bufpush(0x217E);
+ break;
+ case 0x216F:
+ bufpush(0x217F);
+ break;
+ case 0x24B6:
+ bufpush(0x24D0);
+ break;
+ case 0x24B7:
+ bufpush(0x24D1);
+ break;
+ case 0x24B8:
+ bufpush(0x24D2);
+ break;
+ case 0x24B9:
+ bufpush(0x24D3);
+ break;
+ case 0x24BA:
+ bufpush(0x24D4);
+ break;
+ case 0x24BB:
+ bufpush(0x24D5);
+ break;
+ case 0x24BC:
+ bufpush(0x24D6);
+ break;
+ case 0x24BD:
+ bufpush(0x24D7);
+ break;
+ case 0x24BE:
+ bufpush(0x24D8);
+ break;
+ case 0x24BF:
+ bufpush(0x24D9);
+ break;
+ case 0x24C0:
+ bufpush(0x24DA);
+ break;
+ case 0x24C1:
+ bufpush(0x24DB);
+ break;
+ case 0x24C2:
+ bufpush(0x24DC);
+ break;
+ case 0x24C3:
+ bufpush(0x24DD);
+ break;
+ case 0x24C4:
+ bufpush(0x24DE);
+ break;
+ case 0x24C5:
+ bufpush(0x24DF);
+ break;
+ case 0x24C6:
+ bufpush(0x24E0);
+ break;
+ case 0x24C7:
+ bufpush(0x24E1);
+ break;
+ case 0x24C8:
+ bufpush(0x24E2);
+ break;
+ case 0x24C9:
+ bufpush(0x24E3);
+ break;
+ case 0x24CA:
+ bufpush(0x24E4);
+ break;
+ case 0x24CB:
+ bufpush(0x24E5);
+ break;
+ case 0x24CC:
+ bufpush(0x24E6);
+ break;
+ case 0x24CD:
+ bufpush(0x24E7);
+ break;
+ case 0x24CE:
+ bufpush(0x24E8);
+ break;
+ case 0x24CF:
+ bufpush(0x24E9);
+ break;
+ case 0xFB00:
+ bufpush(0x0066);
+ bufpush(0x0066);
+ break;
+ case 0xFB01:
+ bufpush(0x0066);
+ bufpush(0x0069);
+ break;
+ case 0xFB02:
+ bufpush(0x0066);
+ bufpush(0x006C);
+ break;
+ case 0xFB03:
+ bufpush(0x0066);
+ bufpush(0x0066);
+ bufpush(0x0069);
+ break;
+ case 0xFB04:
+ bufpush(0x0066);
+ bufpush(0x0066);
+ bufpush(0x006C);
+ break;
+ case 0xFB05:
+ bufpush(0x0073);
+ bufpush(0x0074);
+ break;
+ case 0xFB06:
+ bufpush(0x0073);
+ bufpush(0x0074);
+ break;
+ case 0xFB13:
+ bufpush(0x0574);
+ bufpush(0x0576);
+ break;
+ case 0xFB14:
+ bufpush(0x0574);
+ bufpush(0x0565);
+ break;
+ case 0xFB15:
+ bufpush(0x0574);
+ bufpush(0x056B);
+ break;
+ case 0xFB16:
+ bufpush(0x057E);
+ bufpush(0x0576);
+ break;
+ case 0xFB17:
+ bufpush(0x0574);
+ bufpush(0x056D);
+ break;
+ case 0xFF21:
+ bufpush(0xFF41);
+ break;
+ case 0xFF22:
+ bufpush(0xFF42);
+ break;
+ case 0xFF23:
+ bufpush(0xFF43);
+ break;
+ case 0xFF24:
+ bufpush(0xFF44);
+ break;
+ case 0xFF25:
+ bufpush(0xFF45);
+ break;
+ case 0xFF26:
+ bufpush(0xFF46);
+ break;
+ case 0xFF27:
+ bufpush(0xFF47);
+ break;
+ case 0xFF28:
+ bufpush(0xFF48);
+ break;
+ case 0xFF29:
+ bufpush(0xFF49);
+ break;
+ case 0xFF2A:
+ bufpush(0xFF4A);
+ break;
+ case 0xFF2B:
+ bufpush(0xFF4B);
+ break;
+ case 0xFF2C:
+ bufpush(0xFF4C);
+ break;
+ case 0xFF2D:
+ bufpush(0xFF4D);
+ break;
+ case 0xFF2E:
+ bufpush(0xFF4E);
+ break;
+ case 0xFF2F:
+ bufpush(0xFF4F);
+ break;
+ case 0xFF30:
+ bufpush(0xFF50);
+ break;
+ case 0xFF31:
+ bufpush(0xFF51);
+ break;
+ case 0xFF32:
+ bufpush(0xFF52);
+ break;
+ case 0xFF33:
+ bufpush(0xFF53);
+ break;
+ case 0xFF34:
+ bufpush(0xFF54);
+ break;
+ case 0xFF35:
+ bufpush(0xFF55);
+ break;
+ case 0xFF36:
+ bufpush(0xFF56);
+ break;
+ case 0xFF37:
+ bufpush(0xFF57);
+ break;
+ case 0xFF38:
+ bufpush(0xFF58);
+ break;
+ case 0xFF39:
+ bufpush(0xFF59);
+ break;
+ case 0xFF3A:
+ bufpush(0xFF5A);
+ break;
+ case 0x10400:
+ bufpush(0x10428);
+ break;
+ case 0x10401:
+ bufpush(0x10429);
+ break;
+ case 0x10402:
+ bufpush(0x1042A);
+ break;
+ case 0x10403:
+ bufpush(0x1042B);
+ break;
+ case 0x10404:
+ bufpush(0x1042C);
+ break;
+ case 0x10405:
+ bufpush(0x1042D);
+ break;
+ case 0x10406:
+ bufpush(0x1042E);
+ break;
+ case 0x10407:
+ bufpush(0x1042F);
+ break;
+ case 0x10408:
+ bufpush(0x10430);
+ break;
+ case 0x10409:
+ bufpush(0x10431);
+ break;
+ case 0x1040A:
+ bufpush(0x10432);
+ break;
+ case 0x1040B:
+ bufpush(0x10433);
+ break;
+ case 0x1040C:
+ bufpush(0x10434);
+ break;
+ case 0x1040D:
+ bufpush(0x10435);
+ break;
+ case 0x1040E:
+ bufpush(0x10436);
+ break;
+ case 0x1040F:
+ bufpush(0x10437);
+ break;
+ case 0x10410:
+ bufpush(0x10438);
+ break;
+ case 0x10411:
+ bufpush(0x10439);
+ break;
+ case 0x10412:
+ bufpush(0x1043A);
+ break;
+ case 0x10413:
+ bufpush(0x1043B);
+ break;
+ case 0x10414:
+ bufpush(0x1043C);
+ break;
+ case 0x10415:
+ bufpush(0x1043D);
+ break;
+ case 0x10416:
+ bufpush(0x1043E);
+ break;
+ case 0x10417:
+ bufpush(0x1043F);
+ break;
+ case 0x10418:
+ bufpush(0x10440);
+ break;
+ case 0x10419:
+ bufpush(0x10441);
+ break;
+ case 0x1041A:
+ bufpush(0x10442);
+ break;
+ case 0x1041B:
+ bufpush(0x10443);
+ break;
+ case 0x1041C:
+ bufpush(0x10444);
+ break;
+ case 0x1041D:
+ bufpush(0x10445);
+ break;
+ case 0x1041E:
+ bufpush(0x10446);
+ break;
+ case 0x1041F:
+ bufpush(0x10447);
+ break;
+ case 0x10420:
+ bufpush(0x10448);
+ break;
+ case 0x10421:
+ bufpush(0x10449);
+ break;
+ case 0x10422:
+ bufpush(0x1044A);
+ break;
+ case 0x10423:
+ bufpush(0x1044B);
+ break;
+ case 0x10424:
+ bufpush(0x1044C);
+ break;
+ case 0x10425:
+ bufpush(0x1044D);
+ break;
+ default:
+ bufpush(c);
+ }
diff --git a/src/casefold.c b/src/casefold.c
deleted file mode 100644
index 33f18aa..0000000
--- a/src/casefold.c
+++ /dev/null
@@ -1,2699 +0,0 @@
-#include
-#include
-
-
- switch c {
- case 0x0041:
- bufpush(0x0061);
- break;
- case 0x0042:
- bufpush(0x0062);
- break;
- case 0x0043:
- bufpush(0x0063);
- break;
- case 0x0044:
- bufpush(0x0064);
- break;
- case 0x0045:
- bufpush(0x0065);
- break;
- case 0x0046:
- bufpush(0x0066);
- break;
- case 0x0047:
- bufpush(0x0067);
- break;
- case 0x0048:
- bufpush(0x0068);
- break;
- case 0x0049:
- bufpush(0x0069);
- break;
- case 0x0049:
- bufpush(0x0131);
- break;
- case 0x004A:
- bufpush(0x006A);
- break;
- case 0x004B:
- bufpush(0x006B);
- break;
- case 0x004C:
- bufpush(0x006C);
- break;
- case 0x004D:
- bufpush(0x006D);
- break;
- case 0x004E:
- bufpush(0x006E);
- break;
- case 0x004F:
- bufpush(0x006F);
- break;
- case 0x0050:
- bufpush(0x0070);
- break;
- case 0x0051:
- bufpush(0x0071);
- break;
- case 0x0052:
- bufpush(0x0072);
- break;
- case 0x0053:
- bufpush(0x0073);
- break;
- case 0x0054:
- bufpush(0x0074);
- break;
- case 0x0055:
- bufpush(0x0075);
- break;
- case 0x0056:
- bufpush(0x0076);
- break;
- case 0x0057:
- bufpush(0x0077);
- break;
- case 0x0058:
- bufpush(0x0078);
- break;
- case 0x0059:
- bufpush(0x0079);
- break;
- case 0x005A:
- bufpush(0x007A);
- break;
- case 0x00B5:
- bufpush(0x03BC);
- break;
- case 0x00C0:
- bufpush(0x00E0);
- break;
- case 0x00C1:
- bufpush(0x00E1);
- break;
- case 0x00C2:
- bufpush(0x00E2);
- break;
- case 0x00C3:
- bufpush(0x00E3);
- break;
- case 0x00C4:
- bufpush(0x00E4);
- break;
- case 0x00C5:
- bufpush(0x00E5);
- break;
- case 0x00C6:
- bufpush(0x00E6);
- break;
- case 0x00C7:
- bufpush(0x00E7);
- break;
- case 0x00C8:
- bufpush(0x00E8);
- break;
- case 0x00C9:
- bufpush(0x00E9);
- break;
- case 0x00CA:
- bufpush(0x00EA);
- break;
- case 0x00CB:
- bufpush(0x00EB);
- break;
- case 0x00CC:
- bufpush(0x00EC);
- break;
- case 0x00CD:
- bufpush(0x00ED);
- break;
- case 0x00CE:
- bufpush(0x00EE);
- break;
- case 0x00CF:
- bufpush(0x00EF);
- break;
- case 0x00D0:
- bufpush(0x00F0);
- break;
- case 0x00D1:
- bufpush(0x00F1);
- break;
- case 0x00D2:
- bufpush(0x00F2);
- break;
- case 0x00D3:
- bufpush(0x00F3);
- break;
- case 0x00D4:
- bufpush(0x00F4);
- break;
- case 0x00D5:
- bufpush(0x00F5);
- break;
- case 0x00D6:
- bufpush(0x00F6);
- break;
- case 0x00D8:
- bufpush(0x00F8);
- break;
- case 0x00D9:
- bufpush(0x00F9);
- break;
- case 0x00DA:
- bufpush(0x00FA);
- break;
- case 0x00DB:
- bufpush(0x00FB);
- break;
- case 0x00DC:
- bufpush(0x00FC);
- break;
- case 0x00DD:
- bufpush(0x00FD);
- break;
- case 0x00DE:
- bufpush(0x00FE);
- break;
- case 0x00DF:
- bufpush(0x0073);
- bufpush(0x0073);
- break;
- case 0x0100:
- bufpush(0x0101);
- break;
- case 0x0102:
- bufpush(0x0103);
- break;
- case 0x0104:
- bufpush(0x0105);
- break;
- case 0x0106:
- bufpush(0x0107);
- break;
- case 0x0108:
- bufpush(0x0109);
- break;
- case 0x010A:
- bufpush(0x010B);
- break;
- case 0x010C:
- bufpush(0x010D);
- break;
- case 0x010E:
- bufpush(0x010F);
- break;
- case 0x0110:
- bufpush(0x0111);
- break;
- case 0x0112:
- bufpush(0x0113);
- break;
- case 0x0114:
- bufpush(0x0115);
- break;
- case 0x0116:
- bufpush(0x0117);
- break;
- case 0x0118:
- bufpush(0x0119);
- break;
- case 0x011A:
- bufpush(0x011B);
- break;
- case 0x011C:
- bufpush(0x011D);
- break;
- case 0x011E:
- bufpush(0x011F);
- break;
- case 0x0120:
- bufpush(0x0121);
- break;
- case 0x0122:
- bufpush(0x0123);
- break;
- case 0x0124:
- bufpush(0x0125);
- break;
- case 0x0126:
- bufpush(0x0127);
- break;
- case 0x0128:
- bufpush(0x0129);
- break;
- case 0x012A:
- bufpush(0x012B);
- break;
- case 0x012C:
- bufpush(0x012D);
- break;
- case 0x012E:
- bufpush(0x012F);
- break;
- case 0x0130:
- bufpush(0x0069);
- bufpush(0x0307);
- break;
- case 0x0130:
- bufpush(0x0069);
- break;
- case 0x0132:
- bufpush(0x0133);
- break;
- case 0x0134:
- bufpush(0x0135);
- break;
- case 0x0136:
- bufpush(0x0137);
- break;
- case 0x0139:
- bufpush(0x013A);
- break;
- case 0x013B:
- bufpush(0x013C);
- break;
- case 0x013D:
- bufpush(0x013E);
- break;
- case 0x013F:
- bufpush(0x0140);
- break;
- case 0x0141:
- bufpush(0x0142);
- break;
- case 0x0143:
- bufpush(0x0144);
- break;
- case 0x0145:
- bufpush(0x0146);
- break;
- case 0x0147:
- bufpush(0x0148);
- break;
- case 0x0149:
- bufpush(0x02BC);
- bufpush(0x006E);
- break;
- case 0x014A:
- bufpush(0x014B);
- break;
- case 0x014C:
- bufpush(0x014D);
- break;
- case 0x014E:
- bufpush(0x014F);
- break;
- case 0x0150:
- bufpush(0x0151);
- break;
- case 0x0152:
- bufpush(0x0153);
- break;
- case 0x0154:
- bufpush(0x0155);
- break;
- case 0x0156:
- bufpush(0x0157);
- break;
- case 0x0158:
- bufpush(0x0159);
- break;
- case 0x015A:
- bufpush(0x015B);
- break;
- case 0x015C:
- bufpush(0x015D);
- break;
- case 0x015E:
- bufpush(0x015F);
- break;
- case 0x0160:
- bufpush(0x0161);
- break;
- case 0x0162:
- bufpush(0x0163);
- break;
- case 0x0164:
- bufpush(0x0165);
- break;
- case 0x0166:
- bufpush(0x0167);
- break;
- case 0x0168:
- bufpush(0x0169);
- break;
- case 0x016A:
- bufpush(0x016B);
- break;
- case 0x016C:
- bufpush(0x016D);
- break;
- case 0x016E:
- bufpush(0x016F);
- break;
- case 0x0170:
- bufpush(0x0171);
- break;
- case 0x0172:
- bufpush(0x0173);
- break;
- case 0x0174:
- bufpush(0x0175);
- break;
- case 0x0176:
- bufpush(0x0177);
- break;
- case 0x0178:
- bufpush(0x00FF);
- break;
- case 0x0179:
- bufpush(0x017A);
- break;
- case 0x017B:
- bufpush(0x017C);
- break;
- case 0x017D:
- bufpush(0x017E);
- break;
- case 0x017F:
- bufpush(0x0073);
- break;
- case 0x0181:
- bufpush(0x0253);
- break;
- case 0x0182:
- bufpush(0x0183);
- break;
- case 0x0184:
- bufpush(0x0185);
- break;
- case 0x0186:
- bufpush(0x0254);
- break;
- case 0x0187:
- bufpush(0x0188);
- break;
- case 0x0189:
- bufpush(0x0256);
- break;
- case 0x018A:
- bufpush(0x0257);
- break;
- case 0x018B:
- bufpush(0x018C);
- break;
- case 0x018E:
- bufpush(0x01DD);
- break;
- case 0x018F:
- bufpush(0x0259);
- break;
- case 0x0190:
- bufpush(0x025B);
- break;
- case 0x0191:
- bufpush(0x0192);
- break;
- case 0x0193:
- bufpush(0x0260);
- break;
- case 0x0194:
- bufpush(0x0263);
- break;
- case 0x0196:
- bufpush(0x0269);
- break;
- case 0x0197:
- bufpush(0x0268);
- break;
- case 0x0198:
- bufpush(0x0199);
- break;
- case 0x019C:
- bufpush(0x026F);
- break;
- case 0x019D:
- bufpush(0x0272);
- break;
- case 0x019F:
- bufpush(0x0275);
- break;
- case 0x01A0:
- bufpush(0x01A1);
- break;
- case 0x01A2:
- bufpush(0x01A3);
- break;
- case 0x01A4:
- bufpush(0x01A5);
- break;
- case 0x01A6:
- bufpush(0x0280);
- break;
- case 0x01A7:
- bufpush(0x01A8);
- break;
- case 0x01A9:
- bufpush(0x0283);
- break;
- case 0x01AC:
- bufpush(0x01AD);
- break;
- case 0x01AE:
- bufpush(0x0288);
- break;
- case 0x01AF:
- bufpush(0x01B0);
- break;
- case 0x01B1:
- bufpush(0x028A);
- break;
- case 0x01B2:
- bufpush(0x028B);
- break;
- case 0x01B3:
- bufpush(0x01B4);
- break;
- case 0x01B5:
- bufpush(0x01B6);
- break;
- case 0x01B7:
- bufpush(0x0292);
- break;
- case 0x01B8:
- bufpush(0x01B9);
- break;
- case 0x01BC:
- bufpush(0x01BD);
- break;
- case 0x01C4:
- bufpush(0x01C6);
- break;
- case 0x01C5:
- bufpush(0x01C6);
- break;
- case 0x01C7:
- bufpush(0x01C9);
- break;
- case 0x01C8:
- bufpush(0x01C9);
- break;
- case 0x01CA:
- bufpush(0x01CC);
- break;
- case 0x01CB:
- bufpush(0x01CC);
- break;
- case 0x01CD:
- bufpush(0x01CE);
- break;
- case 0x01CF:
- bufpush(0x01D0);
- break;
- case 0x01D1:
- bufpush(0x01D2);
- break;
- case 0x01D3:
- bufpush(0x01D4);
- break;
- case 0x01D5:
- bufpush(0x01D6);
- break;
- case 0x01D7:
- bufpush(0x01D8);
- break;
- case 0x01D9:
- bufpush(0x01DA);
- break;
- case 0x01DB:
- bufpush(0x01DC);
- break;
- case 0x01DE:
- bufpush(0x01DF);
- break;
- case 0x01E0:
- bufpush(0x01E1);
- break;
- case 0x01E2:
- bufpush(0x01E3);
- break;
- case 0x01E4:
- bufpush(0x01E5);
- break;
- case 0x01E6:
- bufpush(0x01E7);
- break;
- case 0x01E8:
- bufpush(0x01E9);
- break;
- case 0x01EA:
- bufpush(0x01EB);
- break;
- case 0x01EC:
- bufpush(0x01ED);
- break;
- case 0x01EE:
- bufpush(0x01EF);
- break;
- case 0x01F0:
- bufpush(0x006A);
- bufpush(0x030C);
- break;
- case 0x01F1:
- bufpush(0x01F3);
- break;
- case 0x01F2:
- bufpush(0x01F3);
- break;
- case 0x01F4:
- bufpush(0x01F5);
- break;
- case 0x01F6:
- bufpush(0x0195);
- break;
- case 0x01F7:
- bufpush(0x01BF);
- break;
- case 0x01F8:
- bufpush(0x01F9);
- break;
- case 0x01FA:
- bufpush(0x01FB);
- break;
- case 0x01FC:
- bufpush(0x01FD);
- break;
- case 0x01FE:
- bufpush(0x01FF);
- break;
- case 0x0200:
- bufpush(0x0201);
- break;
- case 0x0202:
- bufpush(0x0203);
- break;
- case 0x0204:
- bufpush(0x0205);
- break;
- case 0x0206:
- bufpush(0x0207);
- break;
- case 0x0208:
- bufpush(0x0209);
- break;
- case 0x020A:
- bufpush(0x020B);
- break;
- case 0x020C:
- bufpush(0x020D);
- break;
- case 0x020E:
- bufpush(0x020F);
- break;
- case 0x0210:
- bufpush(0x0211);
- break;
- case 0x0212:
- bufpush(0x0213);
- break;
- case 0x0214:
- bufpush(0x0215);
- break;
- case 0x0216:
- bufpush(0x0217);
- break;
- case 0x0218:
- bufpush(0x0219);
- break;
- case 0x021A:
- bufpush(0x021B);
- break;
- case 0x021C:
- bufpush(0x021D);
- break;
- case 0x021E:
- bufpush(0x021F);
- break;
- case 0x0220:
- bufpush(0x019E);
- break;
- case 0x0222:
- bufpush(0x0223);
- break;
- case 0x0224:
- bufpush(0x0225);
- break;
- case 0x0226:
- bufpush(0x0227);
- break;
- case 0x0228:
- bufpush(0x0229);
- break;
- case 0x022A:
- bufpush(0x022B);
- break;
- case 0x022C:
- bufpush(0x022D);
- break;
- case 0x022E:
- bufpush(0x022F);
- break;
- case 0x0230:
- bufpush(0x0231);
- break;
- case 0x0232:
- bufpush(0x0233);
- break;
- case 0x0345:
- bufpush(0x03B9);
- break;
- case 0x0386:
- bufpush(0x03AC);
- break;
- case 0x0388:
- bufpush(0x03AD);
- break;
- case 0x0389:
- bufpush(0x03AE);
- break;
- case 0x038A:
- bufpush(0x03AF);
- break;
- case 0x038C:
- bufpush(0x03CC);
- break;
- case 0x038E:
- bufpush(0x03CD);
- break;
- case 0x038F:
- bufpush(0x03CE);
- break;
- case 0x0390:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x0391:
- bufpush(0x03B1);
- break;
- case 0x0392:
- bufpush(0x03B2);
- break;
- case 0x0393:
- bufpush(0x03B3);
- break;
- case 0x0394:
- bufpush(0x03B4);
- break;
- case 0x0395:
- bufpush(0x03B5);
- break;
- case 0x0396:
- bufpush(0x03B6);
- break;
- case 0x0397:
- bufpush(0x03B7);
- break;
- case 0x0398:
- bufpush(0x03B8);
- break;
- case 0x0399:
- bufpush(0x03B9);
- break;
- case 0x039A:
- bufpush(0x03BA);
- break;
- case 0x039B:
- bufpush(0x03BB);
- break;
- case 0x039C:
- bufpush(0x03BC);
- break;
- case 0x039D:
- bufpush(0x03BD);
- break;
- case 0x039E:
- bufpush(0x03BE);
- break;
- case 0x039F:
- bufpush(0x03BF);
- break;
- case 0x03A0:
- bufpush(0x03C0);
- break;
- case 0x03A1:
- bufpush(0x03C1);
- break;
- case 0x03A3:
- bufpush(0x03C3);
- break;
- case 0x03A4:
- bufpush(0x03C4);
- break;
- case 0x03A5:
- bufpush(0x03C5);
- break;
- case 0x03A6:
- bufpush(0x03C6);
- break;
- case 0x03A7:
- bufpush(0x03C7);
- break;
- case 0x03A8:
- bufpush(0x03C8);
- break;
- case 0x03A9:
- bufpush(0x03C9);
- break;
- case 0x03AA:
- bufpush(0x03CA);
- break;
- case 0x03AB:
- bufpush(0x03CB);
- break;
- case 0x03B0:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x03C2:
- bufpush(0x03C3);
- break;
- case 0x03D0:
- bufpush(0x03B2);
- break;
- case 0x03D1:
- bufpush(0x03B8);
- break;
- case 0x03D5:
- bufpush(0x03C6);
- break;
- case 0x03D6:
- bufpush(0x03C0);
- break;
- case 0x03D8:
- bufpush(0x03D9);
- break;
- case 0x03DA:
- bufpush(0x03DB);
- break;
- case 0x03DC:
- bufpush(0x03DD);
- break;
- case 0x03DE:
- bufpush(0x03DF);
- break;
- case 0x03E0:
- bufpush(0x03E1);
- break;
- case 0x03E2:
- bufpush(0x03E3);
- break;
- case 0x03E4:
- bufpush(0x03E5);
- break;
- case 0x03E6:
- bufpush(0x03E7);
- break;
- case 0x03E8:
- bufpush(0x03E9);
- break;
- case 0x03EA:
- bufpush(0x03EB);
- break;
- case 0x03EC:
- bufpush(0x03ED);
- break;
- case 0x03EE:
- bufpush(0x03EF);
- break;
- case 0x03F0:
- bufpush(0x03BA);
- break;
- case 0x03F1:
- bufpush(0x03C1);
- break;
- case 0x03F2:
- bufpush(0x03C3);
- break;
- case 0x03F4:
- bufpush(0x03B8);
- break;
- case 0x03F5:
- bufpush(0x03B5);
- break;
- case 0x0400:
- bufpush(0x0450);
- break;
- case 0x0401:
- bufpush(0x0451);
- break;
- case 0x0402:
- bufpush(0x0452);
- break;
- case 0x0403:
- bufpush(0x0453);
- break;
- case 0x0404:
- bufpush(0x0454);
- break;
- case 0x0405:
- bufpush(0x0455);
- break;
- case 0x0406:
- bufpush(0x0456);
- break;
- case 0x0407:
- bufpush(0x0457);
- break;
- case 0x0408:
- bufpush(0x0458);
- break;
- case 0x0409:
- bufpush(0x0459);
- break;
- case 0x040A:
- bufpush(0x045A);
- break;
- case 0x040B:
- bufpush(0x045B);
- break;
- case 0x040C:
- bufpush(0x045C);
- break;
- case 0x040D:
- bufpush(0x045D);
- break;
- case 0x040E:
- bufpush(0x045E);
- break;
- case 0x040F:
- bufpush(0x045F);
- break;
- case 0x0410:
- bufpush(0x0430);
- break;
- case 0x0411:
- bufpush(0x0431);
- break;
- case 0x0412:
- bufpush(0x0432);
- break;
- case 0x0413:
- bufpush(0x0433);
- break;
- case 0x0414:
- bufpush(0x0434);
- break;
- case 0x0415:
- bufpush(0x0435);
- break;
- case 0x0416:
- bufpush(0x0436);
- break;
- case 0x0417:
- bufpush(0x0437);
- break;
- case 0x0418:
- bufpush(0x0438);
- break;
- case 0x0419:
- bufpush(0x0439);
- break;
- case 0x041A:
- bufpush(0x043A);
- break;
- case 0x041B:
- bufpush(0x043B);
- break;
- case 0x041C:
- bufpush(0x043C);
- break;
- case 0x041D:
- bufpush(0x043D);
- break;
- case 0x041E:
- bufpush(0x043E);
- break;
- case 0x041F:
- bufpush(0x043F);
- break;
- case 0x0420:
- bufpush(0x0440);
- break;
- case 0x0421:
- bufpush(0x0441);
- break;
- case 0x0422:
- bufpush(0x0442);
- break;
- case 0x0423:
- bufpush(0x0443);
- break;
- case 0x0424:
- bufpush(0x0444);
- break;
- case 0x0425:
- bufpush(0x0445);
- break;
- case 0x0426:
- bufpush(0x0446);
- break;
- case 0x0427:
- bufpush(0x0447);
- break;
- case 0x0428:
- bufpush(0x0448);
- break;
- case 0x0429:
- bufpush(0x0449);
- break;
- case 0x042A:
- bufpush(0x044A);
- break;
- case 0x042B:
- bufpush(0x044B);
- break;
- case 0x042C:
- bufpush(0x044C);
- break;
- case 0x042D:
- bufpush(0x044D);
- break;
- case 0x042E:
- bufpush(0x044E);
- break;
- case 0x042F:
- bufpush(0x044F);
- break;
- case 0x0460:
- bufpush(0x0461);
- break;
- case 0x0462:
- bufpush(0x0463);
- break;
- case 0x0464:
- bufpush(0x0465);
- break;
- case 0x0466:
- bufpush(0x0467);
- break;
- case 0x0468:
- bufpush(0x0469);
- break;
- case 0x046A:
- bufpush(0x046B);
- break;
- case 0x046C:
- bufpush(0x046D);
- break;
- case 0x046E:
- bufpush(0x046F);
- break;
- case 0x0470:
- bufpush(0x0471);
- break;
- case 0x0472:
- bufpush(0x0473);
- break;
- case 0x0474:
- bufpush(0x0475);
- break;
- case 0x0476:
- bufpush(0x0477);
- break;
- case 0x0478:
- bufpush(0x0479);
- break;
- case 0x047A:
- bufpush(0x047B);
- break;
- case 0x047C:
- bufpush(0x047D);
- break;
- case 0x047E:
- bufpush(0x047F);
- break;
- case 0x0480:
- bufpush(0x0481);
- break;
- case 0x048A:
- bufpush(0x048B);
- break;
- case 0x048C:
- bufpush(0x048D);
- break;
- case 0x048E:
- bufpush(0x048F);
- break;
- case 0x0490:
- bufpush(0x0491);
- break;
- case 0x0492:
- bufpush(0x0493);
- break;
- case 0x0494:
- bufpush(0x0495);
- break;
- case 0x0496:
- bufpush(0x0497);
- break;
- case 0x0498:
- bufpush(0x0499);
- break;
- case 0x049A:
- bufpush(0x049B);
- break;
- case 0x049C:
- bufpush(0x049D);
- break;
- case 0x049E:
- bufpush(0x049F);
- break;
- case 0x04A0:
- bufpush(0x04A1);
- break;
- case 0x04A2:
- bufpush(0x04A3);
- break;
- case 0x04A4:
- bufpush(0x04A5);
- break;
- case 0x04A6:
- bufpush(0x04A7);
- break;
- case 0x04A8:
- bufpush(0x04A9);
- break;
- case 0x04AA:
- bufpush(0x04AB);
- break;
- case 0x04AC:
- bufpush(0x04AD);
- break;
- case 0x04AE:
- bufpush(0x04AF);
- break;
- case 0x04B0:
- bufpush(0x04B1);
- break;
- case 0x04B2:
- bufpush(0x04B3);
- break;
- case 0x04B4:
- bufpush(0x04B5);
- break;
- case 0x04B6:
- bufpush(0x04B7);
- break;
- case 0x04B8:
- bufpush(0x04B9);
- break;
- case 0x04BA:
- bufpush(0x04BB);
- break;
- case 0x04BC:
- bufpush(0x04BD);
- break;
- case 0x04BE:
- bufpush(0x04BF);
- break;
- case 0x04C1:
- bufpush(0x04C2);
- break;
- case 0x04C3:
- bufpush(0x04C4);
- break;
- case 0x04C5:
- bufpush(0x04C6);
- break;
- case 0x04C7:
- bufpush(0x04C8);
- break;
- case 0x04C9:
- bufpush(0x04CA);
- break;
- case 0x04CB:
- bufpush(0x04CC);
- break;
- case 0x04CD:
- bufpush(0x04CE);
- break;
- case 0x04D0:
- bufpush(0x04D1);
- break;
- case 0x04D2:
- bufpush(0x04D3);
- break;
- case 0x04D4:
- bufpush(0x04D5);
- break;
- case 0x04D6:
- bufpush(0x04D7);
- break;
- case 0x04D8:
- bufpush(0x04D9);
- break;
- case 0x04DA:
- bufpush(0x04DB);
- break;
- case 0x04DC:
- bufpush(0x04DD);
- break;
- case 0x04DE:
- bufpush(0x04DF);
- break;
- case 0x04E0:
- bufpush(0x04E1);
- break;
- case 0x04E2:
- bufpush(0x04E3);
- break;
- case 0x04E4:
- bufpush(0x04E5);
- break;
- case 0x04E6:
- bufpush(0x04E7);
- break;
- case 0x04E8:
- bufpush(0x04E9);
- break;
- case 0x04EA:
- bufpush(0x04EB);
- break;
- case 0x04EC:
- bufpush(0x04ED);
- break;
- case 0x04EE:
- bufpush(0x04EF);
- break;
- case 0x04F0:
- bufpush(0x04F1);
- break;
- case 0x04F2:
- bufpush(0x04F3);
- break;
- case 0x04F4:
- bufpush(0x04F5);
- break;
- case 0x04F8:
- bufpush(0x04F9);
- break;
- case 0x0500:
- bufpush(0x0501);
- break;
- case 0x0502:
- bufpush(0x0503);
- break;
- case 0x0504:
- bufpush(0x0505);
- break;
- case 0x0506:
- bufpush(0x0507);
- break;
- case 0x0508:
- bufpush(0x0509);
- break;
- case 0x050A:
- bufpush(0x050B);
- break;
- case 0x050C:
- bufpush(0x050D);
- break;
- case 0x050E:
- bufpush(0x050F);
- break;
- case 0x0531:
- bufpush(0x0561);
- break;
- case 0x0532:
- bufpush(0x0562);
- break;
- case 0x0533:
- bufpush(0x0563);
- break;
- case 0x0534:
- bufpush(0x0564);
- break;
- case 0x0535:
- bufpush(0x0565);
- break;
- case 0x0536:
- bufpush(0x0566);
- break;
- case 0x0537:
- bufpush(0x0567);
- break;
- case 0x0538:
- bufpush(0x0568);
- break;
- case 0x0539:
- bufpush(0x0569);
- break;
- case 0x053A:
- bufpush(0x056A);
- break;
- case 0x053B:
- bufpush(0x056B);
- break;
- case 0x053C:
- bufpush(0x056C);
- break;
- case 0x053D:
- bufpush(0x056D);
- break;
- case 0x053E:
- bufpush(0x056E);
- break;
- case 0x053F:
- bufpush(0x056F);
- break;
- case 0x0540:
- bufpush(0x0570);
- break;
- case 0x0541:
- bufpush(0x0571);
- break;
- case 0x0542:
- bufpush(0x0572);
- break;
- case 0x0543:
- bufpush(0x0573);
- break;
- case 0x0544:
- bufpush(0x0574);
- break;
- case 0x0545:
- bufpush(0x0575);
- break;
- case 0x0546:
- bufpush(0x0576);
- break;
- case 0x0547:
- bufpush(0x0577);
- break;
- case 0x0548:
- bufpush(0x0578);
- break;
- case 0x0549:
- bufpush(0x0579);
- break;
- case 0x054A:
- bufpush(0x057A);
- break;
- case 0x054B:
- bufpush(0x057B);
- break;
- case 0x054C:
- bufpush(0x057C);
- break;
- case 0x054D:
- bufpush(0x057D);
- break;
- case 0x054E:
- bufpush(0x057E);
- break;
- case 0x054F:
- bufpush(0x057F);
- break;
- case 0x0550:
- bufpush(0x0580);
- break;
- case 0x0551:
- bufpush(0x0581);
- break;
- case 0x0552:
- bufpush(0x0582);
- break;
- case 0x0553:
- bufpush(0x0583);
- break;
- case 0x0554:
- bufpush(0x0584);
- break;
- case 0x0555:
- bufpush(0x0585);
- break;
- case 0x0556:
- bufpush(0x0586);
- break;
- case 0x0587:
- bufpush(0x0565);
- bufpush(0x0582);
- break;
- case 0x1E00:
- bufpush(0x1E01);
- break;
- case 0x1E02:
- bufpush(0x1E03);
- break;
- case 0x1E04:
- bufpush(0x1E05);
- break;
- case 0x1E06:
- bufpush(0x1E07);
- break;
- case 0x1E08:
- bufpush(0x1E09);
- break;
- case 0x1E0A:
- bufpush(0x1E0B);
- break;
- case 0x1E0C:
- bufpush(0x1E0D);
- break;
- case 0x1E0E:
- bufpush(0x1E0F);
- break;
- case 0x1E10:
- bufpush(0x1E11);
- break;
- case 0x1E12:
- bufpush(0x1E13);
- break;
- case 0x1E14:
- bufpush(0x1E15);
- break;
- case 0x1E16:
- bufpush(0x1E17);
- break;
- case 0x1E18:
- bufpush(0x1E19);
- break;
- case 0x1E1A:
- bufpush(0x1E1B);
- break;
- case 0x1E1C:
- bufpush(0x1E1D);
- break;
- case 0x1E1E:
- bufpush(0x1E1F);
- break;
- case 0x1E20:
- bufpush(0x1E21);
- break;
- case 0x1E22:
- bufpush(0x1E23);
- break;
- case 0x1E24:
- bufpush(0x1E25);
- break;
- case 0x1E26:
- bufpush(0x1E27);
- break;
- case 0x1E28:
- bufpush(0x1E29);
- break;
- case 0x1E2A:
- bufpush(0x1E2B);
- break;
- case 0x1E2C:
- bufpush(0x1E2D);
- break;
- case 0x1E2E:
- bufpush(0x1E2F);
- break;
- case 0x1E30:
- bufpush(0x1E31);
- break;
- case 0x1E32:
- bufpush(0x1E33);
- break;
- case 0x1E34:
- bufpush(0x1E35);
- break;
- case 0x1E36:
- bufpush(0x1E37);
- break;
- case 0x1E38:
- bufpush(0x1E39);
- break;
- case 0x1E3A:
- bufpush(0x1E3B);
- break;
- case 0x1E3C:
- bufpush(0x1E3D);
- break;
- case 0x1E3E:
- bufpush(0x1E3F);
- break;
- case 0x1E40:
- bufpush(0x1E41);
- break;
- case 0x1E42:
- bufpush(0x1E43);
- break;
- case 0x1E44:
- bufpush(0x1E45);
- break;
- case 0x1E46:
- bufpush(0x1E47);
- break;
- case 0x1E48:
- bufpush(0x1E49);
- break;
- case 0x1E4A:
- bufpush(0x1E4B);
- break;
- case 0x1E4C:
- bufpush(0x1E4D);
- break;
- case 0x1E4E:
- bufpush(0x1E4F);
- break;
- case 0x1E50:
- bufpush(0x1E51);
- break;
- case 0x1E52:
- bufpush(0x1E53);
- break;
- case 0x1E54:
- bufpush(0x1E55);
- break;
- case 0x1E56:
- bufpush(0x1E57);
- break;
- case 0x1E58:
- bufpush(0x1E59);
- break;
- case 0x1E5A:
- bufpush(0x1E5B);
- break;
- case 0x1E5C:
- bufpush(0x1E5D);
- break;
- case 0x1E5E:
- bufpush(0x1E5F);
- break;
- case 0x1E60:
- bufpush(0x1E61);
- break;
- case 0x1E62:
- bufpush(0x1E63);
- break;
- case 0x1E64:
- bufpush(0x1E65);
- break;
- case 0x1E66:
- bufpush(0x1E67);
- break;
- case 0x1E68:
- bufpush(0x1E69);
- break;
- case 0x1E6A:
- bufpush(0x1E6B);
- break;
- case 0x1E6C:
- bufpush(0x1E6D);
- break;
- case 0x1E6E:
- bufpush(0x1E6F);
- break;
- case 0x1E70:
- bufpush(0x1E71);
- break;
- case 0x1E72:
- bufpush(0x1E73);
- break;
- case 0x1E74:
- bufpush(0x1E75);
- break;
- case 0x1E76:
- bufpush(0x1E77);
- break;
- case 0x1E78:
- bufpush(0x1E79);
- break;
- case 0x1E7A:
- bufpush(0x1E7B);
- break;
- case 0x1E7C:
- bufpush(0x1E7D);
- break;
- case 0x1E7E:
- bufpush(0x1E7F);
- break;
- case 0x1E80:
- bufpush(0x1E81);
- break;
- case 0x1E82:
- bufpush(0x1E83);
- break;
- case 0x1E84:
- bufpush(0x1E85);
- break;
- case 0x1E86:
- bufpush(0x1E87);
- break;
- case 0x1E88:
- bufpush(0x1E89);
- break;
- case 0x1E8A:
- bufpush(0x1E8B);
- break;
- case 0x1E8C:
- bufpush(0x1E8D);
- break;
- case 0x1E8E:
- bufpush(0x1E8F);
- break;
- case 0x1E90:
- bufpush(0x1E91);
- break;
- case 0x1E92:
- bufpush(0x1E93);
- break;
- case 0x1E94:
- bufpush(0x1E95);
- break;
- case 0x1E96:
- bufpush(0x0068);
- bufpush(0x0331);
- break;
- case 0x1E97:
- bufpush(0x0074);
- bufpush(0x0308);
- break;
- case 0x1E98:
- bufpush(0x0077);
- bufpush(0x030A);
- break;
- case 0x1E99:
- bufpush(0x0079);
- bufpush(0x030A);
- break;
- case 0x1E9A:
- bufpush(0x0061);
- bufpush(0x02BE);
- break;
- case 0x1E9B:
- bufpush(0x1E61);
- break;
- case 0x1EA0:
- bufpush(0x1EA1);
- break;
- case 0x1EA2:
- bufpush(0x1EA3);
- break;
- case 0x1EA4:
- bufpush(0x1EA5);
- break;
- case 0x1EA6:
- bufpush(0x1EA7);
- break;
- case 0x1EA8:
- bufpush(0x1EA9);
- break;
- case 0x1EAA:
- bufpush(0x1EAB);
- break;
- case 0x1EAC:
- bufpush(0x1EAD);
- break;
- case 0x1EAE:
- bufpush(0x1EAF);
- break;
- case 0x1EB0:
- bufpush(0x1EB1);
- break;
- case 0x1EB2:
- bufpush(0x1EB3);
- break;
- case 0x1EB4:
- bufpush(0x1EB5);
- break;
- case 0x1EB6:
- bufpush(0x1EB7);
- break;
- case 0x1EB8:
- bufpush(0x1EB9);
- break;
- case 0x1EBA:
- bufpush(0x1EBB);
- break;
- case 0x1EBC:
- bufpush(0x1EBD);
- break;
- case 0x1EBE:
- bufpush(0x1EBF);
- break;
- case 0x1EC0:
- bufpush(0x1EC1);
- break;
- case 0x1EC2:
- bufpush(0x1EC3);
- break;
- case 0x1EC4:
- bufpush(0x1EC5);
- break;
- case 0x1EC6:
- bufpush(0x1EC7);
- break;
- case 0x1EC8:
- bufpush(0x1EC9);
- break;
- case 0x1ECA:
- bufpush(0x1ECB);
- break;
- case 0x1ECC:
- bufpush(0x1ECD);
- break;
- case 0x1ECE:
- bufpush(0x1ECF);
- break;
- case 0x1ED0:
- bufpush(0x1ED1);
- break;
- case 0x1ED2:
- bufpush(0x1ED3);
- break;
- case 0x1ED4:
- bufpush(0x1ED5);
- break;
- case 0x1ED6:
- bufpush(0x1ED7);
- break;
- case 0x1ED8:
- bufpush(0x1ED9);
- break;
- case 0x1EDA:
- bufpush(0x1EDB);
- break;
- case 0x1EDC:
- bufpush(0x1EDD);
- break;
- case 0x1EDE:
- bufpush(0x1EDF);
- break;
- case 0x1EE0:
- bufpush(0x1EE1);
- break;
- case 0x1EE2:
- bufpush(0x1EE3);
- break;
- case 0x1EE4:
- bufpush(0x1EE5);
- break;
- case 0x1EE6:
- bufpush(0x1EE7);
- break;
- case 0x1EE8:
- bufpush(0x1EE9);
- break;
- case 0x1EEA:
- bufpush(0x1EEB);
- break;
- case 0x1EEC:
- bufpush(0x1EED);
- break;
- case 0x1EEE:
- bufpush(0x1EEF);
- break;
- case 0x1EF0:
- bufpush(0x1EF1);
- break;
- case 0x1EF2:
- bufpush(0x1EF3);
- break;
- case 0x1EF4:
- bufpush(0x1EF5);
- break;
- case 0x1EF6:
- bufpush(0x1EF7);
- break;
- case 0x1EF8:
- bufpush(0x1EF9);
- break;
- case 0x1F08:
- bufpush(0x1F00);
- break;
- case 0x1F09:
- bufpush(0x1F01);
- break;
- case 0x1F0A:
- bufpush(0x1F02);
- break;
- case 0x1F0B:
- bufpush(0x1F03);
- break;
- case 0x1F0C:
- bufpush(0x1F04);
- break;
- case 0x1F0D:
- bufpush(0x1F05);
- break;
- case 0x1F0E:
- bufpush(0x1F06);
- break;
- case 0x1F0F:
- bufpush(0x1F07);
- break;
- case 0x1F18:
- bufpush(0x1F10);
- break;
- case 0x1F19:
- bufpush(0x1F11);
- break;
- case 0x1F1A:
- bufpush(0x1F12);
- break;
- case 0x1F1B:
- bufpush(0x1F13);
- break;
- case 0x1F1C:
- bufpush(0x1F14);
- break;
- case 0x1F1D:
- bufpush(0x1F15);
- break;
- case 0x1F28:
- bufpush(0x1F20);
- break;
- case 0x1F29:
- bufpush(0x1F21);
- break;
- case 0x1F2A:
- bufpush(0x1F22);
- break;
- case 0x1F2B:
- bufpush(0x1F23);
- break;
- case 0x1F2C:
- bufpush(0x1F24);
- break;
- case 0x1F2D:
- bufpush(0x1F25);
- break;
- case 0x1F2E:
- bufpush(0x1F26);
- break;
- case 0x1F2F:
- bufpush(0x1F27);
- break;
- case 0x1F38:
- bufpush(0x1F30);
- break;
- case 0x1F39:
- bufpush(0x1F31);
- break;
- case 0x1F3A:
- bufpush(0x1F32);
- break;
- case 0x1F3B:
- bufpush(0x1F33);
- break;
- case 0x1F3C:
- bufpush(0x1F34);
- break;
- case 0x1F3D:
- bufpush(0x1F35);
- break;
- case 0x1F3E:
- bufpush(0x1F36);
- break;
- case 0x1F3F:
- bufpush(0x1F37);
- break;
- case 0x1F48:
- bufpush(0x1F40);
- break;
- case 0x1F49:
- bufpush(0x1F41);
- break;
- case 0x1F4A:
- bufpush(0x1F42);
- break;
- case 0x1F4B:
- bufpush(0x1F43);
- break;
- case 0x1F4C:
- bufpush(0x1F44);
- break;
- case 0x1F4D:
- bufpush(0x1F45);
- break;
- case 0x1F50:
- bufpush(0x03C5);
- bufpush(0x0313);
- break;
- case 0x1F52:
- bufpush(0x03C5);
- bufpush(0x0313);
- bufpush(0x0300);
- break;
- case 0x1F54:
- bufpush(0x03C5);
- bufpush(0x0313);
- bufpush(0x0301);
- break;
- case 0x1F56:
- bufpush(0x03C5);
- bufpush(0x0313);
- bufpush(0x0342);
- break;
- case 0x1F59:
- bufpush(0x1F51);
- break;
- case 0x1F5B:
- bufpush(0x1F53);
- break;
- case 0x1F5D:
- bufpush(0x1F55);
- break;
- case 0x1F5F:
- bufpush(0x1F57);
- break;
- case 0x1F68:
- bufpush(0x1F60);
- break;
- case 0x1F69:
- bufpush(0x1F61);
- break;
- case 0x1F6A:
- bufpush(0x1F62);
- break;
- case 0x1F6B:
- bufpush(0x1F63);
- break;
- case 0x1F6C:
- bufpush(0x1F64);
- break;
- case 0x1F6D:
- bufpush(0x1F65);
- break;
- case 0x1F6E:
- bufpush(0x1F66);
- break;
- case 0x1F6F:
- bufpush(0x1F67);
- break;
- case 0x1F80:
- bufpush(0x1F00);
- bufpush(0x03B9);
- break;
- case 0x1F81:
- bufpush(0x1F01);
- bufpush(0x03B9);
- break;
- case 0x1F82:
- bufpush(0x1F02);
- bufpush(0x03B9);
- break;
- case 0x1F83:
- bufpush(0x1F03);
- bufpush(0x03B9);
- break;
- case 0x1F84:
- bufpush(0x1F04);
- bufpush(0x03B9);
- break;
- case 0x1F85:
- bufpush(0x1F05);
- bufpush(0x03B9);
- break;
- case 0x1F86:
- bufpush(0x1F06);
- bufpush(0x03B9);
- break;
- case 0x1F87:
- bufpush(0x1F07);
- bufpush(0x03B9);
- break;
- case 0x1F88:
- bufpush(0x1F00);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F89:
- bufpush(0x1F01);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F8A:
- bufpush(0x1F02);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F8B:
- bufpush(0x1F03);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F8C:
- bufpush(0x1F04);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F8D:
- bufpush(0x1F05);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F8E:
- bufpush(0x1F06);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F8F:
- bufpush(0x1F07);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F90:
- bufpush(0x1F20);
- bufpush(0x03B9);
- break;
- case 0x1F91:
- bufpush(0x1F21);
- bufpush(0x03B9);
- break;
- case 0x1F92:
- bufpush(0x1F22);
- bufpush(0x03B9);
- break;
- case 0x1F93:
- bufpush(0x1F23);
- bufpush(0x03B9);
- break;
- case 0x1F94:
- bufpush(0x1F24);
- bufpush(0x03B9);
- break;
- case 0x1F95:
- bufpush(0x1F25);
- bufpush(0x03B9);
- break;
- case 0x1F96:
- bufpush(0x1F26);
- bufpush(0x03B9);
- break;
- case 0x1F97:
- bufpush(0x1F27);
- bufpush(0x03B9);
- break;
- case 0x1F98:
- bufpush(0x1F20);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F99:
- bufpush(0x1F21);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F9A:
- bufpush(0x1F22);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F9B:
- bufpush(0x1F23);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F9C:
- bufpush(0x1F24);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F9D:
- bufpush(0x1F25);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F9E:
- bufpush(0x1F26);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1F9F:
- bufpush(0x1F27);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FA0:
- bufpush(0x1F60);
- bufpush(0x03B9);
- break;
- case 0x1FA1:
- bufpush(0x1F61);
- bufpush(0x03B9);
- break;
- case 0x1FA2:
- bufpush(0x1F62);
- bufpush(0x03B9);
- break;
- case 0x1FA3:
- bufpush(0x1F63);
- bufpush(0x03B9);
- break;
- case 0x1FA4:
- bufpush(0x1F64);
- bufpush(0x03B9);
- break;
- case 0x1FA5:
- bufpush(0x1F65);
- bufpush(0x03B9);
- break;
- case 0x1FA6:
- bufpush(0x1F66);
- bufpush(0x03B9);
- break;
- case 0x1FA7:
- bufpush(0x1F67);
- bufpush(0x03B9);
- break;
- case 0x1FA8:
- bufpush(0x1F60);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FA9:
- bufpush(0x1F61);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FAA:
- bufpush(0x1F62);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FAB:
- bufpush(0x1F63);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FAC:
- bufpush(0x1F64);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FAD:
- bufpush(0x1F65);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FAE:
- bufpush(0x1F66);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FAF:
- bufpush(0x1F67);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FB2:
- bufpush(0x1F70);
- bufpush(0x03B9);
- break;
- case 0x1FB3:
- bufpush(0x03B1);
- bufpush(0x03B9);
- break;
- case 0x1FB4:
- bufpush(0x03AC);
- bufpush(0x03B9);
- break;
- case 0x1FB6:
- bufpush(0x03B1);
- bufpush(0x0342);
- break;
- case 0x1FB7:
- bufpush(0x03B1);
- bufpush(0x0342);
- bufpush(0x03B9);
- break;
- case 0x1FB8:
- bufpush(0x1FB0);
- break;
- case 0x1FB9:
- bufpush(0x1FB1);
- break;
- case 0x1FBA:
- bufpush(0x1F70);
- break;
- case 0x1FBB:
- bufpush(0x1F71);
- break;
- case 0x1FBC:
- bufpush(0x03B1);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FBE:
- bufpush(0x03B9);
- break;
- case 0x1FC2:
- bufpush(0x1F74);
- bufpush(0x03B9);
- break;
- case 0x1FC3:
- bufpush(0x03B7);
- bufpush(0x03B9);
- break;
- case 0x1FC4:
- bufpush(0x03AE);
- bufpush(0x03B9);
- break;
- case 0x1FC6:
- bufpush(0x03B7);
- bufpush(0x0342);
- break;
- case 0x1FC7:
- bufpush(0x03B7);
- bufpush(0x0342);
- bufpush(0x03B9);
- break;
- case 0x1FC8:
- bufpush(0x1F72);
- break;
- case 0x1FC9:
- bufpush(0x1F73);
- break;
- case 0x1FCA:
- bufpush(0x1F74);
- break;
- case 0x1FCB:
- bufpush(0x1F75);
- break;
- case 0x1FCC:
- bufpush(0x03B7);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x1FD2:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0300);
- break;
- case 0x1FD3:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x1FD6:
- bufpush(0x03B9);
- bufpush(0x0342);
- break;
- case 0x1FD7:
- bufpush(0x03B9);
- bufpush(0x0308);
- bufpush(0x0342);
- break;
- case 0x1FD8:
- bufpush(0x1FD0);
- break;
- case 0x1FD9:
- bufpush(0x1FD1);
- break;
- case 0x1FDA:
- bufpush(0x1F76);
- break;
- case 0x1FDB:
- bufpush(0x1F77);
- break;
- case 0x1FE2:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0300);
- break;
- case 0x1FE3:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0301);
- break;
- case 0x1FE4:
- bufpush(0x03C1);
- bufpush(0x0313);
- break;
- case 0x1FE6:
- bufpush(0x03C5);
- bufpush(0x0342);
- break;
- case 0x1FE7:
- bufpush(0x03C5);
- bufpush(0x0308);
- bufpush(0x0342);
- break;
- case 0x1FE8:
- bufpush(0x1FE0);
- break;
- case 0x1FE9:
- bufpush(0x1FE1);
- break;
- case 0x1FEA:
- bufpush(0x1F7A);
- break;
- case 0x1FEB:
- bufpush(0x1F7B);
- break;
- case 0x1FEC:
- bufpush(0x1FE5);
- break;
- case 0x1FF2:
- bufpush(0x1F7C);
- bufpush(0x03B9);
- break;
- case 0x1FF3:
- bufpush(0x03C9);
- bufpush(0x03B9);
- break;
- case 0x1FF4:
- bufpush(0x03CE);
- bufpush(0x03B9);
- break;
- case 0x1FF6:
- bufpush(0x03C9);
- bufpush(0x0342);
- break;
- case 0x1FF7:
- bufpush(0x03C9);
- bufpush(0x0342);
- bufpush(0x03B9);
- break;
- case 0x1FF8:
- bufpush(0x1F78);
- break;
- case 0x1FF9:
- bufpush(0x1F79);
- break;
- case 0x1FFA:
- bufpush(0x1F7C);
- break;
- case 0x1FFB:
- bufpush(0x1F7D);
- break;
- case 0x1FFC:
- bufpush(0x03C9);
- bufpush(0x03B9);
- break;
- case 0x:
- break;
- case 0x2126:
- bufpush(0x03C9);
- break;
- case 0x212A:
- bufpush(0x006B);
- break;
- case 0x212B:
- bufpush(0x00E5);
- break;
- case 0x2160:
- bufpush(0x2170);
- break;
- case 0x2161:
- bufpush(0x2171);
- break;
- case 0x2162:
- bufpush(0x2172);
- break;
- case 0x2163:
- bufpush(0x2173);
- break;
- case 0x2164:
- bufpush(0x2174);
- break;
- case 0x2165:
- bufpush(0x2175);
- break;
- case 0x2166:
- bufpush(0x2176);
- break;
- case 0x2167:
- bufpush(0x2177);
- break;
- case 0x2168:
- bufpush(0x2178);
- break;
- case 0x2169:
- bufpush(0x2179);
- break;
- case 0x216A:
- bufpush(0x217A);
- break;
- case 0x216B:
- bufpush(0x217B);
- break;
- case 0x216C:
- bufpush(0x217C);
- break;
- case 0x216D:
- bufpush(0x217D);
- break;
- case 0x216E:
- bufpush(0x217E);
- break;
- case 0x216F:
- bufpush(0x217F);
- break;
- case 0x24B6:
- bufpush(0x24D0);
- break;
- case 0x24B7:
- bufpush(0x24D1);
- break;
- case 0x24B8:
- bufpush(0x24D2);
- break;
- case 0x24B9:
- bufpush(0x24D3);
- break;
- case 0x24BA:
- bufpush(0x24D4);
- break;
- case 0x24BB:
- bufpush(0x24D5);
- break;
- case 0x24BC:
- bufpush(0x24D6);
- break;
- case 0x24BD:
- bufpush(0x24D7);
- break;
- case 0x24BE:
- bufpush(0x24D8);
- break;
- case 0x24BF:
- bufpush(0x24D9);
- break;
- case 0x24C0:
- bufpush(0x24DA);
- break;
- case 0x24C1:
- bufpush(0x24DB);
- break;
- case 0x24C2:
- bufpush(0x24DC);
- break;
- case 0x24C3:
- bufpush(0x24DD);
- break;
- case 0x24C4:
- bufpush(0x24DE);
- break;
- case 0x24C5:
- bufpush(0x24DF);
- break;
- case 0x24C6:
- bufpush(0x24E0);
- break;
- case 0x24C7:
- bufpush(0x24E1);
- break;
- case 0x24C8:
- bufpush(0x24E2);
- break;
- case 0x24C9:
- bufpush(0x24E3);
- break;
- case 0x24CA:
- bufpush(0x24E4);
- break;
- case 0x24CB:
- bufpush(0x24E5);
- break;
- case 0x24CC:
- bufpush(0x24E6);
- break;
- case 0x24CD:
- bufpush(0x24E7);
- break;
- case 0x24CE:
- bufpush(0x24E8);
- break;
- case 0x24CF:
- bufpush(0x24E9);
- break;
- case 0xFB00:
- bufpush(0x0066);
- bufpush(0x0066);
- break;
- case 0xFB01:
- bufpush(0x0066);
- bufpush(0x0069);
- break;
- case 0xFB02:
- bufpush(0x0066);
- bufpush(0x006C);
- break;
- case 0xFB03:
- bufpush(0x0066);
- bufpush(0x0066);
- bufpush(0x0069);
- break;
- case 0xFB04:
- bufpush(0x0066);
- bufpush(0x0066);
- bufpush(0x006C);
- break;
- case 0xFB05:
- bufpush(0x0073);
- bufpush(0x0074);
- break;
- case 0xFB06:
- bufpush(0x0073);
- bufpush(0x0074);
- break;
- case 0xFB13:
- bufpush(0x0574);
- bufpush(0x0576);
- break;
- case 0xFB14:
- bufpush(0x0574);
- bufpush(0x0565);
- break;
- case 0xFB15:
- bufpush(0x0574);
- bufpush(0x056B);
- break;
- case 0xFB16:
- bufpush(0x057E);
- bufpush(0x0576);
- break;
- case 0xFB17:
- bufpush(0x0574);
- bufpush(0x056D);
- break;
- case 0xFF21:
- bufpush(0xFF41);
- break;
- case 0xFF22:
- bufpush(0xFF42);
- break;
- case 0xFF23:
- bufpush(0xFF43);
- break;
- case 0xFF24:
- bufpush(0xFF44);
- break;
- case 0xFF25:
- bufpush(0xFF45);
- break;
- case 0xFF26:
- bufpush(0xFF46);
- break;
- case 0xFF27:
- bufpush(0xFF47);
- break;
- case 0xFF28:
- bufpush(0xFF48);
- break;
- case 0xFF29:
- bufpush(0xFF49);
- break;
- case 0xFF2A:
- bufpush(0xFF4A);
- break;
- case 0xFF2B:
- bufpush(0xFF4B);
- break;
- case 0xFF2C:
- bufpush(0xFF4C);
- break;
- case 0xFF2D:
- bufpush(0xFF4D);
- break;
- case 0xFF2E:
- bufpush(0xFF4E);
- break;
- case 0xFF2F:
- bufpush(0xFF4F);
- break;
- case 0xFF30:
- bufpush(0xFF50);
- break;
- case 0xFF31:
- bufpush(0xFF51);
- break;
- case 0xFF32:
- bufpush(0xFF52);
- break;
- case 0xFF33:
- bufpush(0xFF53);
- break;
- case 0xFF34:
- bufpush(0xFF54);
- break;
- case 0xFF35:
- bufpush(0xFF55);
- break;
- case 0xFF36:
- bufpush(0xFF56);
- break;
- case 0xFF37:
- bufpush(0xFF57);
- break;
- case 0xFF38:
- bufpush(0xFF58);
- break;
- case 0xFF39:
- bufpush(0xFF59);
- break;
- case 0xFF3A:
- bufpush(0xFF5A);
- break;
- case 0x10400:
- bufpush(0x10428);
- break;
- case 0x10401:
- bufpush(0x10429);
- break;
- case 0x10402:
- bufpush(0x1042A);
- break;
- case 0x10403:
- bufpush(0x1042B);
- break;
- case 0x10404:
- bufpush(0x1042C);
- break;
- case 0x10405:
- bufpush(0x1042D);
- break;
- case 0x10406:
- bufpush(0x1042E);
- break;
- case 0x10407:
- bufpush(0x1042F);
- break;
- case 0x10408:
- bufpush(0x10430);
- break;
- case 0x10409:
- bufpush(0x10431);
- break;
- case 0x1040A:
- bufpush(0x10432);
- break;
- case 0x1040B:
- bufpush(0x10433);
- break;
- case 0x1040C:
- bufpush(0x10434);
- break;
- case 0x1040D:
- bufpush(0x10435);
- break;
- case 0x1040E:
- bufpush(0x10436);
- break;
- case 0x1040F:
- bufpush(0x10437);
- break;
- case 0x10410:
- bufpush(0x10438);
- break;
- case 0x10411:
- bufpush(0x10439);
- break;
- case 0x10412:
- bufpush(0x1043A);
- break;
- case 0x10413:
- bufpush(0x1043B);
- break;
- case 0x10414:
- bufpush(0x1043C);
- break;
- case 0x10415:
- bufpush(0x1043D);
- break;
- case 0x10416:
- bufpush(0x1043E);
- break;
- case 0x10417:
- bufpush(0x1043F);
- break;
- case 0x10418:
- bufpush(0x10440);
- break;
- case 0x10419:
- bufpush(0x10441);
- break;
- case 0x1041A:
- bufpush(0x10442);
- break;
- case 0x1041B:
- bufpush(0x10443);
- break;
- case 0x1041C:
- bufpush(0x10444);
- break;
- case 0x1041D:
- bufpush(0x10445);
- break;
- case 0x1041E:
- bufpush(0x10446);
- break;
- case 0x1041F:
- bufpush(0x10447);
- break;
- case 0x10420:
- bufpush(0x10448);
- break;
- case 0x10421:
- bufpush(0x10449);
- break;
- case 0x10422:
- bufpush(0x1044A);
- break;
- case 0x10423:
- bufpush(0x1044B);
- break;
- case 0x10424:
- bufpush(0x1044C);
- break;
- case 0x10425:
- bufpush(0x1044D);
- break;
- }
diff --git a/src/detab.c b/src/detab.c
deleted file mode 100644
index e03fcf7..0000000
--- a/src/detab.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "bstrlib.h"
-
-// UTF-8 aware detab: assumes s has no newlines, or only a final newline.
-// Return 0 on success, BSTR_ERR if invalid UTF-8.
-extern int bdetab(bstring s, int utf8)
-{
- unsigned char c;
- int pos = 0; // a count of characters
- int byte = 0; // a count of bytes
- int high_chars_to_skip = 0;
- int numspaces = 0;
- while ((c = bchar(s, byte))) {
- if (utf8 && high_chars_to_skip > 0) {
- if (c >= 0x80) {
- high_chars_to_skip--;
- byte++;
- } else {
- return BSTR_ERR; // invalid utf-8
- }
- } else if (c == '\t') {
- bdelete(s, byte, 1); // delete tab character
- numspaces = 4 - (pos % 4);
- binsertch(s, byte, numspaces, ' ');
- byte += numspaces;
- pos += numspaces;
- } else if (c <= 0x80 || !utf8) {
- byte++;
- pos++;
- } else { // multibyte utf8 sequences
- if (c >> 1 == 0176) {
- high_chars_to_skip = 5;
- } else if (c >> 2 == 076) {
- high_chars_to_skip = 4;
- } else if (c >> 3 == 036) {
- high_chars_to_skip = 3;
- } else if (c >> 4 == 016) {
- high_chars_to_skip = 2;
- } else if (c >> 5 == 06) {
- high_chars_to_skip = 1;
- } else {
- return BSTR_ERR; // invalid utf-8
- }
- pos++;
- byte++;
- }
- }
- return 0;
-}
diff --git a/src/getopt.c b/src/getopt.c
deleted file mode 100644
index 321dd9f..0000000
--- a/src/getopt.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* $Id: getopt.c 4022 2008-03-31 06:11:07Z rra $
- *
- * Replacement implementation of getopt.
- *
- * This is a replacement implementation for getopt based on the my_getopt
- * distribution by Benjamin Sittler. Only the getopt interface is included,
- * since remctl doesn't use GNU long options, and the code has been rearranged
- * and reworked somewhat to fit with the remctl coding style.
- *
- * Copyright 1997, 2000, 2001, 2002 Benjamin Sittler
- * Copyright 2008 Russ Allbery
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include
-#include
-#include
-
-/*
- * If we're running the test suite, rename getopt and the global variables to
- * avoid conflicts with the system version.
- */
-#if TESTING
-# define getopt test_getopt
-int test_getopt(int, char **, const char *);
-# define optind test_optind
-# define opterr test_opterr
-# define optopt test_optopt
-# define optarg test_optarg
-#endif
-
-/* Initialize global interface variables. */
-int optind = 1;
-int opterr = 1;
-int optopt = 0;
-char *optarg = NULL;
-
-/*
- * This is the plain old UNIX getopt, with GNU-style extensions. If you're
- * porting some piece of UNIX software, this is all you need. It supports
- * GNU-style permutation and optional arguments, but does not support the GNU
- * -W extension.
- *
- * This function is not re-entrant or thread-safe, has static variables, and
- * generally isn't a great interface, but normally you only call it once.
- */
-int
-getopt(int argc, char *argv[], const char *optstring)
-{
- const char *p;
- size_t offset = 0;
- char mode = '\0';
- int colon_mode = 0;
- int option = -1;
-
- /* Holds the current position in the parameter being parsed. */
- static int charind = 0;
-
- /*
- * By default, getopt permutes argv as it scans and leaves all non-options
- * at the end. This can be changed with the first character of optstring
- * or the environment variable POSIXLY_CORRECT. With a first character of
- * '+' or when POSIXLY_CORRECT is set, option processing stops at the
- * first non-option. If the first character is '-', each non-option argv
- * element is handled as if it were the argument of an option with
- * character code 1. mode holds this character.
- *
- * After the optional leading '+' and '-', optstring may contain ':'. If
- * present, missing arguments return ':' instead of '?'. colon_mode holds
- * this setting.
- */
- if (getenv("POSIXLY_CORRECT") != NULL) {
- mode = '+';
- colon_mode = '+';
- } else {
- if (optstring[offset] == '+' || optstring[offset] == '-') {
- mode = optstring[offset];
- offset++;
- }
- if (optstring[offset] == ':') {
- colon_mode = 1;
- offset++;
- }
- }
-
- /*
- * charind holds where we left off. If it's set, we were in the middle
- * of an argv element; if not, we pick up with the next element of
- * optind.
- */
- optarg = NULL;
- if (charind == 0) {
- if (optind >= argc)
- option = -1;
- else if (strcmp(argv[optind], "--") == 0) {
- optind++;
- option = -1;
- } else if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
- char *tmp;
- int i, j, k, end;
-
- if (mode == '+')
- option = -1;
- else if (mode == '-') {
- optarg = argv[optind];
- optind++;
- option = 1;
- } else {
- for (i = optind + 1, j = optind; i < argc; i++)
- if ((argv[i][0] == '-') && (argv[i][1] != '\0')) {
- optind = i;
- option = getopt(argc, argv, optstring);
- while (i > j) {
- --i;
- tmp = argv[i];
- end = (charind == 0) ? optind - 1 : optind;
- for (k = i; k + 1 <= end; k++) {
- argv[k] = argv[k + 1];
- }
- argv[end] = tmp;
- --optind;
- }
- break;
- }
- if (i == argc)
- option = -1;
- }
- return option;
- } else {
- charind = 1;
- }
- }
- if (charind != 0) {
- optopt = argv[optind][charind];
- for (p = optstring + offset; *p != '\0'; p++)
- if (optopt == *p) {
- p++;
- if (*p == ':') {
- if (argv[optind][charind + 1] != '\0') {
- optarg = &argv[optind][charind + 1];
- optind++;
- charind = 0;
- } else {
- p++;
- if (*p != ':') {
- charind = 0;
- optind++;
- if (optind >= argc) {
- if (opterr)
- fprintf(stderr, "%s: option requires"
- " an argument -- %c\n", argv[0],
- optopt);
- option = colon_mode ? ':' : '?';
- goto done;
- } else {
- optarg = argv[optind];
- optind++;
- }
- }
- }
- }
- option = optopt;
- }
- if (option == -1) {
- if (opterr)
- fprintf(stderr, "%s: illegal option -- %c\n", argv[0], optopt);
- option = '?';
- }
- }
-
-done:
- if (charind != 0) {
- charind++;
- if (argv[optind][charind] == '\0') {
- optind++;
- charind = 0;
- }
- }
- if (optind > argc)
- optind = argc;
- return option;
-}
diff --git a/src/inlines.c b/src/inlines.c
index f75c846..4ff45ad 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -2,133 +2,154 @@
#include
#include
#include
-#include "bstrlib.h"
+#include
+
#include "stmd.h"
#include "uthash.h"
#include "debug.h"
#include "scanners.h"
#include "utf8.h"
+typedef struct Subject {
+ const gh_buf *buffer;
+ int pos;
+ reference** reference_map;
+ int label_nestlevel;
+} subject;
+
+reference* lookup_reference(reference** refmap, chunk *label);
+reference* make_reference(chunk *label, chunk *url, chunk *title);
+
+static unsigned char *clean_url(chunk *url);
+static unsigned char *clean_title(chunk *title);
+
+inline static unsigned char *chunk_to_cstr(chunk *c);
+inline static void chunk_free(chunk *c);
+inline static void chunk_trim(chunk *c);
+
+inline static chunk chunk_literal(const char *data);
+inline static chunk chunk_buf_detach(gh_buf *buf);
+inline static chunk chunk_buf(const gh_buf *buf, int pos, int len);
+
+static inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
+static inl *parse_inlines_while(subject* subj, int (*f)(subject*));
+static int parse_inline(subject* subj, inl ** last);
+
extern void free_reference(reference *ref) {
- bdestroy(ref->label);
- bdestroy(ref->url);
- bdestroy(ref->title);
- free(ref);
+ free(ref->label);
+ free(ref->url);
+ free(ref->title);
+ free(ref);
}
extern void free_reference_map(reference **refmap) {
- /* free the hash table contents */
- reference *s;
- reference *tmp;
- if (refmap != NULL) {
- HASH_ITER(hh, *refmap, s, tmp) {
- HASH_DEL(*refmap, s);
- free_reference(s);
- }
- free(refmap);
- }
+ /* free the hash table contents */
+ reference *s;
+ reference *tmp;
+ if (refmap != NULL) {
+ HASH_ITER(hh, *refmap, s, tmp) {
+ HASH_DEL(*refmap, s);
+ free_reference(s);
+ }
+ free(refmap);
+ }
}
// normalize reference: collapse internal whitespace to single space,
// remove leading/trailing whitespace, case fold
-static bstring normalize_reference(bstring s)
-{
- bstring normalized = case_fold(s);
- int pos = 0;
- int startpos;
- char c;
- while ((c = bchar(normalized, pos))) {
- if (isspace(c)) {
- startpos = pos;
- // skip til next non-space
- pos++;
- while (isspace(bchar(s, pos))) {
- pos++;
- }
- bdelete(normalized, startpos, pos - startpos);
- binsertch(normalized, startpos, 1, ' ');
- pos = startpos + 1;
- }
- pos++;
- }
- btrimws(normalized);
- return normalized;
+static unsigned char *normalize_reference(chunk *ref)
+{
+ gh_buf normalized = GH_BUF_INIT;
+ int r, w;
+
+ utf8proc_case_fold(&normalized, ref->data, ref->len);
+ gh_buf_trim(&normalized);
+
+ for (r = 0, w = 0; r < normalized.size; ++r) {
+ if (r && gh_buf_at(&normalized, r - 1) == ' ') {
+ while (gh_buf_at(&normalized, r) == ' ')
+ r++;
+ }
+
+ normalized.ptr[w++] = normalized.ptr[r];
+ }
+
+ return gh_buf_detach(&normalized);
}
// Returns reference if refmap contains a reference with matching
// label, otherwise NULL.
-extern reference* lookup_reference(reference** refmap, bstring lab)
+extern reference* lookup_reference(reference** refmap, chunk *label)
{
- reference * ref = NULL;
- bstring label = normalize_reference(lab);
- if (refmap != NULL) {
- HASH_FIND_STR(*refmap, (char*) label->data, ref);
- }
- bdestroy(label);
- return ref;
+ reference *ref = NULL;
+ unsigned char *norm = normalize_reference(label);
+ if (refmap != NULL) {
+ HASH_FIND_STR(*refmap, (char*)norm, ref);
+ }
+ free(label);
+ return ref;
}
-extern reference* make_reference(bstring label, bstring url, bstring title)
+extern reference* make_reference(chunk *label, chunk *url, chunk *title)
{
- reference * ref;
- ref = malloc(sizeof(reference));
- ref->label = normalize_reference(label);
- ref->url = bstrcpy(url);
- ref->title = bstrcpy(title);
- return ref;
+ reference *ref;
+ ref = malloc(sizeof(reference));
+ ref->label = normalize_reference(label);
+ ref->url = clean_url(url);
+ ref->title = clean_title(title);
+ return ref;
}
extern void add_reference(reference** refmap, reference* ref)
{
- reference * t = NULL;
- HASH_FIND(hh, *refmap, (char*) ref->label->data,
- (unsigned) blength(ref->label), t);
- if (t == NULL) {
- HASH_ADD_KEYPTR(hh, *refmap, (char*) ref->label->data,
- (unsigned) blength(ref->label), ref);
- } else {
- free_reference(ref); // we free this now since it won't be in the refmap
- }
+ reference * t = NULL;
+ HASH_FIND(hh, *refmap, (char*)ref->label, (unsigned)strlen(ref->label), t);
+
+ if (t == NULL) {
+ HASH_ADD_KEYPTR(hh, *refmap, (char*)ref->label, (unsigned)strlen(ref->label), ref);
+ } else {
+ free_reference(ref); // we free this now since it won't be in the refmap
+ }
}
// Create an inline with a linkable string value.
-inline static inl* make_linkable(int t, inl* label, bstring url, bstring title)
+inline static inl* make_linkable(int t, inl* label, chunk url, chunk title)
{
- inl* e = (inl*) malloc(sizeof(inl));
- e->tag = t;
- e->content.linkable.label = label;
- e->content.linkable.url = url;
- e->content.linkable.title = title;
- e->next = NULL;
- return e;
+ inl* e = (inl*) malloc(sizeof(inl));
+ e->tag = t;
+ e->content.linkable.label = label;
+ e->content.linkable.url = chunk_to_cstr(&url);
+ e->content.linkable.title = chunk_to_cstr(&title);
+ e->next = NULL;
+ return e;
}
inline static inl* make_inlines(int t, inl* contents)
{
- inl* e = (inl*) malloc(sizeof(inl));
- e->tag = t;
- e->content.inlines = contents;
- e->next = NULL;
- return e;
+ inl* e = (inl*) malloc(sizeof(inl));
+ e->tag = t;
+ e->content.inlines = contents;
+ e->next = NULL;
+ return e;
}
// Create an inline with a literal string value.
-inline static inl* make_literal(int t, bstring s)
+inline static inl* make_literal(int t, chunk s)
{
- inl* e = (inl*) malloc(sizeof(inl));
- e->tag = t;
- e->content.literal = s;
- e->next = NULL;
- return e;
+ inl* e = (inl*) malloc(sizeof(inl));
+ e->tag = t;
+ e->content.literal = s;
+ e->next = NULL;
+ return e;
}
// Create an inline with no value.
inline static inl* make_simple(int t)
{
- inl* e = (inl*) malloc(sizeof(inl));
- e->tag = t;
- e->next = NULL;
- return e;
+ inl* e = (inl*) malloc(sizeof(inl));
+ e->tag = t;
+ e->next = NULL;
+ return e;
}
// Macros for creating various kinds of inlines.
@@ -139,113 +160,157 @@ inline static inl* make_simple(int t)
#define make_linebreak() make_simple(linebreak)
#define make_softbreak() make_simple(softbreak)
#define make_link(label, url, title) make_linkable(link, label, url, title)
-#define make_image(alt, url, title) make_linkable(image, alt, url, title)
#define make_emph(contents) make_inlines(emph, contents)
#define make_strong(contents) make_inlines(strong, contents)
// Free an inline list.
extern void free_inlines(inl* e)
{
- inl * next;
- while (e != NULL) {
- switch (e->tag){
- case str:
- case raw_html:
- case code:
- case entity:
- bdestroy(e->content.literal);
- break;
- case linebreak:
- case softbreak:
- break;
- case link:
- case image:
- bdestroy(e->content.linkable.url);
- bdestroy(e->content.linkable.title);
- free_inlines(e->content.linkable.label);
- break;
- case emph:
- case strong:
- free_inlines(e->content.inlines);
- break;
- default:
- break;
- }
- next = e->next;
- free(e);
- e = next;
- }
+ inl * next;
+ while (e != NULL) {
+ switch (e->tag){
+ case str:
+ case raw_html:
+ case code:
+ case entity:
+ chunk_free(&e->content.literal);
+ break;
+ case linebreak:
+ case softbreak:
+ break;
+ case link:
+ case image:
+ free(e->content.linkable.url);
+ free(e->content.linkable.title);
+ free_inlines(e->content.linkable.label);
+ break;
+ case emph:
+ case strong:
+ free_inlines(e->content.inlines);
+ break;
+ default:
+ break;
+ }
+ next = e->next;
+ free(e);
+ e = next;
+ }
}
// Append inline list b to the end of inline list a.
// Return pointer to head of new list.
inline static inl* append_inlines(inl* a, inl* b)
{
- if (a == NULL) { // NULL acts like an empty list
- return b;
- }
- inl* cur = a;
- while (cur->next) {
- cur = cur->next;
- }
- cur->next = b;
- return a;
+ if (a == NULL) { // NULL acts like an empty list
+ return b;
+ }
+ inl* cur = a;
+ while (cur->next) {
+ cur = cur->next;
+ }
+ cur->next = b;
+ return a;
}
// Make a 'subject' from an input string.
-static subject* make_subject(bstring s, reference** refmap)
+static void init_subject(subject *e, gh_buf *buffer, int input_pos, reference** refmap)
{
- subject* e = (subject*) malloc(sizeof(subject));
- // remove final whitespace
- brtrimws(s);
- e->buffer = s;
- e->pos = 0;
- e->label_nestlevel = 0;
- e->reference_map = refmap;
- return e;
+ e->buffer = buffer;
+ e->pos = input_pos;
+ e->label_nestlevel = 0;
+ e->reference_map = refmap;
}
inline static int isbacktick(int c)
{
- return (c == '`');
+ return (c == '`');
+}
+
+inline static void chunk_free(chunk *c)
+{
+ if (c->alloc)
+ free((char *)c->data);
+
+ c->data = NULL;
+ c->alloc = 0;
+ c->len = 0;
+}
+
+inline static void chunk_trim(chunk *c)
+{
+ while (c->len && isspace(c->data[0])) {
+ c->data++;
+ c->len--;
+ }
+
+ while (c->len > 0) {
+ if (!isspace(c->data[c->len - 1]))
+ break;
+
+ c->len--;
+ }
+}
+
+inline static unsigned char *chunk_to_cstr(chunk *c)
+{
+ unsigned char *str;
+
+ str = malloc(c->len + 1);
+ memcpy(str, c->data, c->len);
+ str[c->len] = 0;
+
+ return str;
+}
+
+inline static chunk chunk_literal(const char *data)
+{
+ chunk c = {data, strlen(data), 0};
+ return c;
+}
+
+inline static chunk chunk_buf(const gh_buf *buf, int pos, int len)
+{
+ chunk c = {buf->ptr + pos, len, 0};
+ return c;
+}
+
+inline static chunk chunk_buf_detach(gh_buf *buf)
+{
+ chunk c;
+
+ c.len = buf->size;
+ c.data = gh_buf_detach(buf);
+ c.alloc = 1;
+
+ return c;
}
// Return the next character in the subject, without advancing.
// Return 0 if at the end of the subject.
-#define peek_char(subj) bchar(subj->buffer, subj->pos)
+#define peek_char(subj) gh_buf_at((subj)->buffer, (subj)->pos)
// Return true if there are more characters in the subject.
inline static int is_eof(subject* subj)
{
- return (subj->pos >= blength(subj->buffer));
+ return (subj->pos >= gh_buf_len(subj->buffer));
}
// Advance the subject. Doesn't check for eof.
-#define advance(subj) subj->pos += 1
+#define advance(subj) (subj)->pos += 1
// Take characters while a predicate holds, and return a string.
-inline static bstring take_while(subject* subj, int (*f)(int))
+inline static chunk take_while(subject* subj, int (*f)(int))
{
- unsigned char c;
- int startpos = subj->pos;
- int len = 0;
- while ((c = peek_char(subj)) && (*f)(c)) {
- advance(subj);
- len++;
- }
- return bmidstr(subj->buffer, startpos, len);
-}
+ unsigned char c;
+ int startpos = subj->pos;
+ int len = 0;
-// Take one character and return a string, or NULL if eof.
-inline static bstring take_one(subject* subj)
-{
- int startpos = subj->pos;
- if (is_eof(subj)){
- return NULL;
- } else {
- advance(subj);
- return bmidstr(subj->buffer, startpos, 1);
- }
+ while ((c = peek_char(subj)) && (*f)(c)) {
+ advance(subj);
+ len++;
+ }
+
+ return chunk_buf(subj->buffer, startpos, len);
}
// Try to process a backtick code span that began with a
@@ -255,381 +320,406 @@ inline static bstring take_one(subject* subj)
// after the closing backticks.
static int scan_to_closing_backticks(subject* subj, int openticklength)
{
- // read non backticks
- char c;
- while ((c = peek_char(subj)) && c != '`') {
- advance(subj);
- }
- if (is_eof(subj)) {
- return 0; // did not find closing ticks, return 0
- }
- int numticks = 0;
- while (peek_char(subj) == '`') {
- advance(subj);
- numticks++;
- }
- if (numticks != openticklength){
- return(scan_to_closing_backticks(subj, openticklength));
- }
- return (subj->pos);
-}
-
-// Destructively modify bstring, collapsing consecutive
+ // read non backticks
+ char c;
+ while ((c = peek_char(subj)) && c != '`') {
+ advance(subj);
+ }
+ if (is_eof(subj)) {
+ return 0; // did not find closing ticks, return 0
+ }
+ int numticks = 0;
+ while (peek_char(subj) == '`') {
+ advance(subj);
+ numticks++;
+ }
+ if (numticks != openticklength){
+ return(scan_to_closing_backticks(subj, openticklength));
+ }
+ return (subj->pos);
+}
+
+// Destructively modify string, collapsing consecutive
// space and newline characters into a single space.
-static int normalize_whitespace(bstring s)
-{
- bool last_char_was_space = false;
- int pos = 0;
- char c;
- while ((c = bchar(s, pos))) {
- switch (c) {
- case ' ':
- if (last_char_was_space) {
- bdelete(s, pos, 1);
- } else {
- pos++;
- }
- last_char_was_space = true;
- break;
- case '\n':
- if (last_char_was_space) {
- bdelete(s, pos, 1);
- } else {
- bdelete(s, pos, 1);
- binsertch(s, pos, 1, ' ');
- pos++;
- }
- last_char_was_space = true;
- break;
- default:
- pos++;
- last_char_was_space = false;
- }
- }
- return 0;
+static void normalize_whitespace(gh_buf *s)
+{
+ /* TODO */
+#if 0
+ bool last_char_was_space = false;
+ int pos = 0;
+ char c;
+ while ((c = gh_buf_at(s, pos))) {
+ switch (c) {
+ case ' ':
+ if (last_char_was_space) {
+ bdelete(s, pos, 1);
+ } else {
+ pos++;
+ }
+ last_char_was_space = true;
+ break;
+ case '\n':
+ if (last_char_was_space) {
+ bdelete(s, pos, 1);
+ } else {
+ bdelete(s, pos, 1);
+ binsertch(s, pos, 1, ' ');
+ pos++;
+ }
+ last_char_was_space = true;
+ break;
+ default:
+ pos++;
+ last_char_was_space = false;
+ }
+ }
+#endif
}
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
static inl* handle_backticks(subject *subj)
{
- bstring openticks = take_while(subj, isbacktick);
- bstring result;
- int ticklength = blength(openticks);
- int startpos = subj->pos;
- int endpos = scan_to_closing_backticks(subj, ticklength);
- if (endpos == 0) { // not found
- subj->pos = startpos; // rewind
- return make_str(openticks);
- } else {
- bdestroy(openticks);
- result = bmidstr(subj->buffer, startpos, endpos - startpos - ticklength);
- btrimws(result);
- normalize_whitespace(result);
- return make_code(result);
- }
+ chunk openticks = take_while(subj, isbacktick);
+ int startpos = subj->pos;
+ int endpos = scan_to_closing_backticks(subj, openticks.len);
+
+ if (endpos == 0) { // not found
+ subj->pos = startpos; // rewind
+ return make_str(openticks);
+ } else {
+ gh_buf buf = GH_BUF_INIT;
+
+ gh_buf_set(&buf, subj->buffer->ptr + startpos, endpos - startpos - openticks.len);
+ gh_buf_trim(&buf);
+ normalize_whitespace(&buf);
+
+ return make_code(chunk_buf_detach(&buf));
+ }
}
// Scan ***, **, or * and return number scanned, or 0.
// Don't advance position.
static int scan_delims(subject* subj, char c, bool * can_open, bool * can_close)
{
- int numdelims = 0;
- char char_before, char_after;
- int startpos = subj->pos;
-
- char_before = subj->pos == 0 ? '\n' : bchar(subj->buffer, subj->pos - 1);
- while (peek_char(subj) == c) {
- numdelims++;
- advance(subj);
- }
- char_after = peek_char(subj);
- *can_open = numdelims > 0 && numdelims <= 3 && !isspace(char_after);
- *can_close = numdelims > 0 && numdelims <= 3 && !isspace(char_before);
- if (c == '_') {
- *can_open = *can_open && !isalnum(char_before);
- *can_close = *can_close && !isalnum(char_after);
- }
- subj->pos = startpos;
- return numdelims;
+ int numdelims = 0;
+ char char_before, char_after;
+ int startpos = subj->pos;
+
+ char_before = subj->pos == 0 ? '\n' : gh_buf_at(subj->buffer, subj->pos - 1);
+ while (peek_char(subj) == c) {
+ numdelims++;
+ advance(subj);
+ }
+ char_after = peek_char(subj);
+ *can_open = numdelims > 0 && numdelims <= 3 && !isspace(char_after);
+ *can_close = numdelims > 0 && numdelims <= 3 && !isspace(char_before);
+ if (c == '_') {
+ *can_open = *can_open && !isalnum(char_before);
+ *can_close = *can_close && !isalnum(char_after);
+ }
+ subj->pos = startpos;
+ return numdelims;
}
// Parse strong/emph or a fallback.
// Assumes the subject has '_' or '*' at the current position.
static inl* handle_strong_emph(subject* subj, char c)
{
- bool can_open, can_close;
- inl * result = NULL;
- inl ** last = malloc(sizeof(inl *));
- inl * new;
- inl * il;
- inl * first_head = NULL;
- inl * first_close = NULL;
- int first_close_delims = 0;
- int numdelims;
-
- *last = NULL;
-
- numdelims = scan_delims(subj, c, &can_open, &can_close);
- subj->pos += numdelims;
-
- new = make_str(bmidstr(subj->buffer, subj->pos - numdelims, numdelims));
- *last = new;
- first_head = new;
- result = new;
-
- if (!can_open || numdelims == 0) {
- goto done;
- }
-
- switch (numdelims) {
- case 1:
- while (true) {
- numdelims = scan_delims(subj, c, &can_open, &can_close);
- if (numdelims >= 1 && can_close) {
- subj->pos += 1;
- first_head->tag = emph;
- bdestroy(first_head->content.literal);
- first_head->content.inlines = first_head->next;
- first_head->next = NULL;
- goto done;
- } else {
- if (!parse_inline(subj, last)) {
- goto done;
- }
- }
- }
- break;
- case 2:
- while (true) {
- numdelims = scan_delims(subj, c, &can_open, &can_close);
- if (numdelims >= 2 && can_close) {
- subj->pos += 2;
- first_head->tag = strong;
- bdestroy(first_head->content.literal);
- first_head->content.inlines = first_head->next;
- first_head->next = NULL;
- goto done;
- } else {
- if (!parse_inline(subj, last)) {
- goto done;
- }
- }
- }
- break;
- case 3:
- while (true) {
- numdelims = scan_delims(subj, c, &can_open, &can_close);
- if (can_close && numdelims >= 1 && numdelims <= 3 &&
- numdelims != first_close_delims) {
- new = make_str(bmidstr(subj->buffer, subj->pos, numdelims));
- append_inlines(*last, new);
- *last = new;
-
- if (first_close_delims == 1 && numdelims > 2) {
- numdelims = 2;
- } else if (first_close_delims == 2) {
- numdelims = 1;
- } else if (numdelims == 3) {
- // If we opened with ***, we interpret it as ** followed by *
- // giving us
- numdelims = 1;
- }
-
- subj->pos += numdelims;
- if (first_close) {
- first_head->tag = first_close_delims == 1 ? strong : emph;
- bdestroy(first_head->content.literal);
- first_head->content.inlines =
- make_inlines(first_close_delims == 1 ? emph : strong,
- first_head->next);
-
- il = first_head->next;
- while (il->next && il->next != first_close) {
- il = il->next;
- }
- il->next = NULL;
-
- first_head->content.inlines->next = first_close->next;
-
- il = first_head->content.inlines;
- while (il->next && il->next != *last) {
- il = il->next;
- }
- il->next = NULL;
- free_inlines(*last);
-
- first_close->next = NULL;
- free_inlines(first_close);
- first_head->next = NULL;
- goto done;
- } else {
- first_close = *last;
- first_close_delims = numdelims;
- }
- } else {
- if (!parse_inline(subj, last)) {
- goto done;
- }
- }
- }
- break;
- default:
- goto done;
- }
-
- done:
- free(last);
- return result;
+ bool can_open, can_close;
+ inl * result = NULL;
+ inl ** last = malloc(sizeof(inl *));
+ inl * new;
+ inl * il;
+ inl * first_head = NULL;
+ inl * first_close = NULL;
+ int first_close_delims = 0;
+ int numdelims;
+
+ *last = NULL;
+
+ numdelims = scan_delims(subj, c, &can_open, &can_close);
+ subj->pos += numdelims;
+
+ new = make_str(chunk_buf(subj->buffer, subj->pos - numdelims, numdelims));
+ *last = new;
+ first_head = new;
+ result = new;
+
+ if (!can_open || numdelims == 0) {
+ goto done;
+ }
+
+ switch (numdelims) {
+ case 1:
+ while (true) {
+ numdelims = scan_delims(subj, c, &can_open, &can_close);
+ if (numdelims >= 1 && can_close) {
+ subj->pos += 1;
+ first_head->tag = emph;
+ chunk_free(&first_head->content.literal);
+ first_head->content.inlines = first_head->next;
+ first_head->next = NULL;
+ goto done;
+ } else {
+ if (!parse_inline(subj, last)) {
+ goto done;
+ }
+ }
+ }
+ break;
+ case 2:
+ while (true) {
+ numdelims = scan_delims(subj, c, &can_open, &can_close);
+ if (numdelims >= 2 && can_close) {
+ subj->pos += 2;
+ first_head->tag = strong;
+ chunk_free(&first_head->content.literal);
+ first_head->content.inlines = first_head->next;
+ first_head->next = NULL;
+ goto done;
+ } else {
+ if (!parse_inline(subj, last)) {
+ goto done;
+ }
+ }
+ }
+ break;
+ case 3:
+ while (true) {
+ numdelims = scan_delims(subj, c, &can_open, &can_close);
+ if (can_close && numdelims >= 1 && numdelims <= 3 &&
+ numdelims != first_close_delims) {
+ new = make_str(chunk_buf(subj->buffer, subj->pos, numdelims));
+ append_inlines(*last, new);
+ *last = new;
+ if (first_close_delims == 1 && numdelims > 2) {
+ numdelims = 2;
+ } else if (first_close_delims == 2) {
+ numdelims = 1;
+ } else if (numdelims == 3) {
+ // If we opened with ***, we interpret it as ** followed by *
+ // giving us
+ numdelims = 1;
+ }
+ subj->pos += numdelims;
+ if (first_close) {
+ first_head->tag = first_close_delims == 1 ? strong : emph;
+ chunk_free(&first_head->content.literal);
+ first_head->content.inlines =
+ make_inlines(first_close_delims == 1 ? emph : strong,
+ first_head->next);
+
+ il = first_head->next;
+ while (il->next && il->next != first_close) {
+ il = il->next;
+ }
+ il->next = NULL;
+
+ first_head->content.inlines->next = first_close->next;
+
+ il = first_head->content.inlines;
+ while (il->next && il->next != *last) {
+ il = il->next;
+ }
+ il->next = NULL;
+ free_inlines(*last);
+
+ first_close->next = NULL;
+ free_inlines(first_close);
+ first_head->next = NULL;
+ goto done;
+ } else {
+ first_close = *last;
+ first_close_delims = numdelims;
+ }
+ } else {
+ if (!parse_inline(subj, last)) {
+ goto done;
+ }
+ }
+ }
+ break;
+ default:
+ goto done;
+ }
+
+done:
+ free(last);
+ return result;
}
// Parse backslash-escape or just a backslash, returning an inline.
static inl* handle_backslash(subject *subj)
{
- advance(subj);
- unsigned char nextchar = peek_char(subj);
- if (ispunct(nextchar)) { // only ascii symbols and newline can be escaped
- advance(subj);
- return make_str(bformat("%c", nextchar));
- } else if (nextchar == '\n') {
- advance(subj);
- return make_linebreak();
- } else {
- return make_str(bfromcstr("\\"));
- }
+ advance(subj);
+ unsigned char nextchar = peek_char(subj);
+ if (ispunct(nextchar)) { // only ascii symbols and newline can be escaped
+ advance(subj);
+ return make_str(chunk_buf(subj->buffer, subj->pos - 1, 1));
+ } else if (nextchar == '\n') {
+ advance(subj);
+ return make_linebreak();
+ } else {
+ return make_str(chunk_literal("\\"));
+ }
}
// Parse an entity or a regular "&" string.
// Assumes the subject has an '&' character at the current position.
static inl* handle_entity(subject* subj)
{
- int match;
- inl * result;
- match = scan_entity(subj->buffer, subj->pos);
- if (match) {
- result = make_entity(bmidstr(subj->buffer, subj->pos, match));
- subj->pos += match;
- } else {
- advance(subj);
- result = make_str(bfromcstr("&"));
- }
- return result;
+ int match;
+ inl *result;
+ match = scan_entity(subj->buffer, subj->pos);
+ if (match) {
+ result = make_entity(chunk_buf(subj->buffer, subj->pos, match));
+ subj->pos += match;
+ } else {
+ advance(subj);
+ result = make_str(chunk_literal("&"));
+ }
+ return result;
}
// Like make_str, but parses entities.
// Returns an inline sequence consisting of str and entity elements.
-static inl * make_str_with_entities(bstring s)
-{
- inl * result = NULL;
- inl * new;
- int searchpos;
- char c;
- subject * subj = make_subject(s, NULL);
-
- while ((c = peek_char(subj))) {
- switch (c) {
- case '&':
- new = handle_entity(subj);
- break;
- default:
- searchpos = bstrchrp(subj->buffer, '&', subj->pos);
- if (searchpos == BSTR_ERR) {
- searchpos = blength(subj->buffer);
- }
- new = make_str(bmidstr(subj->buffer, subj->pos, searchpos - subj->pos));
- subj->pos = searchpos;
- }
- result = append_inlines(result, new);
- }
- free(subj);
- return result;
+static inl *make_str_with_entities(chunk *content)
+{
+ inl * result = NULL;
+ inl * new;
+ int searchpos;
+ char c;
+ subject subj;
+ gh_buf content_buf = GH_BUF_INIT;
+
+ gh_buf_set(&content_buf, content->data, content->len);
+ init_subject(&subj, &content_buf, 0, NULL);
+
+ while ((c = peek_char(&subj))) {
+ switch (c) {
+ case '&':
+ new = handle_entity(&subj);
+ break;
+ default:
+ searchpos = gh_buf_strchr(subj.buffer, '&', subj.pos);
+ if (searchpos < 0) {
+ searchpos = gh_buf_len(subj.buffer);
+ }
+
+ new = make_str(chunk_buf(subj.buffer, subj.pos, searchpos - subj.pos));
+ subj.pos = searchpos;
+ }
+ result = append_inlines(result, new);
+ }
+
+ gh_buf_free(&content_buf);
+ return result;
}
// Destructively unescape a string: remove backslashes before punctuation chars.
-extern int unescape(bstring url)
+extern void unescape_buffer(gh_buf *buf)
{
- // remove backslashes before punctuation chars:
- int searchpos = 0;
- while ((searchpos = bstrchrp(url, '\\', searchpos)) != BSTR_ERR) {
- if (ispunct(bchar(url, searchpos + 1))) {
- bdelete(url, searchpos, 1);
- } else {
- searchpos++;
- }
- }
- return 0;
+ int r, w;
+
+ for (r = 0, w = 0; r < buf->size; ++r) {
+ if (buf->ptr[r] == '\\' && ispunct(buf->ptr[r + 1]))
+ continue;
+
+ buf->ptr[w++] = buf->ptr[r];
+ }
+
+ gh_buf_truncate(buf, w);
}
// Clean a URL: remove surrounding whitespace and surrounding <>,
// and remove \ that escape punctuation.
-static int clean_url(bstring url)
+static unsigned char *clean_url(chunk *url)
{
- // remove surrounding <> if any:
- int urllength = blength(url);
- btrimws(url);
- if (bchar(url, 0) == '<' && bchar(url, urllength - 1) == '>') {
- bdelete(url, 0, 1);
- bdelete(url, urllength - 2, 1);
- }
- unescape(url);
- return 0;
+ gh_buf buf = GH_BUF_INIT;
+
+ chunk_trim(url);
+
+ if (url->data[0] == '<' && url->data[url->len - 1] == '>') {
+ gh_buf_set(&buf, url->data + 1, url->len - 2);
+ } else {
+ gh_buf_set(&buf, url->data, url->len);
+ }
+
+ unescape_buffer(&buf);
+ return gh_buf_detach(&buf);
}
// Clean a title: remove surrounding quotes and remove \ that escape punctuation.
-static int clean_title(bstring title)
+static unsigned char *clean_title(chunk *title)
{
- // remove surrounding quotes if any:
- int titlelength = blength(title);
- if ((bchar(title, 0) == '\'' && bchar(title, titlelength - 1) == '\'') ||
- (bchar(title, 0) == '(' && bchar(title, titlelength - 1) == ')') ||
- (bchar(title, 0) == '"' && bchar(title, titlelength - 1) == '"')) {
- bdelete(title, 0, 1);
- bdelete(title, titlelength - 2, 1);
- }
- unescape(title);
- return 0;
+ gh_buf buf = GH_BUF_INIT;
+ unsigned char first = title->data[0];
+ unsigned char last = title->data[title->len - 1];
+
+ // remove surrounding quotes if any:
+ if ((first == '\'' && last == '\'') ||
+ (first == '(' && last == ')') ||
+ (first == '"' && last == '"')) {
+ gh_buf_set(&buf, title->data + 1, title->len - 2);
+ } else {
+ gh_buf_set(&buf, title->data, title->len);
+ }
+
+ unescape_buffer(&buf);
+ return gh_buf_detach(&buf);
}
// Parse an autolink or HTML tag.
// Assumes the subject has a '<' character at the current position.
static inl* handle_pointy_brace(subject* subj)
{
- int matchlen = 0;
- bstring contents;
- inl* result;
-
- advance(subj); // advance past first <
- // first try to match a URL autolink
- matchlen = scan_autolink_uri(subj->buffer, subj->pos);
- if (matchlen > 0) {
- contents = bmidstr(subj->buffer, subj->pos, matchlen - 1);
- subj->pos += matchlen;
- result = make_link(make_str_with_entities(contents),
- bstrcpy(contents), bfromcstr(""));
- bdestroy(contents);
- return result;
- }
- // next try to match an email autolink
- matchlen = scan_autolink_email(subj->buffer, subj->pos);
- if (matchlen > 0) {
- contents = bmidstr(subj->buffer, subj->pos, matchlen - 1);
- subj->pos += matchlen;
- result = make_link(make_str_with_entities(contents),
- bformat("mailto:%s", contents->data),
- bfromcstr(""));
- bdestroy(contents);
- return result;
- }
- // finally, try to match an html tag
- matchlen = scan_html_tag(subj->buffer, subj->pos);
- if (matchlen > 0) {
- contents = bmidstr(subj->buffer, subj->pos, matchlen);
- binsertch(contents, 0, 1, '<');
- subj->pos += matchlen;
- return make_raw_html(contents);
- } else {// if nothing matches, just return the opening <:
- return make_str(bfromcstr("<"));
- }
+ int matchlen = 0;
+ chunk contents;
+
+ advance(subj); // advance past first <
+
+ // first try to match a URL autolink
+ matchlen = scan_autolink_uri(subj->buffer, subj->pos);
+ if (matchlen > 0) {
+ contents = chunk_buf(subj->buffer, subj->pos, matchlen - 1);
+ subj->pos += matchlen;
+
+ return make_link(
+ make_str_with_entities(&contents),
+ contents,
+ chunk_literal("")
+ );
+ }
+
+ // next try to match an email autolink
+ matchlen = scan_autolink_email(subj->buffer, subj->pos);
+ if (matchlen > 0) {
+ gh_buf mail_url = GH_BUF_INIT;
+
+ contents = chunk_buf(subj->buffer, subj->pos, matchlen - 1);
+ subj->pos += matchlen;
+
+ gh_buf_puts(&mail_url, "mailto:");
+ gh_buf_put(&mail_url, contents.data, contents.len);
+
+ return make_link(
+ make_str_with_entities(&contents),
+ chunk_buf_detach(&mail_url),
+ chunk_literal("")
+ );
+ }
+
+ // finally, try to match an html tag
+ matchlen = scan_html_tag(subj->buffer, subj->pos);
+ if (matchlen > 0) {
+ contents = chunk_buf(subj->buffer, subj->pos - 1, matchlen + 1);
+ subj->pos += matchlen;
+ return make_raw_html(contents);
+ }
+
+ // if nothing matches, just return the opening <:
+ return make_str(chunk_literal("<"));
}
// Parse a link label. Returns 1 if successful.
@@ -641,366 +731,381 @@ static inl* handle_pointy_brace(subject* subj)
// markers. So, 2 below contains a link while 1 does not:
// 1. [a link `with a ](/url)` character
// 2. [a link *with emphasized ](/url) text*
-static int link_label(subject* subj, bstring* raw_label)
-{
- int nestlevel = 0;
- inl* tmp = NULL;
- bstring raw;
- int startpos = subj->pos;
- if (subj->label_nestlevel) {
- // if we've already checked to the end of the subject
- // for a label, even with a different starting [, we
- // know we won't find one here and we can just return.
- // Note: nestlevel 1 would be: [foo [bar]
- // nestlevel 2 would be: [foo [bar [baz]
- subj->label_nestlevel--;
- return 0;
- }
- advance(subj); // advance past [
- char c;
- while ((c = peek_char(subj)) && (c != ']' || nestlevel > 0)) {
- switch (c) {
- case '`':
- tmp = handle_backticks(subj);
- free_inlines(tmp);
- break;
- case '<':
- tmp = handle_pointy_brace(subj);
- free_inlines(tmp);
- break;
- case '[': // nested []
- nestlevel++;
- advance(subj);
- break;
- case ']': // nested []
- nestlevel--;
- advance(subj);
- break;
- case '\\':
- advance(subj);
- if (ispunct(peek_char(subj))) {
- advance(subj);
- }
- break;
- default:
- advance(subj);
- }
- }
- if (c == ']') {
- if (raw_label != NULL) {
- raw = bmidstr(subj->buffer, startpos + 1, subj->pos - (startpos + 1));
- *raw_label = raw;
- }
- subj->label_nestlevel = 0;
- advance(subj); // advance past ]
- return 1;
- } else {
- if (c == 0) {
- subj->label_nestlevel = nestlevel;
- }
- subj->pos = startpos; // rewind
- return 0;
- }
+static int link_label(subject* subj, chunk *raw_label)
+{
+ int nestlevel = 0;
+ inl* tmp = NULL;
+ int startpos = subj->pos;
+
+ if (subj->label_nestlevel) {
+ // if we've already checked to the end of the subject
+ // for a label, even with a different starting [, we
+ // know we won't find one here and we can just return.
+ // Note: nestlevel 1 would be: [foo [bar]
+ // nestlevel 2 would be: [foo [bar [baz]
+ subj->label_nestlevel--;
+ return 0;
+ }
+
+ advance(subj); // advance past [
+ char c;
+ while ((c = peek_char(subj)) && (c != ']' || nestlevel > 0)) {
+ switch (c) {
+ case '`':
+ tmp = handle_backticks(subj);
+ free_inlines(tmp);
+ break;
+ case '<':
+ tmp = handle_pointy_brace(subj);
+ free_inlines(tmp);
+ break;
+ case '[': // nested []
+ nestlevel++;
+ advance(subj);
+ break;
+ case ']': // nested []
+ nestlevel--;
+ advance(subj);
+ break;
+ case '\\':
+ advance(subj);
+ if (ispunct(peek_char(subj))) {
+ advance(subj);
+ }
+ break;
+ default:
+ advance(subj);
+ }
+ }
+ if (c == ']') {
+ *raw_label = chunk_buf(
+ subj->buffer,
+ startpos + 1,
+ subj->pos - (startpos + 1)
+ );
+
+ subj->label_nestlevel = 0;
+ advance(subj); // advance past ]
+ return 1;
+ } else {
+ if (c == 0) {
+ subj->label_nestlevel = nestlevel;
+ }
+ subj->pos = startpos; // rewind
+ return 0;
+ }
}
// Parse a link or the link portion of an image, or return a fallback.
static inl* handle_left_bracket(subject* subj)
{
- inl* lab = NULL;
- inl* result = NULL;
- reference* ref;
- int n;
- int sps;
- int found_label;
- int endlabel, starturl, endurl, starttitle, endtitle, endall;
- bstring url, title, rawlabel, reflabel;
- bstring rawlabel2 = NULL;
- found_label = link_label(subj, &rawlabel);
- endlabel = subj->pos;
- if (found_label) {
- if (peek_char(subj) == '(' &&
- ((sps = scan_spacechars(subj->buffer, subj->pos + 1)) > -1) &&
- ((n = scan_link_url(subj->buffer, subj->pos + 1 + sps)) > -1)) {
- // try to parse an explicit link:
- starturl = subj->pos + 1 + sps; // after (
- endurl = starturl + n;
- starttitle = endurl + scan_spacechars(subj->buffer, endurl);
- // ensure there are spaces btw url and title
- endtitle = (starttitle == endurl) ? starttitle :
- starttitle + scan_link_title(subj->buffer, starttitle);
- endall = endtitle + scan_spacechars(subj->buffer, endtitle);
- if (bchar(subj->buffer, endall) == ')') {
- subj->pos = endall + 1;
- url = bmidstr(subj->buffer, starturl, endurl - starturl);
- clean_url(url);
- title = bmidstr(subj->buffer, starttitle, endtitle - starttitle);
- clean_title(title);
- lab = parse_inlines(rawlabel, NULL);
- bdestroy(rawlabel);
- return make_link(lab, url, title);
- } else {
- // if we get here, we matched a label but didn't get further:
- subj->pos = endlabel;
- lab = parse_inlines(rawlabel, subj->reference_map);
- bdestroy(rawlabel);
- result = append_inlines(make_str(bfromcstr("[")),
- append_inlines(lab,
- make_str(bfromcstr("]"))));
- return result;
- }
- } else {
- // Check for reference link.
- // First, see if there's another label:
- subj->pos = subj->pos + scan_spacechars(subj->buffer, endlabel);
- reflabel = rawlabel;
- // if followed by a nonempty link label, we change reflabel to it:
- if (peek_char(subj) == '[' &&
- link_label(subj, &rawlabel2)) {
- if (blength(rawlabel2) > 0) {
- reflabel = rawlabel2;
- }
- } else {
- subj->pos = endlabel;
- }
- // lookup rawlabel in subject->reference_map:
- ref = lookup_reference(subj->reference_map, reflabel);
- if (ref != NULL) { // found
- lab = parse_inlines(rawlabel, NULL);
- result = make_link(lab, bstrcpy(ref->url), bstrcpy(ref->title));
- } else {
- subj->pos = endlabel;
- lab = parse_inlines(rawlabel, subj->reference_map);
- result = append_inlines(make_str(bfromcstr("[")),
- append_inlines(lab, make_str(bfromcstr("]"))));
- }
- bdestroy(rawlabel);
- bdestroy(rawlabel2);
- return result;
- }
- }
- // If we fall through to here, it means we didn't match a link:
- advance(subj); // advance past [
- return make_str(bfromcstr("["));
+ inl *lab = NULL;
+ inl *result = NULL;
+ reference *ref;
+ int n;
+ int sps;
+ int found_label;
+ int endlabel, starturl, endurl, starttitle, endtitle, endall;
+
+ chunk rawlabel;
+ chunk url, title;
+
+ found_label = link_label(subj, &rawlabel);
+ endlabel = subj->pos;
+
+ if (found_label) {
+ if (peek_char(subj) == '(' &&
+ ((sps = scan_spacechars(subj->buffer, subj->pos + 1)) > -1) &&
+ ((n = scan_link_url(subj->buffer, subj->pos + 1 + sps)) > -1)) {
+
+ // try to parse an explicit link:
+ starturl = subj->pos + 1 + sps; // after (
+ endurl = starturl + n;
+ starttitle = endurl + scan_spacechars(subj->buffer, endurl);
+
+ // ensure there are spaces btw url and title
+ endtitle = (starttitle == endurl) ? starttitle :
+ starttitle + scan_link_title(subj->buffer, starttitle);
+
+ endall = endtitle + scan_spacechars(subj->buffer, endtitle);
+
+ if (gh_buf_at(subj->buffer, endall) == ')') {
+ subj->pos = endall + 1;
+
+ url = chunk_buf(subj->buffer, starturl, endurl - starturl);
+ title = chunk_buf(subj->buffer, starttitle, endtitle - starttitle);
+ lab = parse_chunk_inlines(&rawlabel, NULL);
+
+ return make_link(lab, url, title);
+ } else {
+ // if we get here, we matched a label but didn't get further:
+ subj->pos = endlabel;
+ lab = parse_chunk_inlines(&rawlabel, subj->reference_map);
+ result = append_inlines(make_str(chunk_literal("[")),
+ append_inlines(lab,
+ make_str(chunk_literal("]"))));
+ return result;
+ }
+ } else {
+ chunk rawlabel_tmp;
+ chunk reflabel;
+
+ // Check for reference link.
+ // First, see if there's another label:
+ subj->pos = subj->pos + scan_spacechars(subj->buffer, endlabel);
+ reflabel = rawlabel;
+
+ // if followed by a nonempty link label, we change reflabel to it:
+ if (peek_char(subj) == '[' && link_label(subj, &rawlabel_tmp)) {
+ if (rawlabel_tmp.len > 0)
+ reflabel = rawlabel_tmp;
+ } else {
+ subj->pos = endlabel;
+ }
+
+ // lookup rawlabel in subject->reference_map:
+ ref = lookup_reference(subj->reference_map, &reflabel);
+ if (ref != NULL) { // found
+ lab = parse_chunk_inlines(&rawlabel, NULL);
+ result = make_link(lab, chunk_literal(ref->url), chunk_literal(ref->title));
+ } else {
+ subj->pos = endlabel;
+ lab = parse_chunk_inlines(&rawlabel, subj->reference_map);
+ result = append_inlines(make_str(chunk_literal("[")),
+ append_inlines(lab, make_str(chunk_literal("]"))));
+ }
+ return result;
+ }
+ }
+ // If we fall through to here, it means we didn't match a link:
+ advance(subj); // advance past [
+ return make_str(chunk_literal("["));
}
// Parse a hard or soft linebreak, returning an inline.
// Assumes the subject has a newline at the current position.
static inl* handle_newline(subject *subj)
{
- int nlpos = subj->pos;
- // skip over newline
- advance(subj);
- // skip spaces at beginning of line
- while (peek_char(subj) == ' ') {
- advance(subj);
- }
- if (nlpos > 1 &&
- bchar(subj->buffer, nlpos - 1) == ' ' &&
- bchar(subj->buffer, nlpos - 2) == ' ') {
- return make_linebreak();
- } else {
- return make_softbreak();
- }
+ int nlpos = subj->pos;
+ // skip over newline
+ advance(subj);
+ // skip spaces at beginning of line
+ while (peek_char(subj) == ' ') {
+ advance(subj);
+ }
+ if (nlpos > 1 &&
+ gh_buf_at(subj->buffer, nlpos - 1) == ' ' &&
+ gh_buf_at(subj->buffer, nlpos - 2) == ' ') {
+ return make_linebreak();
+ } else {
+ return make_softbreak();
+ }
}
inline static int not_eof(subject* subj)
{
- return !is_eof(subj);
+ return !is_eof(subj);
}
// Parse inlines while a predicate is satisfied. Return inlines.
extern inl* parse_inlines_while(subject* subj, int (*f)(subject*))
{
- inl* result = NULL;
- inl** last = &result;
- while ((*f)(subj) && parse_inline(subj, last)) {
- }
- return result;
+ inl* result = NULL;
+ inl** last = &result;
+ while ((*f)(subj) && parse_inline(subj, last)) {
+ }
+ return result;
+}
+
+inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
+{
+ inl *result;
+ subject subj;
+ gh_buf full_chunk = GH_BUF_INIT;
+
+ gh_buf_set(&full_chunk, chunk->data, chunk->len);
+ init_subject(&subj, &full_chunk, 0, refmap);
+ result = parse_inlines_while(&subj, not_eof);
+
+ gh_buf_free(&full_chunk);
+ return result;
+}
+
+static int find_special_char(subject *subj)
+{
+ int n = subj->pos + 1;
+ int size = (int)gh_buf_len(subj->buffer);
+
+ while (n < size) {
+ if (strchr("\n\\`&_*[]buffer, n)))
+ return n;
+ }
+
+ return -1;
}
// Parse an inline, advancing subject, and add it to last element.
// Adjust tail to point to new last element of list.
// Return 0 if no inline can be parsed, 1 otherwise.
-extern int parse_inline(subject* subj, inl ** last)
-{
- inl* new = NULL;
- bstring contents;
- bstring special_chars;
- unsigned char c;
- int endpos;
- c = peek_char(subj);
- if (c == 0) {
- return 0;
- }
- switch(c){
- case '\n':
- new = handle_newline(subj);
- break;
- case '`':
- new = handle_backticks(subj);
- break;
- case '\\':
- new = handle_backslash(subj);
- break;
- case '&':
- new = handle_entity(subj);
- break;
- case '<':
- new = handle_pointy_brace(subj);
- break;
- case '_':
- if (subj->pos > 0 && (isalnum(bchar(subj->buffer, subj->pos - 1)) ||
- bchar(subj->buffer, subj->pos - 1) == '_')) {
- new = make_str(take_one(subj));
- } else {
- new = handle_strong_emph(subj, '_');
- }
- break;
- case '*':
- new = handle_strong_emph(subj, '*');
- break;
- case '[':
- new = handle_left_bracket(subj);
- break;
- case '!':
- advance(subj);
- if (peek_char(subj) == '[') {
- new = handle_left_bracket(subj);
- if (new != NULL && new->tag == link) {
- new->tag = image;
- } else {
- new = append_inlines(make_str(bfromcstr("!")), new);
- }
- } else {
- new = make_str(bfromcstr("!"));
- }
- break;
- default:
- // we read until we hit a special character
- special_chars = bfromcstr("\n\\`&_*[]buffer, subj->pos, special_chars);
- bdestroy(special_chars);
- if (endpos == subj->pos) {
- // current char is special: read a 1-character str
- contents = take_one(subj);
- } else if (endpos == BSTR_ERR) {
- // special char not found, take whole rest of buffer:
- endpos = subj->buffer->slen;
- contents = bmidstr(subj->buffer, subj->pos, endpos - subj->pos);
- subj->pos = endpos;
- } else {
- // take buffer from subj->pos to endpos to str.
- contents = bmidstr(subj->buffer, subj->pos, endpos - subj->pos);
- subj->pos = endpos;
- // if we're at a newline, strip trailing spaces.
- if (peek_char(subj) == '\n') {
- brtrimws(contents);
- }
- }
- new = make_str(contents);
- }
- if (*last == NULL) {
- *last = new;
- } else {
- append_inlines(*last, new);
- }
- return 1;
-}
-
-extern inl* parse_inlines(bstring input, reference** refmap)
-{
- subject * subj = make_subject(input, refmap);
- inl * result = parse_inlines_while(subj, not_eof);
- free(subj);
- return result;
+static int parse_inline(subject* subj, inl ** last)
+{
+ inl* new = NULL;
+ chunk contents;
+ unsigned char c;
+ int endpos;
+ c = peek_char(subj);
+ if (c == 0) {
+ return 0;
+ }
+ switch(c){
+ case '\n':
+ new = handle_newline(subj);
+ break;
+ case '`':
+ new = handle_backticks(subj);
+ break;
+ case '\\':
+ new = handle_backslash(subj);
+ break;
+ case '&':
+ new = handle_entity(subj);
+ break;
+ case '<':
+ new = handle_pointy_brace(subj);
+ break;
+ case '_':
+ if (subj->pos > 0 && (isalnum(gh_buf_at(subj->buffer, subj->pos - 1)) ||
+ gh_buf_at(subj->buffer, subj->pos - 1) == '_')) {
+ goto text_literal;
+ }
+
+ new = handle_strong_emph(subj, '_');
+ break;
+ case '*':
+ new = handle_strong_emph(subj, '*');
+ break;
+ case '[':
+ new = handle_left_bracket(subj);
+ break;
+ case '!':
+ advance(subj);
+ if (peek_char(subj) == '[') {
+ new = handle_left_bracket(subj);
+ if (new != NULL && new->tag == link) {
+ new->tag = image;
+ } else {
+ new = append_inlines(make_str(chunk_literal("!")), new);
+ }
+ } else {
+ new = make_str(chunk_literal("!"));
+ }
+ break;
+ default:
+ text_literal:
+ endpos = find_special_char(subj);
+ if (endpos < 0) {
+ endpos = gh_buf_len(subj->buffer);
+ }
+
+ contents = chunk_buf(subj->buffer, subj->pos, endpos - subj->pos);
+ subj->pos = endpos;
+
+ // if we're at a newline, strip trailing spaces.
+ if (peek_char(subj) == '\n') {
+ chunk_trim(&contents);
+ }
+
+ new = make_str(contents);
+ }
+ if (*last == NULL) {
+ *last = new;
+ } else {
+ append_inlines(*last, new);
+ }
+ return 1;
+}
+
+extern inl* parse_inlines(gh_buf *input, int input_pos, reference** refmap)
+{
+ subject subj;
+ init_subject(&subj, input, input_pos, refmap);
+ return parse_inlines_while(&subj, not_eof);
}
// Parse zero or more space characters, including at most one newline.
void spnl(subject* subj)
{
- bool seen_newline = false;
- while (peek_char(subj) == ' ' ||
- (!seen_newline &&
- (seen_newline = peek_char(subj) == '\n'))) {
- advance(subj);
- }
+ bool seen_newline = false;
+ while (peek_char(subj) == ' ' ||
+ (!seen_newline &&
+ (seen_newline = peek_char(subj) == '\n'))) {
+ advance(subj);
+ }
}
// Parse reference. Assumes string begins with '[' character.
// Modify refmap if a reference is encountered.
// Return 0 if no reference found, otherwise position of subject
// after reference is parsed.
-extern int parse_reference(bstring input, reference** refmap)
-{
- subject * subj = make_subject(input, NULL);
- bstring lab = NULL;
- bstring url = NULL;
- bstring title = NULL;
- int matchlen = 0;
- int beforetitle;
- reference * new = NULL;
- int newpos;
-
- // parse label:
- if (!link_label(subj, &lab)) {
- free(subj);
- return 0;
- }
- // colon:
- if (peek_char(subj) == ':') {
- advance(subj);
- } else {
- free(subj);
- bdestroy(lab);
- return 0;
- }
- // parse link url:
- spnl(subj);
- matchlen = scan_link_url(subj->buffer, subj->pos);
- if (matchlen) {
- url = bmidstr(subj->buffer, subj->pos, matchlen);
- clean_url(url);
- subj->pos += matchlen;
- } else {
- free(subj);
- bdestroy(lab);
- bdestroy(url);
- return 0;
- }
- // parse optional link_title
- beforetitle = subj->pos;
- spnl(subj);
- matchlen = scan_link_title(subj->buffer, subj->pos);
- if (matchlen) {
- title = bmidstr(subj->buffer, subj->pos, matchlen);
- clean_title(title);
- subj->pos += matchlen;
- } else {
- subj->pos = beforetitle;
- title = bfromcstr("");
- }
- // parse final spaces and newline:
- while (peek_char(subj) == ' ') {
- advance(subj);
- }
- if (peek_char(subj) == '\n') {
- advance(subj);
- } else if (peek_char(subj) != 0) {
- free(subj);
- bdestroy(lab);
- bdestroy(url);
- bdestroy(title);
- return 0;
- }
- // insert reference into refmap
- new = make_reference(lab, url, title);
- add_reference(refmap, new);
-
- newpos = subj->pos;
- free(subj);
- bdestroy(lab);
- bdestroy(url);
- bdestroy(title);
- return newpos;
+extern int parse_reference(gh_buf *input, int input_pos, reference** refmap)
+{
+ subject subj;
+
+ chunk lab;
+ chunk url;
+ chunk title;
+
+ int matchlen = 0;
+ int beforetitle;
+ reference * new = NULL;
+
+ init_subject(&subj, input, input_pos, NULL);
+
+ // parse label:
+ if (!link_label(&subj, &lab))
+ return 0;
+
+ // colon:
+ if (peek_char(&subj) == ':') {
+ advance(&subj);
+ } else {
+ return 0;
+ }
+
+ // parse link url:
+ spnl(&subj);
+ matchlen = scan_link_url(subj.buffer, subj.pos);
+ if (matchlen) {
+ url = chunk_buf(subj.buffer, subj.pos, matchlen);
+ subj.pos += matchlen;
+ } else {
+ return 0;
+ }
+
+ // parse optional link_title
+ beforetitle = subj.pos;
+ spnl(&subj);
+ matchlen = scan_link_title(subj.buffer, subj.pos);
+ if (matchlen) {
+ title = chunk_buf(subj.buffer, subj.pos, matchlen);
+ subj.pos += matchlen;
+ } else {
+ subj.pos = beforetitle;
+ title = chunk_literal("");
+ }
+ // parse final spaces and newline:
+ while (peek_char(&subj) == ' ') {
+ advance(&subj);
+ }
+ if (peek_char(&subj) == '\n') {
+ advance(&subj);
+ } else if (peek_char(&subj) != 0) {
+ return 0;
+ }
+ // insert reference into refmap
+ new = make_reference(&lab, &url, &title);
+ add_reference(refmap, new);
+
+ return subj.pos;
}
diff --git a/src/main.c b/src/main.c
index f0ecb82..9e0a3c8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
print_blocks(cur, 0);
} else {
check(blocks_to_html(cur, &html, false) == 0, "could not format as HTML");
- printf("%s", html->data);
+ // printf("%s", html->data);
bdestroy(html);
}
free_blocks(cur);
diff --git a/src/scanners.h b/src/scanners.h
index 71e0520..b6e586b 100644
--- a/src/scanners.h
+++ b/src/scanners.h
@@ -1,15 +1,15 @@
-#include "bstrlib.h"
+#include "buffer.h"
-int scan_autolink_uri(bstring s, int pos);
-int scan_autolink_email(bstring s, int pos);
-int scan_html_tag(bstring s, int pos);
-int scan_html_block_tag(bstring s, int pos);
-int scan_link_url(bstring s, int pos);
-int scan_link_title(bstring s, int pos);
-int scan_spacechars(bstring s, int pos);
-int scan_atx_header_start(bstring s, int pos);
-int scan_setext_header_line(bstring s, int pos);
-int scan_hrule(bstring s, int pos);
-int scan_open_code_fence(bstring s, int pos);
-int scan_close_code_fence(bstring s, int pos, int len);
-int scan_entity(bstring s, int pos);
+int scan_autolink_uri(const gh_buf *s, int pos);
+int scan_autolink_email(const gh_buf *s, int pos);
+int scan_html_tag(const gh_buf *s, int pos);
+int scan_html_block_tag(const gh_buf *s, int pos);
+int scan_link_url(const gh_buf *s, int pos);
+int scan_link_title(const gh_buf *s, int pos);
+int scan_spacechars(const gh_buf *s, int pos);
+int scan_atx_header_start(const gh_buf *s, int pos);
+int scan_setext_header_line(const gh_buf *s, int pos);
+int scan_hrule(const gh_buf *s, int pos);
+int scan_open_code_fence(const gh_buf *s, int pos);
+int scan_close_code_fence(const gh_buf *s, int pos, int len);
+int scan_entity(const gh_buf *s, int pos);
diff --git a/src/scanners.re b/src/scanners.re
index 305d1ea..7323ef9 100644
--- a/src/scanners.re
+++ b/src/scanners.re
@@ -1,4 +1,4 @@
-#include "bstrlib.h"
+#include "buffer.h"
/*!re2c
re2c:define:YYCTYPE = "unsigned char";
@@ -55,10 +55,10 @@
*/
// Try to match URI autolink after first <, returning number of chars matched.
-extern int scan_autolink_uri(bstring s, int pos)
+extern int scan_autolink_uri(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
scheme [:]([^\x00-\x20<>\\]|escaped_char)*[>] { return (p - start); }
@@ -67,10 +67,10 @@ extern int scan_autolink_uri(bstring s, int pos)
}
// Try to match email autolink after first <, returning num of chars matched.
-extern int scan_autolink_email(bstring s, int pos)
+extern int scan_autolink_email(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+
@@ -83,10 +83,10 @@ extern int scan_autolink_email(bstring s, int pos)
}
// Try to match an HTML tag after first <, returning num of chars matched.
-extern int scan_html_tag(bstring s, int pos)
+extern int scan_html_tag(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
htmltag { return (p - start); }
@@ -96,10 +96,10 @@ extern int scan_html_tag(bstring s, int pos)
// Try to match an HTML block tag including first <,
// returning num of chars matched.
-extern int scan_html_block_tag(bstring s, int pos)
+extern int scan_html_block_tag(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[<] [/] blocktagname (spacechar | [>]) { return (p - start); }
@@ -113,10 +113,10 @@ extern int scan_html_block_tag(bstring s, int pos)
// This may optionally be contained in <..>; otherwise
// whitespace and unbalanced right parentheses aren't allowed.
// Newlines aren't ever allowed.
-extern int scan_link_url(bstring s, int pos)
+extern int scan_link_url(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[ \n]* [<] ([^<>\n\\\x00] | escaped_char | [\\])* [>] { return (p - start); }
@@ -128,10 +128,10 @@ extern int scan_link_url(bstring s, int pos)
// Try to match a link title (in single quotes, in double quotes, or
// in parentheses), returning number of chars matched. Allow one
// level of internal nesting (quotes within quotes).
-extern int scan_link_title(bstring s, int pos)
+extern int scan_link_title(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
["] (escaped_char|[^"\x00])* ["] { return (p - start); }
@@ -142,9 +142,9 @@ extern int scan_link_title(bstring s, int pos)
}
// Match space characters, including newlines.
-extern int scan_spacechars(bstring s, int pos)
+extern int scan_spacechars(const gh_buf *s, int pos)
{
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[ \t\n]* { return (p - start); }
@@ -153,10 +153,10 @@ extern int scan_spacechars(bstring s, int pos)
}
// Match ATX header start.
-extern int scan_atx_header_start(bstring s, int pos)
+extern int scan_atx_header_start(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[#]{1,6} ([ ]+|[\n]) { return (p - start); }
@@ -166,10 +166,10 @@ extern int scan_atx_header_start(bstring s, int pos)
// Match sexext header line. Return 1 for level-1 header,
// 2 for level-2, 0 for no match.
-extern int scan_setext_header_line(bstring s, int pos)
+extern int scan_setext_header_line(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
/*!re2c
[=]+ [ ]* [\n] { return 1; }
[-]+ [ ]* [\n] { return 2; }
@@ -180,10 +180,10 @@ extern int scan_setext_header_line(bstring s, int pos)
// Scan a horizontal rule line: "...three or more hyphens, asterisks,
// or underscores on a line by themselves. If you wish, you may use
// spaces between the hyphens or asterisks."
-extern int scan_hrule(bstring s, int pos)
+extern int scan_hrule(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
([*][ ]*){3,} [ \t]* [\n] { return (p - start); }
@@ -194,10 +194,10 @@ extern int scan_hrule(bstring s, int pos)
}
// Scan an opening code fence.
-extern int scan_open_code_fence(bstring s, int pos)
+extern int scan_open_code_fence(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[`]{3,} / [^`\n\x00]*[\n] { return (p - start); }
@@ -207,10 +207,10 @@ extern int scan_open_code_fence(bstring s, int pos)
}
// Scan a closing code fence with length at least len.
-extern int scan_close_code_fence(bstring s, int pos, int len)
+extern int scan_close_code_fence(const gh_buf *s, int pos, int len)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
([`]{3,} | [~]{3,}) / spacechar* [\n]
@@ -225,10 +225,10 @@ extern int scan_close_code_fence(bstring s, int pos, int len)
// Scans an entity.
// Returns number of chars matched.
-extern int scan_entity(bstring s, int pos)
+extern int scan_entity(const gh_buf *s, int pos)
{
unsigned char * marker = NULL;
- unsigned char * p = &(s->data[pos]);
+ unsigned char * p = &(s->ptr[pos]);
unsigned char * start = p;
/*!re2c
[&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]
diff --git a/src/stmd.h b/src/stmd.h
index 5e34399..eb1b989 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -1,38 +1,38 @@
#include
-#include "bstrlib.h"
+#include "buffer.h"
#include "uthash.h"
#define VERSION "0.1"
#define CODE_INDENT 4
+typedef struct {
+ const unsigned char *data;
+ int len;
+ int alloc;
+} chunk;
+
typedef struct Inline {
- enum { str, softbreak, linebreak, code, raw_html, entity,
- emph, strong, link, image } tag;
- union {
- bstring literal;
- struct Inline* inlines;
- struct { struct Inline* label;
- bstring url;
- bstring title;
- } linkable;
- } content;
- struct Inline* next;
+ enum { str, softbreak, linebreak, code, raw_html, entity,
+ emph, strong, link, image } tag;
+ union {
+ chunk literal;
+ struct Inline *inlines;
+ struct {
+ struct Inline *label;
+ unsigned char *url;
+ unsigned char *title;
+ } linkable;
+ } content;
+ struct Inline *next;
} inl;
typedef struct Reference {
- bstring label;
- bstring url;
- bstring title;
+ unsigned char *label;
+ unsigned char *url;
+ unsigned char *title;
UT_hash_handle hh; // used by uthash
} reference;
-typedef struct Subject {
- bstring buffer;
- int pos;
- reference** reference_map;
- int label_nestlevel;
-} subject;
-
// Types for blocks
struct ListData {
@@ -51,7 +51,7 @@ struct FencedCodeData {
int fence_length;
int fence_offset;
char fence_char;
- bstring info;
+ gh_buf info;
};
typedef struct Block {
@@ -77,7 +77,8 @@ typedef struct Block {
struct Block* last_child;
struct Block* parent;
struct Block* top;
- bstring string_content;
+ gh_buf string_content;
+ int string_pos;
inl* inline_content;
union {
struct ListData list_data;
@@ -89,33 +90,34 @@ typedef struct Block {
struct Block * prev;
} block;
-int parse_inline(subject* subj, inl ** last);
-inl* parse_inlines(bstring input, reference** refmap);
-inl* parse_inlines_while(subject* subj, int (*f)(subject*));
+inl* parse_inlines(gh_buf *input, int input_pos, reference** refmap);
void free_inlines(inl* e);
-int parse_reference(bstring input, reference** refmap);
+
+int parse_reference(gh_buf *input, int input_pos, reference** refmap);
void free_reference(reference *ref);
void free_reference_map(reference **refmap);
-reference* make_reference(bstring label, bstring url, bstring title);
-reference* lookup_reference(reference** refmap, bstring label);
+
void add_reference(reference** refmap, reference* ref);
-int unescape(bstring s);
+void unescape_buffer(gh_buf *buf);
extern block* make_document();
extern block* add_child(block* parent,
int block_type, int start_line, int start_column);
void free_blocks(block* e);
+block *stmd_parse_document(const char *buffer, size_t len);
+
// FOR NOW:
-int process_inlines(block* cur, reference** refmap);
-int incorporate_line(bstring ln, int line_number, block** curptr);
-int finalize(block* b, int line_number);
+void process_inlines(block* cur, reference** refmap);
+void incorporate_line(gh_buf *ln, int line_number, block** curptr);
+void finalize(block* b, int line_number);
void print_inlines(inl* ils, int indent);
void print_blocks(block* blk, int indent);
-int blocks_to_html(block* b, bstring* result, bool tight);
-int inlines_to_html(inl* b, bstring* result);
+/* TODO */
+// int blocks_to_html(block* b, bstring* result, bool tight);
+// int inlines_to_html(inl* b, bstring* result);
-int bdetab(bstring s, int utf8);
+void utf8proc_case_fold(gh_buf *dest, const unsigned char *str, int len);
diff --git a/src/utf8.c b/src/utf8.c
index 4bb3b35..1a5df9e 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -2,105 +2,142 @@
#include "bstrlib.h"
#include "debug.h"
-#define advance(s) \
- s++; \
- check(*s >> 6 == 0x02, "UTF-8 decode error on byte %x", *s);
-
-// Reads a unicode code point from a UTF8-encoded string, and
-// puts it in the pointer n. If something illegal
-// is encountered, 0xFFFD is emitted.
-// Returns a pointer to next position in string, or NULL if no
-// more characters remain.
-extern unsigned char * from_utf8(unsigned char * s, unsigned int *n)
+static const int8_t utf8proc_utf8class[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len)
{
- int x = 0;
-
- if (*s == 0) {
- return NULL;
- } else if (*s < 0x80) {
- x = *s;
- } else if (*s >> 5 == 0x06) {
- x = *s & 0x1F;
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- } else if (*s >> 4 == 0x0E) {
- x = *s & 0x0F;
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- } else if (*s >> 3 == 0x1E) {
- x = *s & 0x07;
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- } else if (*s >> 2 == 0x3E) {
- x = *s & 0x03;
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- advance(s);
- x = (x << 6) + (*s & 0x3F);
- } else {
- log_err("UTF-8 decode error on byte %x", *s);
- goto error;
- }
- *n = x;
- s++;
- return s;
- error:
- *n = 0xFFFD;
- return s;
+ ssize_t length, i;
+
+ if (!str_len)
+ return 0;
+
+ length = utf8proc_utf8class[str[0]];
+
+ if (!length)
+ return -1;
+
+ if (str_len >= 0 && length > str_len)
+ return -1;
+
+ for (i = 1; i < length; i++) {
+ if ((str[i] & 0xC0) != 0x80)
+ return -1;
+ }
+
+ return length;
+}
+
+ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst)
+{
+ ssize_t length;
+ int32_t uc = -1;
+
+ *dst = -1;
+ length = utf8proc_charlen(str, str_len);
+ if (length < 0)
+ return -1;
+
+ switch (length) {
+ case 1:
+ uc = str[0];
+ break;
+ case 2:
+ uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F);
+ if (uc < 0x80) uc = -1;
+ break;
+ case 3:
+ uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6)
+ + (str[2] & 0x3F);
+ if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) ||
+ (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1;
+ break;
+ case 4:
+ uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12)
+ + ((str[2] & 0x3F) << 6) + (str[3] & 0x3F);
+ if (uc < 0x10000 || uc >= 0x110000) uc = -1;
+ break;
+ }
+
+ if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE))
+ return -1;
+
+ *dst = uc;
+ return length;
}
-// Converts the unicode code point c to UTF-8,
-// putting the result in dest. Returns 0 on success, -1 on error.
-extern int to_utf8(unsigned int c, bstring dest)
+void utf8_encode_char(int32_t uc, gh_buf *buf)
{
- if (c < 0x80) {
- bconchar(dest, c);
- } else if (c < 0x800) {
- bconchar(dest, 192 + c/64);
- bconchar(dest, 128 + c%64);
- } else if (c - 0xd800u < 0x800) {
- goto error;
- } else if (c < 0x10000) {
- bconchar(dest, 224 + c / 4096);
- bconchar(dest, 128 + c /64%64);
- bconchar(dest, 128 + c%64);
- } else if (c < 0x110000) {
- bconchar(dest, 240 + c/262144);
- bconchar(dest, 128 + c/4096%64);
- bconchar(dest, 128 + c/64%64);
- bconchar(dest, 128 + c%64);
- } else {
- goto error;
- }
- return 0;
-error:
- return -1;
+ char dst[4];
+ int len = 0;
+
+ if (uc < 0x00) {
+ assert(false);
+ } else if (uc < 0x80) {
+ dst[0] = uc;
+ len = 1;
+ } else if (uc < 0x800) {
+ dst[0] = 0xC0 + (uc >> 6);
+ dst[1] = 0x80 + (uc & 0x3F);
+ len = 2;
+ } else if (uc == 0xFFFF) {
+ dst[0] = 0xFF;
+ return 1;
+ } else if (uc == 0xFFFE) {
+ dst[0] = 0xFE;
+ len = 1;
+ } else if (uc < 0x10000) {
+ dst[0] = 0xE0 + (uc >> 12);
+ dst[1] = 0x80 + ((uc >> 6) & 0x3F);
+ dst[2] = 0x80 + (uc & 0x3F);
+ len = 3;
+ } else if (uc < 0x110000) {
+ dst[0] = 0xF0 + (uc >> 18);
+ dst[1] = 0x80 + ((uc >> 12) & 0x3F);
+ dst[2] = 0x80 + ((uc >> 6) & 0x3F);
+ dst[3] = 0x80 + (uc & 0x3F);
+ len = 4;
+ } else {
+ assert(false);
+ }
+
+ gh_buf_put(buf, dst, len);
}
+void utf8proc_case_fold(gh_buf *dest, const unsigned char *str, int len)
+{
+ int32_t c;
+
#define bufpush(x) \
- check(to_utf8(x, buf) == 0, "UTF-8 encode error on code point %04x", x)
+ utf8proc_encode_char(x, dest)
-// Returns the case-folded version of the source string, or NULL on error.
-extern bstring case_fold(bstring source)
-{
- unsigned char * s = source->data;
- unsigned int c = 0;
- bstring buf = bfromcstr("");
- while ((s = from_utf8(s, &c))) {
-#include "case_fold_switch.c"
- }
- return buf;
-error:
- return NULL;
+ while (len > 0) {
+ ssize_t char_len = utf8proc_iterate(str, len, &c);
+
+ if (char_len < 0) {
+ bufpush(0xFFFD);
+ continue;
+ }
+
+#include "case_fold_switch.inc"
+
+ str += char_len;
+ len -= char_len;
+ }
}
--
cgit v1.2.3
From 582674e662d1f8757350c51486a5e0a837195e15 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 2 Sep 2014 13:18:04 +0200
Subject: ffffix
---
Makefile | 11 ++-
src/blocks.c | 58 +++++++----
src/buffer.c | 69 +++++--------
src/buffer.h | 19 ++--
src/html.c | 276 ----------------------------------------------------
src/inlines.c | 4 +-
src/main.c | 142 ++++++++++++---------------
src/print.c | 307 ++++++++++++++++++++++++++++++----------------------------
src/stmd.h | 13 +--
src/utf8.c | 6 +-
src/utf8.h | 6 --
11 files changed, 304 insertions(+), 607 deletions(-)
delete mode 100644 src/html.c
delete mode 100644 src/utf8.h
diff --git a/Makefile b/Makefile
index cb5938d..d14a928 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ DATADIR=data
PROG=./stmd
.PHONY: all oldtests test spec benchjs testjs
-all: $(SRCDIR)/case_fold_switch.c $(PROG)
+all: $(SRCDIR)/case_fold_switch.inc $(PROG)
README.html: README.md template.html
pandoc --template template.html -S -s -t html5 -o $@ $<
@@ -41,13 +41,16 @@ testjs: spec.txt
benchjs:
node js/bench.js ${BENCHINP}
-$(PROG): $(SRCDIR)/main.c $(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/html.o $(SRCDIR)/utf8.o
+HTML_OBJ=$(SRCDIR)/html/html.o $(SRCDIR)/html/houdini_href_e.o $(SRCDIR)/html/houdini_html_e.o
+STMD_OBJ=$(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/utf8.o
+
+$(PROG): $(SRCDIR)/main.c $(HTML_OBJ) $(STMD_OBJ)
$(CC) $(LDFLAGS) -o $@ $^
$(SRCDIR)/scanners.c: $(SRCDIR)/scanners.re
re2c --case-insensitive -bis $< > $@ || (rm $@ && false)
-$(SRCDIR)/case_fold_switch.inc $(DATADIR)/CaseFolding-3.2.0.txt
+$(SRCDIR)/case_fold_switch.inc: $(DATADIR)/CaseFolding-3.2.0.txt
perl mkcasefold.pl < $< > $@
.PHONY: leakcheck clean fuzztest dingus upload
@@ -72,7 +75,7 @@ update-site: spec.html narrative.html
(cd _site ; git pull ; git commit -a -m "Updated site for latest spec, narrative, js" ; git push; cd ..)
clean:
- -rm -f test $(SRCDIR)/*.o $(SRCDIR)/scanners.c
+ -rm -f test $(SRCDIR)/*.o $(SRCDIR)/scanners.c $(SRCDIR)/html/*.o
-rm -rf *.dSYM
-rm -f README.html
-rm -f spec.md fuzz.txt spec.html
diff --git a/src/blocks.c b/src/blocks.c
index eabac03..71dc830 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -3,11 +3,12 @@
#include
#include
#include
-#include "bstrlib.h"
+
#include "stmd.h"
-#include "uthash.h"
-#include "debug.h"
#include "scanners.h"
+#include "uthash.h"
+
+static void finalize(block* b, int line_number);
static block* make_block(int tag, int start_line, int start_column)
{
@@ -140,7 +141,7 @@ static int break_out_of_lists(block ** bptr, int line_number)
}
-extern void finalize(block* b, int line_number)
+static void finalize(block* b, int line_number)
{
int firstlinelen;
int pos;
@@ -364,7 +365,7 @@ static int lists_match(struct ListData list_data,
list_data.bullet_char == item_data.bullet_char);
}
-static void expand_tabs(gh_buf *ob, const char *line, size_t size)
+static void expand_tabs(gh_buf *ob, const unsigned char *line, size_t size)
{
size_t i = 0, tab = 0;
@@ -389,13 +390,43 @@ static void expand_tabs(gh_buf *ob, const char *line, size_t size)
}
}
-extern block *stmd_parse_document(const char *buffer, size_t len)
+static block *finalize_parsing(block *document, int linenum)
{
- gh_buf line = GH_BUF_INIT;
+ while (document != document->top) {
+ finalize(document, linenum);
+ document = document->parent;
+ }
+
+ finalize(document, linenum);
+ process_inlines(document, document->attributes.refmap);
+
+ return document;
+}
+extern block *stmd_parse_file(FILE *f)
+{
+ gh_buf line = GH_BUF_INIT;
+ unsigned char buffer[4096];
+ int linenum = 1;
block *document = make_document();
+
+ while (fgets((char *)buffer, sizeof(buffer), f)) {
+ expand_tabs(&line, buffer, strlen(buffer));
+ incorporate_line(&line, linenum, &document);
+ gh_buf_clear(&line);
+ linenum++;
+ }
+
+ gh_buf_free(&line);
+ return finalize_document(document, linenum);
+}
+
+extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
+{
+ gh_buf line = GH_BUF_INIT;
int linenum = 1;
- const char *end = buffer + len;
+ const unsigned char *end = buffer + len;
+ block *document = make_document();
while (buffer < end) {
const char *eol = memchr(buffer, '\n', end - buffer);
@@ -414,16 +445,7 @@ extern block *stmd_parse_document(const char *buffer, size_t len)
}
gh_buf_free(&line);
-
- while (document != document->top) {
- finalize(document, linenum);
- document = document->parent;
- }
-
- finalize(document, linenum);
- process_inlines(document, document->attributes.refmap);
-
- return document;
+ return finalize_document(document, linenum);
}
// Process one line at a time, modifying a block.
diff --git a/src/buffer.c b/src/buffer.c
index b81e7fa..17dc864 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -31,10 +31,10 @@ void gh_buf_init(gh_buf *buf, int initial_size)
int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom)
{
- char *new_ptr;
- size_t new_size;
+ unsigned char *new_ptr;
+ int new_size;
- if (buf->ptr == gh_buf__oom || buf->asize < 0)
+ if (buf->ptr == gh_buf__oom)
return -1;
if (target_size <= buf->asize)
@@ -79,7 +79,7 @@ void gh_buf_free(gh_buf *buf)
{
if (!buf) return;
- if (buf->asize > 0 && buf->ptr != gh_buf__initbuf && buf->ptr != gh_buf__oom)
+ if (buf->ptr != gh_buf__initbuf && buf->ptr != gh_buf__oom)
free(buf->ptr);
gh_buf_init(buf, 0);
@@ -91,14 +91,9 @@ void gh_buf_clear(gh_buf *buf)
if (buf->asize > 0)
buf->ptr[0] = '\0';
-
- if (buf->asize < 0) {
- buf->ptr = gh_buf__initbuf;
- buf->asize = 0;
- }
}
-int gh_buf_set(gh_buf *buf, const char *data, int len)
+int gh_buf_set(gh_buf *buf, const unsigned char *data, int len)
{
if (len == 0 || data == NULL) {
gh_buf_clear(buf);
@@ -115,10 +110,12 @@ int gh_buf_set(gh_buf *buf, const char *data, int len)
int gh_buf_sets(gh_buf *buf, const char *string)
{
- return gh_buf_set(buf, string, string ? strlen(string) : 0);
+ return gh_buf_set(buf,
+ (const unsigned char *)string,
+ string ? strlen(string) : 0);
}
-int gh_buf_putc(gh_buf *buf, char c)
+int gh_buf_putc(gh_buf *buf, int c)
{
ENSURE_SIZE(buf, buf->size + 2);
buf->ptr[buf->size++] = c;
@@ -126,7 +123,7 @@ int gh_buf_putc(gh_buf *buf, char c)
return 0;
}
-int gh_buf_put(gh_buf *buf, const char *data, int len)
+int gh_buf_put(gh_buf *buf, const unsigned char *data, int len)
{
ENSURE_SIZE(buf, buf->size + len + 1);
memmove(buf->ptr + buf->size, data, len);
@@ -137,8 +134,7 @@ int gh_buf_put(gh_buf *buf, const char *data, int len)
int gh_buf_puts(gh_buf *buf, const char *string)
{
- assert(string);
- return gh_buf_put(buf, string, strlen(string));
+ return gh_buf_put(buf, (const unsigned char *)string, strlen(string));
}
int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap)
@@ -153,7 +149,7 @@ int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap)
va_copy(args, ap);
len = vsnprintf(
- buf->ptr + buf->size,
+ (char *)buf->ptr + buf->size,
buf->asize - buf->size,
format, args
);
@@ -187,9 +183,9 @@ int gh_buf_printf(gh_buf *buf, const char *format, ...)
return r;
}
-void gh_buf_copy_cstr(char *data, size_t datasize, const gh_buf *buf)
+void gh_buf_copy_cstr(char *data, int datasize, const gh_buf *buf)
{
- size_t copylen;
+ int copylen;
assert(data && datasize && buf);
@@ -212,9 +208,9 @@ void gh_buf_swap(gh_buf *buf_a, gh_buf *buf_b)
*buf_b = t;
}
-char *gh_buf_detach(gh_buf *buf)
+unsigned char *gh_buf_detach(gh_buf *buf)
{
- char *data = buf->ptr;
+ unsigned char *data = buf->ptr;
if (buf->asize == 0 || buf->ptr == gh_buf__oom)
return NULL;
@@ -224,13 +220,13 @@ char *gh_buf_detach(gh_buf *buf)
return data;
}
-void gh_buf_attach(gh_buf *buf, char *ptr, int asize)
+void gh_buf_attach(gh_buf *buf, unsigned char *ptr, int asize)
{
gh_buf_free(buf);
if (ptr) {
buf->ptr = ptr;
- buf->size = strlen(ptr);
+ buf->size = strlen((char *)ptr);
if (asize)
buf->asize = (asize < buf->size) ? buf->size + 1 : asize;
else /* pass 0 to fall back on strlen + 1 */
@@ -249,11 +245,11 @@ int gh_buf_cmp(const gh_buf *a, const gh_buf *b)
int gh_buf_strchr(const gh_buf *buf, int c, int pos)
{
- const char *p = memchr(buf->ptr + pos, c, buf->size - pos);
- if (!p)
- return -1;
+ const char *p = memchr(buf->ptr + pos, c, buf->size - pos);
+ if (!p)
+ return -1;
- return (int)(p - p->ptr);
+ return (int)(p - buf->ptr);
}
int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
@@ -270,36 +266,21 @@ int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
void gh_buf_truncate(gh_buf *buf, size_t len)
{
- assert(buf->asize >= 0);
-
if (len < buf->size) {
buf->size = len;
buf->ptr[buf->size] = '\0';
}
}
-void gh_buf_ltruncate(gh_buf *buf, size_t len)
-{
- assert(buf->asize >= 0);
-
- if (len && len < buf->size) {
- memmove(buf->ptr, buf->ptr + len, buf->size - len);
- buf->size -= len;
- buf->ptr[buf->size] = '\0';
- }
-}
-
void gh_buf_trim(gh_buf *buf)
{
- size_t i = 0;
-
- assert(buf->asize >= 0);
-
- /* ltrim */
+ /* TODO: leading whitespace? */
+ /*
while (i < buf->size && isspace(buf->ptr[i]))
i++;
gh_buf_truncate(buf, i);
+ */
/* rtrim */
while (buf->size > 0) {
diff --git a/src/buffer.h b/src/buffer.h
index 2581ee3..422ef02 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -24,13 +24,6 @@ extern unsigned char gh_buf__oom[];
*/
extern void gh_buf_init(gh_buf *buf, int initial_size);
-static inline void gh_buf_static(gh_buf *buf, unsigned char *source)
-{
- buf->ptr = source;
- buf->size = strlen(source);
- buf->asize = -1;
-}
-
/**
* Attempt to grow the buffer to hold at least `target_size` bytes.
*
@@ -81,13 +74,13 @@ static inline size_t gh_buf_len(const gh_buf *buf)
extern int gh_buf_cmp(const gh_buf *a, const gh_buf *b);
-extern void gh_buf_attach(gh_buf *buf, char *ptr, int asize);
-extern char *gh_buf_detach(gh_buf *buf);
+extern void gh_buf_attach(gh_buf *buf, unsigned char *ptr, int asize);
+extern unsigned char *gh_buf_detach(gh_buf *buf);
extern void gh_buf_copy_cstr(char *data, int datasize, const gh_buf *buf);
static inline const char *gh_buf_cstr(const gh_buf *buf)
{
- return buf->ptr;
+ return (char *)buf->ptr;
}
#define gh_buf_at(buf, n) ((buf)->ptr[n])
@@ -100,10 +93,10 @@ static inline const char *gh_buf_cstr(const gh_buf *buf)
* return code of these functions and call them in a series then just call
* gh_buf_oom at the end.
*/
-extern int gh_buf_set(gh_buf *buf, const char *data, int len);
+extern int gh_buf_set(gh_buf *buf, const unsigned char *data, int len);
extern int gh_buf_sets(gh_buf *buf, const char *string);
-extern int gh_buf_putc(gh_buf *buf, char c);
-extern int gh_buf_put(gh_buf *buf, const char *data, int len);
+extern int gh_buf_putc(gh_buf *buf, int c);
+extern int gh_buf_put(gh_buf *buf, const unsigned char *data, int len);
extern int gh_buf_puts(gh_buf *buf, const char *string);
extern int gh_buf_printf(gh_buf *buf, const char *format, ...)
__attribute__((format (printf, 2, 3)));
diff --git a/src/html.c b/src/html.c
deleted file mode 100644
index aeec5f1..0000000
--- a/src/html.c
+++ /dev/null
@@ -1,276 +0,0 @@
-#include
-#include
-#include
-#include "bstrlib.h"
-#include "stmd.h"
-#include "debug.h"
-#include "scanners.h"
-
-// Functions to convert block and inline lists to HTML strings.
-
-// Escape special characters in HTML. More efficient than
-// three calls to bfindreplace. If preserve_entities is set,
-// existing entities are left alone.
-static bstring escape_html(bstring inp, bool preserve_entities)
-{
- int pos = 0;
- int match;
- char c;
- bstring escapable = blk2bstr("&<>\"", 4);
- bstring ent;
- bstring s = bstrcpy(inp);
- while ((pos = binchr(s, pos, escapable)) != BSTR_ERR) {
- c = bchar(s,pos);
- switch (c) {
- case '<':
- bdelete(s, pos, 1);
- ent = blk2bstr("<", 4);
- binsert(s, pos, ent, ' ');
- bdestroy(ent);
- pos += 4;
- break;
- case '>':
- bdelete(s, pos, 1);
- ent = blk2bstr(">", 4);
- binsert(s, pos, ent, ' ');
- bdestroy(ent);
- pos += 4;
- break;
- case '&':
- if (preserve_entities && (match = scan_entity(s, pos))) {
- pos += match;
- } else {
- bdelete(s, pos, 1);
- ent = blk2bstr("&", 5);
- binsert(s, pos, ent, ' ');
- bdestroy(ent);
- pos += 5;
- }
- break;
- case '"':
- bdelete(s, pos, 1);
- ent = blk2bstr(""", 6);
- binsert(s, pos, ent, ' ');
- bdestroy(ent);
- pos += 6;
- break;
- default:
- bdelete(s, pos, 1);
- log_err("unexpected character %02x", c);
- }
- }
- bdestroy(escapable);
- return s;
-}
-
-static inline void cr(bstring buffer)
-{
- int c = bchar(buffer, blength(buffer) - 1);
- if (c != '\n' && c) {
- bconchar(buffer, '\n');
- }
-}
-
-// Convert a block list to HTML. Returns 0 on success, and sets result.
-extern int blocks_to_html(block* b, bstring* result, bool tight)
-{
- bstring contents = NULL;
- bstring escaped, escaped2;
- struct bstrList * info_words;
- struct ListData * data;
- bstring mbstart;
- bstring html = blk2bstr("", 0);
-
- while(b != NULL) {
- switch(b->tag) {
- case document:
- check(blocks_to_html(b->children, &contents, false) == 0,
- "error converting blocks to html");
- bformata(html, "%s", contents->data);
- bdestroy(contents);
- break;
- case paragraph:
- check(inlines_to_html(b->inline_content, &contents) == 0,
- "error converting inlines to html");
- if (tight) {
- bformata(html, "%s", contents->data);
- } else {
- cr(html);
- bformata(html, "%s
", contents->data);
- cr(html);
- }
- bdestroy(contents);
- break;
- case block_quote:
- check(blocks_to_html(b->children, &contents, false) == 0,
- "error converting blocks to html");
- cr(html);
- bformata(html, "\n%s
", contents->data);
- cr(html);
- bdestroy(contents);
- break;
- case list_item:
- check(blocks_to_html(b->children, &contents, tight) == 0,
- "error converting blocks to html");
- brtrimws(contents);
- cr(html);
- bformata(html, "%s", contents->data);
- cr(html);
- bdestroy(contents);
- break;
- case list:
- // make sure a list starts at the beginning of the line:
- cr(html);
- data = &(b->attributes.list_data);
- check(blocks_to_html(b->children, &contents, data->tight) == 0,
- "error converting blocks to html");
- mbstart = bformat(" start=\"%d\"", data->start);
- bformata(html, "<%s%s>\n%s%s>",
- data->list_type == bullet ? "ul" : "ol",
- data->start == 1 ? "" : (char*) mbstart->data,
- contents->data,
- data->list_type == bullet ? "ul" : "ol");
- cr(html);
- bdestroy(contents);
- bdestroy(mbstart);
- break;
- case atx_header:
- case setext_header:
- check(inlines_to_html(b->inline_content, &contents) == 0,
- "error converting inlines to html");
- cr(html);
- bformata(html, "%s",
- b->attributes.header_level,
- contents->data,
- b->attributes.header_level);
- cr(html);
- bdestroy(contents);
- break;
- case indented_code:
- escaped = escape_html(b->string_content, false);
- cr(html);
- bformata(html, "%s
", escaped->data);
- cr(html);
- bdestroy(escaped);
- break;
- case fenced_code:
- escaped = escape_html(b->string_content, false);
- cr(html);
- bformata(html, "attributes.fenced_code_data.info) > 0) {
- escaped2 = escape_html(b->attributes.fenced_code_data.info, true);
- info_words = bsplit(escaped2, ' ');
- bformata(html, " class=\"language-%s\"", info_words->entry[0]->data);
- bdestroy(escaped2);
- bstrListDestroy(info_words);
- }
- bformata(html, ">%s
", escaped->data);
- cr(html);
- bdestroy(escaped);
- break;
- case html_block:
- bformata(html, "%s", b->string_content->data);
- break;
- case hrule:
- bformata(html, "
");
- cr(html);
- break;
- case reference_def:
- break;
- default:
- log_warn("block type %d not implemented\n", b->tag);
- break;
- }
- b = b->next;
- }
- *result = html;
- return 0;
- error:
- return -1;
-}
-
-// Convert an inline list to HTML. Returns 0 on success, and sets result.
-extern int inlines_to_html(inl* ils, bstring* result)
-{
- bstring contents = NULL;
- bstring html = blk2bstr("", 0);
- bstring mbtitle, escaped, escaped2;
-
- while(ils != NULL) {
- switch(ils->tag) {
- case str:
- escaped = escape_html(ils->content.literal, false);
- bformata(html, "%s", escaped->data);
- bdestroy(escaped);
- break;
- case linebreak:
- bformata(html, "
\n");
- break;
- case softbreak:
- bformata(html, "\n");
- break;
- case code:
- escaped = escape_html(ils->content.literal, false);
- bformata(html, "%s
", escaped->data);
- bdestroy(escaped);
- break;
- case raw_html:
- case entity:
- bformata(html, "%s", ils->content.literal->data);
- break;
- case link:
- check(inlines_to_html(ils->content.inlines, &contents) == 0,
- "error converting inlines to html");
- if (blength(ils->content.linkable.title) > 0) {
- escaped = escape_html(ils->content.linkable.title, true);
- mbtitle = bformat(" title=\"%s\"", escaped->data);
- bdestroy(escaped);
- } else {
- mbtitle = blk2bstr("",0);
- }
- escaped = escape_html(ils->content.linkable.url, true);
- bformata(html, "%s",
- escaped->data,
- mbtitle->data,
- contents->data);
- bdestroy(escaped);
- bdestroy(mbtitle);
- bdestroy(contents);
- break;
- case image:
- check(inlines_to_html(ils->content.inlines, &contents) == 0,
- "error converting inlines to html");
- escaped = escape_html(ils->content.linkable.url, true);
- escaped2 = escape_html(contents, false);
- bdestroy(contents);
- bformata(html, "data, escaped2->data);
- bdestroy(escaped);
- bdestroy(escaped2);
- if (blength(ils->content.linkable.title) > 0) {
- escaped = escape_html(ils->content.linkable.title, true);
- bformata(html, " title=\"%s\"", escaped->data);
- bdestroy(escaped);
- }
- bformata(html, " />");
- break;
- case strong:
- check(inlines_to_html(ils->content.inlines, &contents) == 0,
- "error converting inlines to html");
- bformata(html, "%s", contents->data);
- bdestroy(contents);
- break;
- case emph:
- check(inlines_to_html(ils->content.inlines, &contents) == 0,
- "error converting inlines to html");
- bformata(html, "%s", contents->data);
- bdestroy(contents);
- break;
- }
- ils = ils->next;
- }
- *result = html;
- return 0;
- error:
- return -1;
-}
diff --git a/src/inlines.c b/src/inlines.c
index 4ff45ad..82c7219 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -6,9 +6,7 @@
#include "stmd.h"
#include "uthash.h"
-#include "debug.h"
#include "scanners.h"
-#include "utf8.h"
typedef struct Subject {
const gh_buf *buffer;
@@ -119,7 +117,7 @@ inline static inl* make_linkable(int t, inl* label, chunk url, chunk title)
e->tag = t;
e->content.linkable.label = label;
e->content.linkable.url = chunk_to_cstr(&url);
- e->content.linkable.title = chunk_to_cstr(&title);
+ e->content.linkable.title = url.len ? chunk_to_cstr(&title) : NULL;
e->next = NULL;
return e;
}
diff --git a/src/main.c b/src/main.c
index 9e0a3c8..e1abedc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,99 +1,77 @@
#include
#include
-#include "bstrlib.h"
+#include
#include "stmd.h"
#include "debug.h"
void print_usage()
{
- printf("Usage: stmd [FILE*]\n");
- printf("Options: --help, -h Print usage information\n");
- printf(" --ast Print AST instead of HTML\n");
- printf(" --version Print version\n");
+ printf("Usage: stmd [FILE*]\n");
+ printf("Options: --help, -h Print usage information\n");
+ printf(" --ast Print AST instead of HTML\n");
+ printf(" --version Print version\n");
}
-int main(int argc, char *argv[]) {
- int i;
- bool ast = false;
- int g = 0;
- int numfps = 0;
- int files[argc];
+static void print_document(block *document, bool ast)
+{
+ gh_buf html = GH_BUF_INIT;
+
+ if (ast) {
+ print_blocks(document, 0);
+ } else {
+ blocks_to_html(&html, document, false);
+ printf("%s", html.ptr);
+ gh_buf_free(&html);
+ }
+}
- for (i=1; i < argc; i++) {
- if (strcmp(argv[i], "--version") == 0) {
- printf("stmd %s", VERSION);
- printf(" - CommonMark converter (c) 2014 John MacFarlane\n");
- exit(0);
- } else if ((strcmp(argv[i], "--help") == 0) ||
- (strcmp(argv[i], "-h") == 0)) {
- print_usage();
- exit(0);
- } else if (strcmp(argv[i], "--ast") == 0) {
- ast = true;
- } else if (*argv[i] == '-') {
- print_usage();
- exit(1);
- } else { // treat as file argument
- files[g] = i;
- g++;
- }
- }
+int main(int argc, char *argv[])
+{
+ int i, numfps = 0;
+ bool ast = false;
+ int files[argc];
+ block *document = NULL;
- numfps = g;
- bstring s = NULL;
- bstring html;
- g = 0;
- block * cur = make_document();
- int linenum = 1;
- extern int errno;
- FILE * fp = NULL;
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--version") == 0) {
+ printf("stmd %s", VERSION);
+ printf(" - CommonMark converter (c) 2014 John MacFarlane\n");
+ exit(0);
+ } else if ((strcmp(argv[i], "--help") == 0) ||
+ (strcmp(argv[i], "-h") == 0)) {
+ print_usage();
+ exit(0);
+ } else if (strcmp(argv[i], "--ast") == 0) {
+ ast = true;
+ } else if (*argv[i] == '-') {
+ print_usage();
+ exit(1);
+ } else { // treat as file argument
+ files[numfps++] = i;
+ }
+ }
- if (numfps == 0) {
- // read from stdin
- while ((s = bgets((bNgetc) fgetc, stdin, '\n'))) {
- check(incorporate_line(s, linenum, &cur) == 0,
- "error incorporating line %d", linenum);
- bdestroy(s);
- linenum++;
- }
- } else {
- // iterate over input file pointers
- for (g=0; g < numfps; g++) {
+ if (numfps == 0) {
+ document = stmd_parse_file(stdin);
+ print_document(document, ast);
+ free_blocks(document);
+ } else {
+ for (i = 0; i < numfps; i++) {
+ FILE *fp = fopen(argv[files[i]], "r");
- fp = fopen(argv[files[g]], "r");
- if (fp == NULL) {
- fprintf(stderr, "Error opening file %s: %s\n",
- argv[files[g]], strerror(errno));
- exit(1);
- }
+ if (fp == NULL) {
+ fprintf(stderr, "Error opening file %s: %s\n",
+ argv[files[i]], strerror(errno));
+ exit(1);
+ }
- while ((s = bgets((bNgetc) fgetc, fp, '\n'))) {
- check(incorporate_line(s, linenum, &cur) == 0,
- "error incorporating line %d", linenum);
- bdestroy(s);
- linenum++;
- }
- fclose(fp);
- }
- }
+ document = stmd_parse_file(fp);
+ print_document(document, ast);
+ free_blocks(document);
+ fclose(fp);
+ }
+ }
- while (cur != cur->top) {
- finalize(cur, linenum);
- cur = cur->parent;
- }
- check(cur == cur->top, "problems finalizing open containers");
- finalize(cur, linenum);
- process_inlines(cur, cur->attributes.refmap);
- if (ast) {
- print_blocks(cur, 0);
- } else {
- check(blocks_to_html(cur, &html, false) == 0, "could not format as HTML");
- // printf("%s", html->data);
- bdestroy(html);
- }
- free_blocks(cur);
- return 0;
-error:
- return -1;
+ return 0;
}
diff --git a/src/print.c b/src/print.c
index a924870..3ebde16 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1,168 +1,175 @@
#include
#include
-#include "bstrlib.h"
+#include
#include "stmd.h"
#include "debug.h"
-static bstring format_str(bstring s)
+static void print_str(const unsigned char *s, int len)
{
- int pos = 0;
- int len = blength(s);
- bstring result = bfromcstr("");
- char c;
- bformata(result, "\"");
- while (pos < len) {
- c = bchar(s, pos);
- switch (c) {
- case '\n':
- bformata(result, "\\n");
- break;
- case '"':
- bformata(result, "\\\"");
- break;
- case '\\':
- bformata(result, "\\\\");
- break;
- default:
- bformata(result, "%c", c);
- }
- pos++;
- }
- bformata(result, "\"");
- return result;
+ int i;
+
+ if (len < 0)
+ len = strlen(s);
+
+ putchar('"');
+ for (i = 0; i < len; ++i) {
+ unsigned char c = s[i];
+
+ switch (c) {
+ case '\n':
+ printf("\\n");
+ break;
+ case '"':
+ printf("\\\"");
+ break;
+ case '\\':
+ printf("\\\\");
+ break;
+ default:
+ putchar((int)c);
+ }
+ }
+ putchar('"');
}
// Functions to pretty-print inline and block lists, for debugging.
// Prettyprint an inline list, for debugging.
extern void print_blocks(block* b, int indent)
{
- struct ListData * data;
- while(b != NULL) {
- // printf("%3d %3d %3d| ", b->start_line, b->start_column, b->end_line);
- for (int i=0; i < indent; i++) {
- putchar(' ');
- }
- switch(b->tag) {
- case document:
- printf("document\n");
- print_blocks(b->children, indent + 2);
- break;
- case block_quote:
- printf("block_quote\n");
- print_blocks(b->children, indent + 2);
- break;
- case list_item:
- data = &(b->attributes.list_data);
- printf("list_item\n");
- print_blocks(b->children, indent + 2);
- break;
- case list:
- data = &(b->attributes.list_data);
- if (data->list_type == ordered) {
- printf("list (type=ordered tight=%s start=%d delim=%s)\n",
- (data->tight ? "true" : "false"),
- data->start,
- (data->delimiter == parens ? "parens" : "period"));
- } else {
- printf("list (type=bullet tight=%s bullet_char=%c)\n",
- (data->tight ? "true" : "false"),
- data->bullet_char);
- }
- print_blocks(b->children, indent + 2);
- break;
- case atx_header:
- printf("atx_header (level=%d)\n", b->attributes.header_level);
- print_inlines(b->inline_content, indent + 2);
- break;
- case setext_header:
- printf("setext_header (level=%d)\n", b->attributes.header_level);
- print_inlines(b->inline_content, indent + 2);
- break;
- case paragraph:
- printf("paragraph\n");
- print_inlines(b->inline_content, indent + 2);
- break;
- case hrule:
- printf("hrule\n");
- break;
- case indented_code:
- printf("indented_code %s\n", format_str(b->string_content)->data);
- break;
- case fenced_code:
- printf("fenced_code length=%d info=%s %s\n",
- b->attributes.fenced_code_data.fence_length,
- format_str(b->attributes.fenced_code_data.info)->data,
- format_str(b->string_content)->data);
- break;
- case html_block:
- printf("html_block %s\n", format_str(b->string_content)->data);
- break;
- case reference_def:
- printf("reference_def\n");
- break;
- default:
- log_warn("block type %d not implemented\n", b->tag);
- break;
- }
- b = b->next;
- }
+ struct ListData *data;
+
+ while(b != NULL) {
+ // printf("%3d %3d %3d| ", b->start_line, b->start_column, b->end_line);
+ for (int i=0; i < indent; i++) {
+ putchar(' ');
+ }
+
+ switch(b->tag) {
+ case document:
+ printf("document\n");
+ print_blocks(b->children, indent + 2);
+ break;
+ case block_quote:
+ printf("block_quote\n");
+ print_blocks(b->children, indent + 2);
+ break;
+ case list_item:
+ data = &(b->attributes.list_data);
+ printf("list_item\n");
+ print_blocks(b->children, indent + 2);
+ break;
+ case list:
+ data = &(b->attributes.list_data);
+ if (data->list_type == ordered) {
+ printf("list (type=ordered tight=%s start=%d delim=%s)\n",
+ (data->tight ? "true" : "false"),
+ data->start,
+ (data->delimiter == parens ? "parens" : "period"));
+ } else {
+ printf("list (type=bullet tight=%s bullet_char=%c)\n",
+ (data->tight ? "true" : "false"),
+ data->bullet_char);
+ }
+ print_blocks(b->children, indent + 2);
+ break;
+ case atx_header:
+ printf("atx_header (level=%d)\n", b->attributes.header_level);
+ print_inlines(b->inline_content, indent + 2);
+ break;
+ case setext_header:
+ printf("setext_header (level=%d)\n", b->attributes.header_level);
+ print_inlines(b->inline_content, indent + 2);
+ break;
+ case paragraph:
+ printf("paragraph\n");
+ print_inlines(b->inline_content, indent + 2);
+ break;
+ case hrule:
+ printf("hrule\n");
+ break;
+ case indented_code:
+ printf("indented_code ");
+ print_str(b->string_content.ptr, -1);
+ putchar('\n');
+ break;
+ case fenced_code:
+ printf("fenced_code length=%d info=",
+ b->attributes.fenced_code_data.fence_length);
+ print_str(b->attributes.fenced_code_data.info.ptr, -1);
+ putchar(' ');
+ print_str(b->string_content.ptr, -1);
+ putchar('\n');
+ break;
+ case html_block:
+ printf("html_block ");
+ print_str(b->string_content.ptr, -1);
+ putchar('\n');
+ break;
+ case reference_def:
+ printf("reference_def\n");
+ break;
+ default:
+ printf("# NOT IMPLEMENTED (%d)\n", b->tag);
+ break;
+ }
+ b = b->next;
+ }
}
// Prettyprint an inline list, for debugging.
extern void print_inlines(inl* ils, int indent)
{
- while(ils != NULL) {
- /*
- // we add 11 extra spaces for the line/column info
- for (int i=0; i < 11; i++) {
- putchar(' ');
- }
- putchar('|');
- putchar(' ');
- */
- for (int i=0; i < indent; i++) {
- putchar(' ');
- }
- switch(ils->tag) {
- case str:
- printf("str %s\n", format_str(ils->content.literal)->data);
- break;
- case linebreak:
- printf("linebreak\n");
- break;
- case softbreak:
- printf("softbreak\n");
- break;
- case code:
- printf("code %s\n", format_str(ils->content.literal)->data);
- break;
- case raw_html:
- printf("html %s\n", format_str(ils->content.literal)->data);
- break;
- case entity:
- printf("entity %s\n", format_str(ils->content.literal)->data);
- break;
- case link:
- printf("link url=%s title=%s\n",
- format_str(ils->content.linkable.url)->data,
- format_str(ils->content.linkable.title)->data);
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- case image:
- printf("image url=%s title=%s\n",
- format_str(ils->content.linkable.url)->data,
- format_str(ils->content.linkable.title)->data);
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- case strong:
- printf("strong\n");
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- case emph:
- printf("emph\n");
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- }
- ils = ils->next;
- }
+ while(ils != NULL) {
+ for (int i=0; i < indent; i++) {
+ putchar(' ');
+ }
+ switch(ils->tag) {
+ case str:
+ printf("str ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case linebreak:
+ printf("linebreak\n");
+ break;
+ case softbreak:
+ printf("softbreak\n");
+ break;
+ case code:
+ printf("code ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case raw_html:
+ printf("html ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case entity:
+ printf("entity ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case link:
+ case image:
+ printf("%s url=", ils->tag == link ? "link" : "image");
+ print_str(ils->content.linkable.url, -1);
+ if (ils->content.linkable.title) {
+ printf(" title=");
+ print_str(ils->content.linkable.title, -1);
+ }
+ putchar('\n');
+ print_inlines(ils->content.linkable.label, indent + 2);
+ break;
+ case strong:
+ printf("strong\n");
+ print_inlines(ils->content.linkable.label, indent + 2);
+ break;
+ case emph:
+ printf("emph\n");
+ print_inlines(ils->content.linkable.label, indent + 2);
+ break;
+ }
+ ils = ils->next;
+ }
}
diff --git a/src/stmd.h b/src/stmd.h
index eb1b989..dc24235 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -105,19 +105,14 @@ extern block* add_child(block* parent,
int block_type, int start_line, int start_column);
void free_blocks(block* e);
-block *stmd_parse_document(const char *buffer, size_t len);
-
-// FOR NOW:
-void process_inlines(block* cur, reference** refmap);
-void incorporate_line(gh_buf *ln, int line_number, block** curptr);
-void finalize(block* b, int line_number);
+extern block *stmd_parse_document(const unsigned char *buffer, size_t len);
+extern block *stmd_parse_file(FILE *f);
void print_inlines(inl* ils, int indent);
void print_blocks(block* blk, int indent);
-/* TODO */
-// int blocks_to_html(block* b, bstring* result, bool tight);
-// int inlines_to_html(inl* b, bstring* result);
+void blocks_to_html(gh_buf *html, block *b, bool tight);
+void inlines_to_html(gh_buf *html, inl *b);
void utf8proc_case_fold(gh_buf *dest, const unsigned char *str, int len);
diff --git a/src/utf8.c b/src/utf8.c
index 1a5df9e..e3f8dd3 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -1,6 +1,8 @@
#include
-#include "bstrlib.h"
-#include "debug.h"
+#include
+#include
+
+#include "stmd.h"
static const int8_t utf8proc_utf8class[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
diff --git a/src/utf8.h b/src/utf8.h
deleted file mode 100644
index fe59a90..0000000
--- a/src/utf8.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#include
-#include "bstrlib.h"
-
-extern unsigned char * from_utf8(unsigned char * s, unsigned int *n);
-extern int to_utf8(unsigned int c, bstring dest);
-extern bstring case_fold(bstring source);
--
cgit v1.2.3
From 24248c0f1a6de6f229890c5c03aeff8738214fee Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 2 Sep 2014 13:30:13 +0200
Subject: Rename inlines
---
src/inlines.c | 50 +++++++++++++++++++++++++-------------------------
src/print.c | 22 +++++++++++-----------
src/stmd.h | 4 ++--
3 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/src/inlines.c b/src/inlines.c
index 82c7219..b9ece0e 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -151,15 +151,15 @@ inline static inl* make_simple(int t)
}
// Macros for creating various kinds of inlines.
-#define make_str(s) make_literal(str, s)
-#define make_code(s) make_literal(code, s)
-#define make_raw_html(s) make_literal(raw_html, s)
-#define make_entity(s) make_literal(entity, s)
-#define make_linebreak() make_simple(linebreak)
-#define make_softbreak() make_simple(softbreak)
-#define make_link(label, url, title) make_linkable(link, label, url, title)
-#define make_emph(contents) make_inlines(emph, contents)
-#define make_strong(contents) make_inlines(strong, contents)
+#define make_str(s) make_literal(INL_STRING, s)
+#define make_code(s) make_literal(INL_CODE, s)
+#define make_raw_html(s) make_literal(INL_RAW_HTML, s)
+#define make_entity(s) make_literal(INL_ENTITY, s)
+#define make_linebreak() make_simple(INL_LINEBREAK)
+#define make_softbreak() make_simple(INL_SOFTBREAK)
+#define make_link(label, url, title) make_linkable(INL_LINK, label, url, title)
+#define make_emph(contents) make_inlines(INL_EMPH, contents)
+#define make_strong(contents) make_inlines(INL_STRONG, contents)
// Free an inline list.
extern void free_inlines(inl* e)
@@ -167,23 +167,23 @@ extern void free_inlines(inl* e)
inl * next;
while (e != NULL) {
switch (e->tag){
- case str:
- case raw_html:
- case code:
- case entity:
+ case INL_STRING:
+ case INL_RAW_HTML:
+ case INL_CODE:
+ case INL_ENTITY:
chunk_free(&e->content.literal);
break;
- case linebreak:
- case softbreak:
+ case INL_LINEBREAK:
+ case INL_SOFTBREAK:
break;
- case link:
- case image:
+ case INL_LINK:
+ case INL_IMAGE:
free(e->content.linkable.url);
free(e->content.linkable.title);
free_inlines(e->content.linkable.label);
break;
- case emph:
- case strong:
+ case INL_EMPH:
+ case INL_STRONG:
free_inlines(e->content.inlines);
break;
default:
@@ -454,7 +454,7 @@ static inl* handle_strong_emph(subject* subj, char c)
numdelims = scan_delims(subj, c, &can_open, &can_close);
if (numdelims >= 1 && can_close) {
subj->pos += 1;
- first_head->tag = emph;
+ first_head->tag = INL_EMPH;
chunk_free(&first_head->content.literal);
first_head->content.inlines = first_head->next;
first_head->next = NULL;
@@ -471,7 +471,7 @@ static inl* handle_strong_emph(subject* subj, char c)
numdelims = scan_delims(subj, c, &can_open, &can_close);
if (numdelims >= 2 && can_close) {
subj->pos += 2;
- first_head->tag = strong;
+ first_head->tag = INL_STRONG;
chunk_free(&first_head->content.literal);
first_head->content.inlines = first_head->next;
first_head->next = NULL;
@@ -502,10 +502,10 @@ static inl* handle_strong_emph(subject* subj, char c)
}
subj->pos += numdelims;
if (first_close) {
- first_head->tag = first_close_delims == 1 ? strong : emph;
+ first_head->tag = first_close_delims == 1 ? INL_STRONG : INL_EMPH;
chunk_free(&first_head->content.literal);
first_head->content.inlines =
- make_inlines(first_close_delims == 1 ? emph : strong,
+ make_inlines(first_close_delims == 1 ? INL_EMPH : INL_STRONG,
first_head->next);
il = first_head->next;
@@ -989,8 +989,8 @@ static int parse_inline(subject* subj, inl ** last)
advance(subj);
if (peek_char(subj) == '[') {
new = handle_left_bracket(subj);
- if (new != NULL && new->tag == link) {
- new->tag = image;
+ if (new != NULL && new->tag == INL_LINK) {
+ new->tag = INL_IMAGE;
} else {
new = append_inlines(make_str(chunk_literal("!")), new);
}
diff --git a/src/print.c b/src/print.c
index 3ebde16..0a87925 100644
--- a/src/print.c
+++ b/src/print.c
@@ -124,35 +124,35 @@ extern void print_inlines(inl* ils, int indent)
putchar(' ');
}
switch(ils->tag) {
- case str:
+ case INL_STRING:
printf("str ");
print_str(ils->content.literal.data, ils->content.literal.len);
putchar('\n');
break;
- case linebreak:
+ case INL_LINEBREAK:
printf("linebreak\n");
break;
- case softbreak:
+ case INL_SOFTBREAK:
printf("softbreak\n");
break;
- case code:
+ case INL_CODE:
printf("code ");
print_str(ils->content.literal.data, ils->content.literal.len);
putchar('\n');
break;
- case raw_html:
+ case INL_RAW_HTML:
printf("html ");
print_str(ils->content.literal.data, ils->content.literal.len);
putchar('\n');
break;
- case entity:
+ case INL_ENTITY:
printf("entity ");
print_str(ils->content.literal.data, ils->content.literal.len);
putchar('\n');
break;
- case link:
- case image:
- printf("%s url=", ils->tag == link ? "link" : "image");
+ case INL_LINK:
+ case INL_IMAGE:
+ printf("%s url=", ils->tag == INL_LINK ? "link" : "image");
print_str(ils->content.linkable.url, -1);
if (ils->content.linkable.title) {
printf(" title=");
@@ -161,11 +161,11 @@ extern void print_inlines(inl* ils, int indent)
putchar('\n');
print_inlines(ils->content.linkable.label, indent + 2);
break;
- case strong:
+ case INL_STRONG:
printf("strong\n");
print_inlines(ils->content.linkable.label, indent + 2);
break;
- case emph:
+ case INL_EMPH:
printf("emph\n");
print_inlines(ils->content.linkable.label, indent + 2);
break;
diff --git a/src/stmd.h b/src/stmd.h
index dc24235..1e490d6 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -12,8 +12,8 @@ typedef struct {
} chunk;
typedef struct Inline {
- enum { str, softbreak, linebreak, code, raw_html, entity,
- emph, strong, link, image } tag;
+ enum { INL_STRING, INL_SOFTBREAK, INL_LINEBREAK, INL_CODE, INL_RAW_HTML, INL_ENTITY,
+ INL_EMPH, INL_STRONG, INL_LINK, INL_IMAGE } tag;
union {
chunk literal;
struct Inline *inlines;
--
cgit v1.2.3
From c28af79329264a7cf331a1b1c414919e4ed9e9f9 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 2 Sep 2014 13:37:34 +0200
Subject: It buiiiilds
---
src/blocks.c | 11 ++-
src/buffer.c | 6 +-
src/html/houdini.h | 44 ++++++++++
src/html/houdini_href_e.c | 115 +++++++++++++++++++++++++
src/html/houdini_html_e.c | 89 +++++++++++++++++++
src/html/html.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++
src/stmd.h | 1 +
src/utf8.c | 7 +-
8 files changed, 473 insertions(+), 12 deletions(-)
create mode 100644 src/html/houdini.h
create mode 100644 src/html/houdini_href_e.c
create mode 100644 src/html/houdini_html_e.c
create mode 100644 src/html/html.c
diff --git a/src/blocks.c b/src/blocks.c
index 71dc830..42f20db 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -8,6 +8,7 @@
#include "scanners.h"
#include "uthash.h"
+static void incorporate_line(gh_buf *ln, int line_number, block** curptr);
static void finalize(block* b, int line_number);
static block* make_block(int tag, int start_line, int start_column)
@@ -390,7 +391,7 @@ static void expand_tabs(gh_buf *ob, const unsigned char *line, size_t size)
}
}
-static block *finalize_parsing(block *document, int linenum)
+static block *finalize_document(block *document, int linenum)
{
while (document != document->top) {
finalize(document, linenum);
@@ -411,7 +412,7 @@ extern block *stmd_parse_file(FILE *f)
block *document = make_document();
while (fgets((char *)buffer, sizeof(buffer), f)) {
- expand_tabs(&line, buffer, strlen(buffer));
+ expand_tabs(&line, buffer, strlen((char *)buffer));
incorporate_line(&line, linenum, &document);
gh_buf_clear(&line);
linenum++;
@@ -429,7 +430,7 @@ extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
block *document = make_document();
while (buffer < end) {
- const char *eol = memchr(buffer, '\n', end - buffer);
+ const unsigned char *eol = memchr(buffer, '\n', end - buffer);
if (!eol) {
expand_tabs(&line, buffer, end - buffer);
@@ -449,9 +450,7 @@ extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
}
// Process one line at a time, modifying a block.
-// Returns 0 if successful. curptr is changed to point to
-// the currently open block.
-extern void incorporate_line(gh_buf *ln, int line_number, block** curptr)
+static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
{
block* last_matched_container;
int offset = 0;
diff --git a/src/buffer.c b/src/buffer.c
index 17dc864..cfc6a7e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -245,11 +245,11 @@ int gh_buf_cmp(const gh_buf *a, const gh_buf *b)
int gh_buf_strchr(const gh_buf *buf, int c, int pos)
{
- const char *p = memchr(buf->ptr + pos, c, buf->size - pos);
+ const unsigned char *p = memchr(buf->ptr + pos, c, buf->size - pos);
if (!p)
return -1;
- return (int)(p - buf->ptr);
+ return (int)(p - (const unsigned char *)buf->ptr);
}
int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
@@ -264,7 +264,7 @@ int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
return -1;
}
-void gh_buf_truncate(gh_buf *buf, size_t len)
+void gh_buf_truncate(gh_buf *buf, int len)
{
if (len < buf->size) {
buf->size = len;
diff --git a/src/html/houdini.h b/src/html/houdini.h
new file mode 100644
index 0000000..31fe917
--- /dev/null
+++ b/src/html/houdini.h
@@ -0,0 +1,44 @@
+#ifndef __HOUDINI_H__
+#define __HOUDINI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include
+#include "buffer.h"
+
+#define likely(x) __builtin_expect((x),1)
+#define unlikely(x) __builtin_expect((x),0)
+
+#ifdef HOUDINI_USE_LOCALE
+# define _isxdigit(c) isxdigit(c)
+# define _isdigit(c) isdigit(c)
+#else
+/*
+ * Helper _isdigit methods -- do not trust the current locale
+ * */
+# define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)
+# define _isdigit(c) ((c) >= '0' && (c) <= '9')
+#endif
+
+#define HOUDINI_ESCAPED_SIZE(x) (((x) * 12) / 10)
+#define HOUDINI_UNESCAPED_SIZE(x) (x)
+
+extern int houdini_escape_html(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure);
+extern int houdini_unescape_html(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_xml(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_uri(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_url(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_unescape_uri(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_unescape_url(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_js(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_unescape_js(gh_buf *ob, const uint8_t *src, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/html/houdini_href_e.c b/src/html/houdini_href_e.c
new file mode 100644
index 0000000..59fe850
--- /dev/null
+++ b/src/html/houdini_href_e.c
@@ -0,0 +1,115 @@
+#include
+#include
+#include
+
+#include "html/houdini.h"
+
+/*
+ * The following characters will not be escaped:
+ *
+ * -_.+!*'(),%#@?=;:/,+&$ alphanum
+ *
+ * Note that this character set is the addition of:
+ *
+ * - The characters which are safe to be in an URL
+ * - The characters which are *not* safe to be in
+ * an URL because they are RESERVED characters.
+ *
+ * We asume (lazily) that any RESERVED char that
+ * appears inside an URL is actually meant to
+ * have its native function (i.e. as an URL
+ * component/separator) and hence needs no escaping.
+ *
+ * There are two exceptions: the chacters & (amp)
+ * and ' (single quote) do not appear in the table.
+ * They are meant to appear in the URL as components,
+ * yet they require special HTML-entity escaping
+ * to generate valid HTML markup.
+ *
+ * All other characters will be escaped to %XX.
+ *
+ */
+static const char HREF_SAFE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+int
+houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
+{
+ static const uint8_t hex_chars[] = "0123456789ABCDEF";
+ size_t i = 0, org;
+ uint8_t hex_str[3];
+
+ hex_str[0] = '%';
+
+ while (i < size) {
+ org = i;
+ while (i < size && HREF_SAFE[src[i]] != 0)
+ i++;
+
+ if (likely(i > org)) {
+ if (unlikely(org == 0)) {
+ if (i >= size)
+ return 0;
+
+ gh_buf_grow(ob, HOUDINI_ESCAPED_SIZE(size));
+ }
+
+ gh_buf_put(ob, src + org, i - org);
+ }
+
+ /* escaping */
+ if (i >= size)
+ break;
+
+ switch (src[i]) {
+ /* amp appears all the time in URLs, but needs
+ * HTML-entity escaping to be inside an href */
+ case '&':
+ gh_buf_puts(ob, "&");
+ break;
+
+ /* the single quote is a valid URL character
+ * according to the standard; it needs HTML
+ * entity escaping too */
+ case '\'':
+ gh_buf_puts(ob, "'");
+ break;
+
+ /* the space can be escaped to %20 or a plus
+ * sign. we're going with the generic escape
+ * for now. the plus thing is more commonly seen
+ * when building GET strings */
+#if 0
+ case ' ':
+ gh_buf_putc(ob, '+');
+ break;
+#endif
+
+ /* every other character goes with a %XX escaping */
+ default:
+ hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];
+ hex_str[2] = hex_chars[src[i] & 0xF];
+ gh_buf_put(ob, hex_str, 3);
+ }
+
+ i++;
+ }
+
+ return 1;
+}
diff --git a/src/html/houdini_html_e.c b/src/html/houdini_html_e.c
new file mode 100644
index 0000000..316c5ce
--- /dev/null
+++ b/src/html/houdini_html_e.c
@@ -0,0 +1,89 @@
+#include
+#include
+#include
+
+#include "html/houdini.h"
+
+/**
+ * According to the OWASP rules:
+ *
+ * & --> &
+ * < --> <
+ * > --> >
+ * " --> "
+ * ' --> ' ' is not recommended
+ * / --> / forward slash is included as it helps end an HTML entity
+ *
+ */
+static const char HTML_ESCAPE_TABLE[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const char *HTML_ESCAPES[] = {
+ "",
+ """,
+ "&",
+ "'",
+ "/",
+ "<",
+ ">"
+};
+
+int
+houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
+{
+ size_t i = 0, org, esc = 0;
+
+ while (i < size) {
+ org = i;
+ while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
+ i++;
+
+ if (i > org) {
+ if (unlikely(org == 0)) {
+ if (i >= size)
+ return 0;
+
+ gh_buf_grow(ob, HOUDINI_ESCAPED_SIZE(size));
+ }
+
+ gh_buf_put(ob, src + org, i - org);
+ }
+
+ /* escaping */
+ if (unlikely(i >= size))
+ break;
+
+ /* The forward slash is only escaped in secure mode */
+ if (src[i] == '/' && !secure) {
+ gh_buf_putc(ob, '/');
+ } else {
+ gh_buf_puts(ob, HTML_ESCAPES[esc]);
+ }
+
+ i++;
+ }
+
+ return 1;
+}
+
+int
+houdini_escape_html(gh_buf *ob, const uint8_t *src, size_t size)
+{
+ return houdini_escape_html0(ob, src, size, 1);
+}
diff --git a/src/html/html.c b/src/html/html.c
new file mode 100644
index 0000000..2f160ca
--- /dev/null
+++ b/src/html/html.c
@@ -0,0 +1,212 @@
+#include
+#include
+#include
+#include
+#include
+
+#include "stmd.h"
+#include "debug.h"
+#include "scanners.h"
+#include "html/houdini.h"
+
+// Functions to convert block and inline lists to HTML strings.
+
+static void escape_html(gh_buf *dest, const unsigned char *source, int length)
+{
+ if (length < 0)
+ length = strlen((char *)source);
+
+ houdini_escape_html0(dest, source, (size_t)length, 0);
+}
+
+static void escape_href(gh_buf *dest, const unsigned char *source, int length)
+{
+ if (length < 0)
+ length = strlen((char *)source);
+
+ houdini_escape_href(dest, source, (size_t)length);
+}
+
+static inline void cr(gh_buf *html)
+{
+ if (html->size && html->ptr[html->size - 1] != '\n')
+ gh_buf_putc(html, '\n');
+}
+
+// Convert a block list to HTML. Returns 0 on success, and sets result.
+void blocks_to_html(gh_buf *html, block *b, bool tight)
+{
+ struct ListData *data;
+
+ while(b != NULL) {
+ switch(b->tag) {
+ case document:
+ blocks_to_html(html, b->children, false);
+ break;
+
+ case paragraph:
+ if (tight) {
+ inlines_to_html(html, b->inline_content);
+ } else {
+ cr(html);
+ gh_buf_puts(html, "");
+ inlines_to_html(html, b->inline_content);
+ gh_buf_puts(html, "
");
+ cr(html);
+ }
+ break;
+
+ case block_quote:
+ cr(html);
+ gh_buf_puts(html, "");
+ blocks_to_html(html, b->children, false);
+ gh_buf_puts(html, "
");
+ cr(html);
+ break;
+
+ case list_item:
+ cr(html);
+ gh_buf_puts(html, "");
+ blocks_to_html(html, b->children, tight);
+ gh_buf_trim(html);
+ gh_buf_puts(html, "");
+ cr(html);
+ break;
+
+ case list:
+ // make sure a list starts at the beginning of the line:
+ cr(html);
+ data = &(b->attributes.list_data);
+
+ if (data->start > 1) {
+ gh_buf_printf(html, "<%s start=\"%d\">\n",
+ data->list_type == bullet ? "ul" : "ol",
+ data->start);
+ } else {
+ gh_buf_puts(html, data->list_type == bullet ? "\n" : "\n");
+ }
+
+ blocks_to_html(html, b->children, data->tight);
+ gh_buf_puts(html, data->list_type == bullet ? "
" : "");
+ cr(html);
+ break;
+
+ case atx_header:
+ case setext_header:
+ cr(html);
+ gh_buf_printf(html, "", b->attributes.header_level);
+ inlines_to_html(html, b->inline_content);
+ gh_buf_printf(html, "", b->attributes.header_level);
+ cr(html);
+ break;
+
+ case indented_code:
+ case fenced_code:
+ /* TODO: fenced code lang attributes */
+ cr(html);
+ gh_buf_puts(html, "");
+ escape_html(html, b->string_content.ptr, b->string_content.size);
+ gh_buf_puts(html, "
");
+ cr(html);
+ break;
+
+ case html_block:
+ gh_buf_put(html, b->string_content.ptr, b->string_content.size);
+ break;
+
+ case hrule:
+ gh_buf_puts(html, "
");
+ cr(html);
+ break;
+
+ case reference_def:
+ break;
+
+ default:
+ assert(false);
+ }
+
+ b = b->next;
+ }
+}
+
+// Convert an inline list to HTML. Returns 0 on success, and sets result.
+void inlines_to_html(gh_buf *html, inl* ils)
+{
+ gh_buf scrap = GH_BUF_INIT;
+
+ while(ils != NULL) {
+ switch(ils->tag) {
+ case INL_STRING:
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ break;
+
+ case INL_LINEBREAK:
+ gh_buf_puts(html, "
\n");
+ break;
+
+ case INL_SOFTBREAK:
+ gh_buf_putc(html, '\n');
+ break;
+
+ case INL_CODE:
+ gh_buf_puts(html, "");
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ gh_buf_puts(html, "
");
+ break;
+
+ case INL_RAW_HTML:
+ case INL_ENTITY:
+ gh_buf_put(html,
+ ils->content.literal.data,
+ ils->content.literal.len);
+ break;
+
+ case INL_LINK:
+ gh_buf_puts(html, "content.linkable.url, -1);
+
+ if (ils->content.linkable.title) {
+ gh_buf_puts(html, "\" title=\"");
+ escape_html(html, ils->content.linkable.title, -1);
+ }
+
+ gh_buf_puts(html, "\">");
+ inlines_to_html(html, ils->content.inlines);
+ gh_buf_puts(html, "");
+ break;
+
+ case INL_IMAGE:
+ gh_buf_puts(html, "content.linkable.url, -1);
+
+ inlines_to_html(&scrap, ils->content.inlines);
+ if (scrap.size) {
+ gh_buf_puts(html, "\" alt=\"");
+ escape_html(html, scrap.ptr, scrap.size);
+ }
+ gh_buf_clear(&scrap);
+
+ if (ils->content.linkable.title) {
+ gh_buf_puts(html, "\" title=\"");
+ escape_html(html, ils->content.linkable.title, -1);
+ }
+
+ gh_buf_puts(html, "\"/>");
+ break;
+
+ case INL_STRONG:
+ gh_buf_puts(html, "");
+ inlines_to_html(html, ils->content.inlines);
+ gh_buf_puts(html, "");
+ break;
+
+ case INL_EMPH:
+ gh_buf_puts(html, "");
+ inlines_to_html(html, ils->content.inlines);
+ gh_buf_puts(html, "");
+ break;
+ }
+ ils = ils->next;
+ }
+}
diff --git a/src/stmd.h b/src/stmd.h
index 1e490d6..3e284bd 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -1,4 +1,5 @@
#include
+#include
#include "buffer.h"
#include "uthash.h"
diff --git a/src/utf8.c b/src/utf8.c
index e3f8dd3..32c78a4 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
#include "stmd.h"
@@ -83,9 +84,9 @@ ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst)
return length;
}
-void utf8_encode_char(int32_t uc, gh_buf *buf)
+void utf8proc_encode_char(int32_t uc, gh_buf *buf)
{
- char dst[4];
+ unsigned char dst[4];
int len = 0;
if (uc < 0x00) {
@@ -99,7 +100,7 @@ void utf8_encode_char(int32_t uc, gh_buf *buf)
len = 2;
} else if (uc == 0xFFFF) {
dst[0] = 0xFF;
- return 1;
+ len = 1;
} else if (uc == 0xFFFE) {
dst[0] = 0xFE;
len = 1;
--
cgit v1.2.3
From 7e12fdba0c9a444a3cfc29c520e2f2caa57a8232 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 2 Sep 2014 14:15:24 +0200
Subject: NO SEGFAULTS KTHX
---
src/inlines.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/inlines.c b/src/inlines.c
index b9ece0e..7b48ad9 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -84,7 +84,7 @@ extern reference* lookup_reference(reference** refmap, chunk *label)
if (refmap != NULL) {
HASH_FIND_STR(*refmap, (char*)norm, ref);
}
- free(label);
+ free(norm);
return ref;
}
@@ -262,7 +262,7 @@ inline static unsigned char *chunk_to_cstr(chunk *c)
inline static chunk chunk_literal(const char *data)
{
- chunk c = {data, strlen(data), 0};
+ chunk c = {data, data ? strlen(data) : 0, 0};
return c;
}
@@ -937,6 +937,7 @@ static int find_special_char(subject *subj)
while (n < size) {
if (strchr("\n\\`&_*[]buffer, n)))
return n;
+ n++;
}
return -1;
@@ -974,7 +975,9 @@ static int parse_inline(subject* subj, inl ** last)
case '_':
if (subj->pos > 0 && (isalnum(gh_buf_at(subj->buffer, subj->pos - 1)) ||
gh_buf_at(subj->buffer, subj->pos - 1) == '_')) {
- goto text_literal;
+ new = make_str(chunk_literal("_"));
+ advance(subj);
+ break;
}
new = handle_strong_emph(subj, '_');
--
cgit v1.2.3
From a7314deae649646f1f7ce5ede972641b5b62538c Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 3 Sep 2014 03:40:23 +0200
Subject: 338/103
---
Makefile | 4 +-
src/blocks.c | 173 +++++++++++++++++-----------------
src/buffer.c | 26 ++++-
src/buffer.h | 2 +-
src/html/houdini_href_e.c | 10 +-
src/html/houdini_html_e.c | 10 +-
src/html/html.c | 4 +-
src/inlines.c | 235 ++++++++++++++++++----------------------------
src/print.c | 2 +-
src/scanners.h | 28 +++---
src/scanners.re | 85 +++++++----------
src/stmd.h | 16 ++--
12 files changed, 261 insertions(+), 334 deletions(-)
diff --git a/Makefile b/Makefile
index d14a928..89ec68c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=-ggdb3 -O0 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-ggdb3 -O0 -Wall -Werror
+CFLAGS=-ggdb3 -O0 -Wall -Wextra -Wno-unused-variable -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS=-ggdb3 -O0 -Wall -Wno-unused-variable # -Werror
SRCDIR=src
DATADIR=data
diff --git a/src/blocks.c b/src/blocks.c
index 42f20db..94ff986 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -8,6 +8,8 @@
#include "scanners.h"
#include "uthash.h"
+#define peek_at(i, n) (i)->data[n]
+
static void incorporate_line(gh_buf *ln, int line_number, block** curptr);
static void finalize(block* b, int line_number);
@@ -27,7 +29,6 @@ static block* make_block(int tag, int start_line, int start_column)
e->top = NULL;
e->attributes.refmap = NULL;
gh_buf_init(&e->string_content, 32);
- e->string_pos = 0;
e->inline_content = NULL;
e->next = NULL;
e->prev = NULL;
@@ -80,10 +81,10 @@ static inline bool accepts_lines(int block_type)
block_type == fenced_code);
}
-static void add_line(block* block, gh_buf *ln, int offset)
+static void add_line(block* block, chunk *ch, int offset)
{
assert(block->open);
- gh_buf_put(&block->string_content, ln->ptr + offset, ln->size - offset);
+ gh_buf_put(&block->string_content, ch->data + offset, ch->len - offset);
}
static void remove_trailing_blank_lines(gh_buf *ln)
@@ -104,7 +105,7 @@ static void remove_trailing_blank_lines(gh_buf *ln)
i = gh_buf_strchr(ln, '\n', i);
if (i >= 0)
- gh_buf_truncate(ln, i + 1);
+ gh_buf_truncate(ln, i);
}
// Check to see if a block ends with a blank line, descending
@@ -162,12 +163,12 @@ static void finalize(block* b, int line_number)
switch (b->tag) {
case paragraph:
pos = 0;
- while (gh_buf_at(&b->string_content, b->string_pos) == '[' &&
- (pos = parse_reference(&b->string_content, b->string_pos,
- b->top->attributes.refmap))) {
- b->string_pos = pos;
+ while (gh_buf_at(&b->string_content, 0) == '[' &&
+ (pos = parse_reference(&b->string_content, b->top->attributes.refmap))) {
+
+ gh_buf_drop(&b->string_content, pos);
}
- if (is_blank(&b->string_content, b->string_pos)) {
+ if (is_blank(&b->string_content, 0)) {
b->tag = reference_def;
}
break;
@@ -179,14 +180,16 @@ static void finalize(block* b, int line_number)
case fenced_code:
// first line of contents becomes info
- firstlinelen = gh_buf_strchr(&b->string_content, '\n', b->string_pos);
+ firstlinelen = gh_buf_strchr(&b->string_content, '\n', 0);
+
+ gh_buf_init(&b->attributes.fenced_code_data.info, 0);
gh_buf_set(
&b->attributes.fenced_code_data.info,
- b->string_content.ptr + b->string_pos,
+ b->string_content.ptr,
firstlinelen
);
- b->string_pos = firstlinelen + 1;
+ gh_buf_drop(&b->string_content, firstlinelen + 1);
gh_buf_trim(&b->attributes.fenced_code_data.info);
unescape_buffer(&b->attributes.fenced_code_data.info);
@@ -281,7 +284,7 @@ void process_inlines(block* cur, reference** refmap)
case paragraph:
case atx_header:
case setext_header:
- cur->inline_content = parse_inlines(&cur->string_content, cur->string_pos, refmap);
+ cur->inline_content = parse_inlines(&cur->string_content, refmap);
// MEM
// gh_buf_free(&cur->string_content);
break;
@@ -300,19 +303,18 @@ void process_inlines(block* cur, reference** refmap)
// Attempts to parse a list item marker (bullet or enumerated).
// On success, returns length of the marker, and populates
// data with the details. On failure, returns 0.
-static int parse_list_marker(gh_buf *ln, int pos,
- struct ListData ** dataptr)
+static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr)
{
- char c;
+ unsigned char c;
int startpos;
struct ListData * data;
startpos = pos;
- c = gh_buf_at(ln, pos);
+ c = peek_at(input, pos);
- if ((c == '*' || c == '-' || c == '+') && !scan_hrule(ln, pos)) {
+ if ((c == '*' || c == '-' || c == '+') && !scan_hrule(input, pos)) {
pos++;
- if (!isspace(gh_buf_at(ln, pos))) {
+ if (!isspace(peek_at(input, pos))) {
return 0;
}
data = malloc(sizeof(struct ListData));
@@ -327,14 +329,14 @@ static int parse_list_marker(gh_buf *ln, int pos,
int start = 0;
do {
- start = (10 * start) + (gh_buf_at(ln, pos) - '0');
+ start = (10 * start) + (peek_at(input, pos) - '0');
pos++;
- } while (isdigit(gh_buf_at(ln, pos)));
+ } while (isdigit(peek_at(input, pos)));
- c = gh_buf_at(ln, pos);
+ c = peek_at(input, pos);
if (c == '.' || c == ')') {
pos++;
- if (!isspace(gh_buf_at(ln, pos))) {
+ if (!isspace(peek_at(input, pos))) {
return 0;
}
data = malloc(sizeof(struct ListData));
@@ -449,8 +451,26 @@ extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
return finalize_document(document, linenum);
}
+static void chop_trailing_hashtags(chunk *ch)
+{
+ int n;
+
+ chunk_rtrim(ch);
+ n = ch->len - 1;
+
+ // if string ends in #s, remove these:
+ while (n >= 0 && peek_at(ch, n) == '#')
+ n--;
+
+ // the last # was escaped, so we include it.
+ if (n >= 0 && peek_at(ch, n) == '\\')
+ n++;
+
+ ch->len = n + 1;
+}
+
// Process one line at a time, modifying a block.
-static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
+static void incorporate_line(gh_buf *line, int line_number, block** curptr)
{
block* last_matched_container;
int offset = 0;
@@ -464,6 +484,10 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
bool blank = false;
int first_nonspace;
int indent;
+ chunk input;
+
+ input.data = line->ptr;
+ input.len = line->size;
// container starts at the document root.
container = cur->top;
@@ -475,21 +499,19 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
container = container->last_child;
first_nonspace = offset;
- while (gh_buf_at(ln, first_nonspace) == ' ') {
+ while (peek_at(&input, first_nonspace) == ' ') {
first_nonspace++;
}
indent = first_nonspace - offset;
- blank = gh_buf_at(ln, first_nonspace) == '\n';
+ blank = peek_at(&input, first_nonspace) == '\n';
if (container->tag == block_quote) {
-
- matched = indent <= 3 && gh_buf_at(ln, first_nonspace) == '>';
+ matched = indent <= 3 && peek_at(&input, first_nonspace) == '>';
if (matched) {
offset = first_nonspace + 1;
- if (gh_buf_at(ln, offset) == ' ') {
+ if (peek_at(&input, offset) == ' ')
offset++;
- }
} else {
all_matched = false;
}
@@ -526,7 +548,7 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
// skip optional spaces of fence offset
i = container->attributes.fenced_code_data.fence_offset;
- while (i > 0 && gh_buf_at(ln, offset) == ' ') {
+ while (i > 0 && peek_at(&input, offset) == ' ') {
offset++;
i--;
}
@@ -564,15 +586,13 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
container->tag != html_block) {
first_nonspace = offset;
- while (gh_buf_at(ln, first_nonspace) == ' ') {
+ while (peek_at(&input, first_nonspace) == ' ')
first_nonspace++;
- }
indent = first_nonspace - offset;
- blank = gh_buf_at(ln, first_nonspace) == '\n';
+ blank = peek_at(&input, first_nonspace) == '\n';
if (indent >= CODE_INDENT) {
-
if (cur->tag != paragraph && !blank) {
offset += CODE_INDENT;
container = add_child(container, indented_code, line_number, offset + 1);
@@ -580,76 +600,70 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
break;
}
- } else if (gh_buf_at(ln, first_nonspace) == '>') {
+ } else if (peek_at(&input, first_nonspace) == '>') {
offset = first_nonspace + 1;
// optional following character
- if (gh_buf_at(ln, offset) == ' ') {
+ if (peek_at(&input, offset) == ' ')
offset++;
- }
container = add_child(container, block_quote, line_number, offset + 1);
- } else if ((matched = scan_atx_header_start(ln, first_nonspace))) {
+ } else if ((matched = scan_atx_header_start(&input, first_nonspace))) {
offset = first_nonspace + matched;
container = add_child(container, atx_header, line_number, offset + 1);
- int hashpos = gh_buf_strchr(ln, '#', first_nonspace);
- assert(hashpos >= 0);
-
+ int hashpos = chunk_strchr(&input, '#', first_nonspace);
int level = 0;
- while (gh_buf_at(ln, hashpos) == '#') {
+
+ while (peek_at(&input, hashpos) == '#') {
level++;
hashpos++;
}
container->attributes.header_level = level;
- } else if ((matched = scan_open_code_fence(ln, first_nonspace))) {
+ } else if ((matched = scan_open_code_fence(&input, first_nonspace))) {
- container = add_child(container, fenced_code, line_number,
- first_nonspace + 1);
- container->attributes.fenced_code_data.fence_char = gh_buf_at(ln,
- first_nonspace);
+ container = add_child(container, fenced_code, line_number, first_nonspace + 1);
+ container->attributes.fenced_code_data.fence_char = peek_at(&input, first_nonspace);
container->attributes.fenced_code_data.fence_length = matched;
- container->attributes.fenced_code_data.fence_offset =
- first_nonspace - offset;
+ container->attributes.fenced_code_data.fence_offset = first_nonspace - offset;
offset = first_nonspace + matched;
- } else if ((matched = scan_html_block_tag(ln, first_nonspace))) {
+ } else if ((matched = scan_html_block_tag(&input, first_nonspace))) {
- container = add_child(container, html_block, line_number,
- first_nonspace + 1);
+ container = add_child(container, html_block, line_number, first_nonspace + 1);
// note, we don't adjust offset because the tag is part of the text
} else if (container->tag == paragraph &&
- (lev = scan_setext_header_line(ln, first_nonspace)) &&
+ (lev = scan_setext_header_line(&input, first_nonspace)) &&
// check that there is only one line in the paragraph:
gh_buf_strrchr(&container->string_content, '\n',
gh_buf_len(&container->string_content) - 2) < 0) {
container->tag = setext_header;
container->attributes.header_level = lev;
- offset = gh_buf_len(ln) - 1;
+ offset = input.len - 1;
} else if (!(container->tag == paragraph && !all_matched) &&
- (matched = scan_hrule(ln, first_nonspace))) {
+ (matched = scan_hrule(&input, first_nonspace))) {
// it's only now that we know the line is not part of a setext header:
container = add_child(container, hrule, line_number, first_nonspace + 1);
finalize(container, line_number);
container = container->parent;
- offset = gh_buf_len(ln) - 1;
+ offset = input.len - 1;
- } else if ((matched = parse_list_marker(ln, first_nonspace, &data))) {
+ } else if ((matched = parse_list_marker(&input, first_nonspace, &data))) {
// compute padding:
offset = first_nonspace + matched;
i = 0;
- while (i <= 5 && gh_buf_at(ln, offset + i) == ' ') {
+ while (i <= 5 && peek_at(&input, offset + i) == ' ') {
i++;
}
// i = number of spaces after marker, up to 5
- if (i >= 5 || i < 1 || gh_buf_at(ln, offset) == '\n') {
+ if (i >= 5 || i < 1 || peek_at(&input, offset) == '\n') {
data->padding = matched + 1;
if (i > 0) {
offset += 1;
@@ -674,6 +688,7 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
// add the list item
container = add_child(container, list_item, line_number,
first_nonspace + 1);
+ /* TODO: static */
container->attributes.list_data = *data;
free(data);
@@ -691,12 +706,11 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
// appropriate container.
first_nonspace = offset;
- while (gh_buf_at(ln, first_nonspace) == ' ') {
+ while (peek_at(&input, first_nonspace) == ' ')
first_nonspace++;
- }
indent = first_nonspace - offset;
- blank = gh_buf_at(ln, first_nonspace) == '\n';
+ blank = peek_at(&input, first_nonspace) == '\n';
// block quote lines are never blank as they start with >
// and we don't count blanks in fenced code for purposes of tight/loose
@@ -721,13 +735,12 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
cur->tag == paragraph &&
gh_buf_len(&cur->string_content) > 0) {
- add_line(cur, ln, offset);
+ add_line(cur, &input, offset);
} else { // not a lazy continuation
// finalize any blocks that were not matched and set cur to container:
while (cur != last_matched_container) {
-
finalize(cur, line_number);
cur = cur->parent;
assert(cur != NULL);
@@ -735,58 +748,46 @@ static void incorporate_line(gh_buf *ln, int line_number, block** curptr)
if (container->tag == indented_code) {
- add_line(container, ln, offset);
+ add_line(container, &input, offset);
} else if (container->tag == fenced_code) {
matched = (indent <= 3
- && gh_buf_at(ln, first_nonspace) == container->attributes.fenced_code_data.fence_char)
- && scan_close_code_fence(ln, first_nonspace,
+ && peek_at(&input, first_nonspace) == container->attributes.fenced_code_data.fence_char)
+ && scan_close_code_fence(&input, first_nonspace,
container->attributes.fenced_code_data.fence_length);
if (matched) {
// if closing fence, don't add line to container; instead, close it:
finalize(container, line_number);
container = container->parent; // back up to parent
} else {
- add_line(container, ln, offset);
+ add_line(container, &input, offset);
}
} else if (container->tag == html_block) {
- add_line(container, ln, offset);
+ add_line(container, &input, offset);
} else if (blank) {
// ??? do nothing
} else if (container->tag == atx_header) {
- // chop off trailing ###s...use a scanner?
- gh_buf_trim(ln);
- int p = gh_buf_len(ln) - 1;
-
- // if string ends in #s, remove these:
- while (gh_buf_at(ln, p) == '#') {
- p--;
- }
- if (gh_buf_at(ln, p) == '\\') {
- // the last # was escaped, so we include it.
- p++;
- }
- gh_buf_truncate(ln, p + 1);
- add_line(container, ln, first_nonspace);
+ chop_trailing_hashtags(&input);
+ add_line(container, &input, first_nonspace);
finalize(container, line_number);
container = container->parent;
} else if (accepts_lines(container->tag)) {
- add_line(container, ln, first_nonspace);
+ add_line(container, &input, first_nonspace);
} else if (container->tag != hrule && container->tag != setext_header) {
// create paragraph container for line
container = add_child(container, paragraph, line_number, first_nonspace + 1);
- add_line(container, ln, first_nonspace);
+ add_line(container, &input, first_nonspace);
} else {
assert(false);
diff --git a/src/buffer.c b/src/buffer.c
index cfc6a7e..dc4a405 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -95,7 +95,7 @@ void gh_buf_clear(gh_buf *buf)
int gh_buf_set(gh_buf *buf, const unsigned char *data, int len)
{
- if (len == 0 || data == NULL) {
+ if (len <= 0 || data == NULL) {
gh_buf_clear(buf);
} else {
if (data != buf->ptr) {
@@ -125,6 +125,9 @@ int gh_buf_putc(gh_buf *buf, int c)
int gh_buf_put(gh_buf *buf, const unsigned char *data, int len)
{
+ if (len <= 0)
+ return 0;
+
ENSURE_SIZE(buf, buf->size + len + 1);
memmove(buf->ptr + buf->size, data, len);
buf->size += len;
@@ -272,15 +275,28 @@ void gh_buf_truncate(gh_buf *buf, int len)
}
}
+void gh_buf_drop(gh_buf *buf, int n)
+{
+ if (n > 0) {
+ buf->size = buf->size - n;
+ if (buf->size)
+ memmove(buf->ptr, buf->ptr + n, buf->size);
+
+ buf->ptr[buf->size] = '\0';
+ }
+}
+
void gh_buf_trim(gh_buf *buf)
{
- /* TODO: leading whitespace? */
- /*
+ int i = 0;
+
+ if (!buf->size)
+ return;
+
while (i < buf->size && isspace(buf->ptr[i]))
i++;
- gh_buf_truncate(buf, i);
- */
+ gh_buf_drop(buf, i);
/* rtrim */
while (buf->size > 0) {
diff --git a/src/buffer.h b/src/buffer.h
index 422ef02..0d5143e 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -105,8 +105,8 @@ extern void gh_buf_clear(gh_buf *buf);
int gh_buf_strchr(const gh_buf *buf, int c, int pos);
int gh_buf_strrchr(const gh_buf *buf, int c, int pos);
+void gh_buf_drop(gh_buf *buf, int n);
void gh_buf_truncate(gh_buf *buf, int len);
-void gh_buf_ltruncate(gh_buf *buf, int len);
void gh_buf_trim(gh_buf *buf);
#endif
diff --git a/src/html/houdini_href_e.c b/src/html/houdini_href_e.c
index 59fe850..b2a7d79 100644
--- a/src/html/houdini_href_e.c
+++ b/src/html/houdini_href_e.c
@@ -62,16 +62,8 @@ houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
while (i < size && HREF_SAFE[src[i]] != 0)
i++;
- if (likely(i > org)) {
- if (unlikely(org == 0)) {
- if (i >= size)
- return 0;
-
- gh_buf_grow(ob, HOUDINI_ESCAPED_SIZE(size));
- }
-
+ if (likely(i > org))
gh_buf_put(ob, src + org, i - org);
- }
/* escaping */
if (i >= size)
diff --git a/src/html/houdini_html_e.c b/src/html/houdini_html_e.c
index 316c5ce..5cdd3dd 100644
--- a/src/html/houdini_html_e.c
+++ b/src/html/houdini_html_e.c
@@ -54,16 +54,8 @@ houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
i++;
- if (i > org) {
- if (unlikely(org == 0)) {
- if (i >= size)
- return 0;
-
- gh_buf_grow(ob, HOUDINI_ESCAPED_SIZE(size));
- }
-
+ if (i > org)
gh_buf_put(ob, src + org, i - org);
- }
/* escaping */
if (unlikely(i >= size))
diff --git a/src/html/html.c b/src/html/html.c
index 2f160ca..27ffe58 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -68,7 +68,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
cr(html);
gh_buf_puts(html, "");
blocks_to_html(html, b->children, tight);
- gh_buf_trim(html);
+ gh_buf_trim(html); /* TODO: rtrim */
gh_buf_puts(html, "");
cr(html);
break;
@@ -106,7 +106,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
cr(html);
gh_buf_puts(html, "");
escape_html(html, b->string_content.ptr, b->string_content.size);
- gh_buf_puts(html, "
");
+ gh_buf_puts(html, "");
cr(html);
break;
diff --git a/src/inlines.c b/src/inlines.c
index 7b48ad9..ef27a24 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -9,10 +9,10 @@
#include "scanners.h"
typedef struct Subject {
- const gh_buf *buffer;
- int pos;
- reference** reference_map;
- int label_nestlevel;
+ chunk input;
+ int pos;
+ int label_nestlevel;
+ reference** reference_map;
} subject;
reference* lookup_reference(reference** refmap, chunk *label);
@@ -27,12 +27,16 @@ inline static void chunk_trim(chunk *c);
inline static chunk chunk_literal(const char *data);
inline static chunk chunk_buf_detach(gh_buf *buf);
-inline static chunk chunk_buf(const gh_buf *buf, int pos, int len);
+inline static chunk chunk_dup(const chunk *ch, int pos, int len);
static inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
static inl *parse_inlines_while(subject* subj, int (*f)(subject*));
static int parse_inline(subject* subj, inl ** last);
+static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap);
+static void subject_from_buf(subject *e, gh_buf *buffer, reference** refmap);
+static int subject_find_special_char(subject *subj);
+
extern void free_reference(reference *ref) {
free(ref->label);
free(ref->url);
@@ -101,10 +105,12 @@ extern reference* make_reference(chunk *label, chunk *url, chunk *title)
extern void add_reference(reference** refmap, reference* ref)
{
reference * t = NULL;
- HASH_FIND(hh, *refmap, (char*)ref->label, (unsigned)strlen(ref->label), t);
+ const char *label = (const char *)ref->label;
+
+ HASH_FIND(hh, *refmap, label, strlen(label), t);
if (t == NULL) {
- HASH_ADD_KEYPTR(hh, *refmap, (char*)ref->label, (unsigned)strlen(ref->label), ref);
+ HASH_ADD_KEYPTR(hh, *refmap, label, strlen(label), ref);
} else {
free_reference(ref); // we free this now since it won't be in the refmap
}
@@ -210,87 +216,49 @@ inline static inl* append_inlines(inl* a, inl* b)
return a;
}
-// Make a 'subject' from an input string.
-static void init_subject(subject *e, gh_buf *buffer, int input_pos, reference** refmap)
+static void subject_from_buf(subject *e, gh_buf *buffer, reference** refmap)
{
- e->buffer = buffer;
- e->pos = input_pos;
+ e->input.data = buffer->ptr;
+ e->input.len = buffer->size;
+ e->input.alloc = 0;
+ e->pos = 0;
e->label_nestlevel = 0;
e->reference_map = refmap;
-}
-
-inline static int isbacktick(int c)
-{
- return (c == '`');
-}
-
-inline static void chunk_free(chunk *c)
-{
- if (c->alloc)
- free((char *)c->data);
-
- c->data = NULL;
- c->alloc = 0;
- c->len = 0;
-}
-
-inline static void chunk_trim(chunk *c)
-{
- while (c->len && isspace(c->data[0])) {
- c->data++;
- c->len--;
- }
-
- while (c->len > 0) {
- if (!isspace(c->data[c->len - 1]))
- break;
- c->len--;
- }
+ chunk_rtrim(&e->input);
}
-inline static unsigned char *chunk_to_cstr(chunk *c)
+static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap)
{
- unsigned char *str;
-
- str = malloc(c->len + 1);
- memcpy(str, c->data, c->len);
- str[c->len] = 0;
+ e->input.data = chunk->data;
+ e->input.len = chunk->len;
+ e->input.alloc = 0;
+ e->pos = 0;
+ e->label_nestlevel = 0;
+ e->reference_map = refmap;
- return str;
+ chunk_rtrim(&e->input);
}
-inline static chunk chunk_literal(const char *data)
+inline static int isbacktick(int c)
{
- chunk c = {data, data ? strlen(data) : 0, 0};
- return c;
+ return (c == '`');
}
-inline static chunk chunk_buf(const gh_buf *buf, int pos, int len)
+static inline unsigned char peek_char(subject *subj)
{
- chunk c = {buf->ptr + pos, len, 0};
- return c;
+ return (subj->pos < subj->input.len) ? subj->input.data[subj->pos] : 0;
}
-inline static chunk chunk_buf_detach(gh_buf *buf)
+static inline unsigned char peek_at(subject *subj, int pos)
{
- chunk c;
-
- c.len = buf->size;
- c.data = gh_buf_detach(buf);
- c.alloc = 1;
-
- return c;
+ return subj->input.data[pos];
}
-// Return the next character in the subject, without advancing.
-// Return 0 if at the end of the subject.
-#define peek_char(subj) gh_buf_at((subj)->buffer, (subj)->pos)
-
// Return true if there are more characters in the subject.
inline static int is_eof(subject* subj)
{
- return (subj->pos >= gh_buf_len(subj->buffer));
+ return (subj->pos >= subj->input.len);
}
// Advance the subject. Doesn't check for eof.
@@ -308,7 +276,7 @@ inline static chunk take_while(subject* subj, int (*f)(int))
len++;
}
- return chunk_buf(subj->buffer, startpos, len);
+ return chunk_dup(&subj->input, startpos, len);
}
// Try to process a backtick code span that began with a
@@ -388,7 +356,7 @@ static inl* handle_backticks(subject *subj)
} else {
gh_buf buf = GH_BUF_INIT;
- gh_buf_set(&buf, subj->buffer->ptr + startpos, endpos - startpos - openticks.len);
+ gh_buf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);
gh_buf_trim(&buf);
normalize_whitespace(&buf);
@@ -404,7 +372,7 @@ static int scan_delims(subject* subj, char c, bool * can_open, bool * can_close)
char char_before, char_after;
int startpos = subj->pos;
- char_before = subj->pos == 0 ? '\n' : gh_buf_at(subj->buffer, subj->pos - 1);
+ char_before = subj->pos == 0 ? '\n' : peek_at(subj, subj->pos - 1);
while (peek_char(subj) == c) {
numdelims++;
advance(subj);
@@ -439,7 +407,7 @@ static inl* handle_strong_emph(subject* subj, char c)
numdelims = scan_delims(subj, c, &can_open, &can_close);
subj->pos += numdelims;
- new = make_str(chunk_buf(subj->buffer, subj->pos - numdelims, numdelims));
+ new = make_str(chunk_dup(&subj->input, subj->pos - numdelims, numdelims));
*last = new;
first_head = new;
result = new;
@@ -488,7 +456,7 @@ static inl* handle_strong_emph(subject* subj, char c)
numdelims = scan_delims(subj, c, &can_open, &can_close);
if (can_close && numdelims >= 1 && numdelims <= 3 &&
numdelims != first_close_delims) {
- new = make_str(chunk_buf(subj->buffer, subj->pos, numdelims));
+ new = make_str(chunk_dup(&subj->input, subj->pos, numdelims));
append_inlines(*last, new);
*last = new;
if (first_close_delims == 1 && numdelims > 2) {
@@ -554,7 +522,7 @@ static inl* handle_backslash(subject *subj)
unsigned char nextchar = peek_char(subj);
if (ispunct(nextchar)) { // only ascii symbols and newline can be escaped
advance(subj);
- return make_str(chunk_buf(subj->buffer, subj->pos - 1, 1));
+ return make_str(chunk_dup(&subj->input, subj->pos - 1, 1));
} else if (nextchar == '\n') {
advance(subj);
return make_linebreak();
@@ -569,9 +537,9 @@ static inl* handle_entity(subject* subj)
{
int match;
inl *result;
- match = scan_entity(subj->buffer, subj->pos);
+ match = scan_entity(&subj->input, subj->pos);
if (match) {
- result = make_entity(chunk_buf(subj->buffer, subj->pos, match));
+ result = make_entity(chunk_dup(&subj->input, subj->pos, match));
subj->pos += match;
} else {
advance(subj);
@@ -584,15 +552,13 @@ static inl* handle_entity(subject* subj)
// Returns an inline sequence consisting of str and entity elements.
static inl *make_str_with_entities(chunk *content)
{
- inl * result = NULL;
- inl * new;
+ inl *result = NULL;
+ inl *new;
int searchpos;
char c;
subject subj;
- gh_buf content_buf = GH_BUF_INIT;
- gh_buf_set(&content_buf, content->data, content->len);
- init_subject(&subj, &content_buf, 0, NULL);
+ subject_from_chunk(&subj, content, NULL);
while ((c = peek_char(&subj))) {
switch (c) {
@@ -600,18 +566,13 @@ static inl *make_str_with_entities(chunk *content)
new = handle_entity(&subj);
break;
default:
- searchpos = gh_buf_strchr(subj.buffer, '&', subj.pos);
- if (searchpos < 0) {
- searchpos = gh_buf_len(subj.buffer);
- }
-
- new = make_str(chunk_buf(subj.buffer, subj.pos, searchpos - subj.pos));
+ searchpos = chunk_strchr(&subj.input, '&', subj.pos);
+ new = make_str(chunk_dup(&subj.input, subj.pos, searchpos - subj.pos));
subj.pos = searchpos;
}
result = append_inlines(result, new);
}
- gh_buf_free(&content_buf);
return result;
}
@@ -678,9 +639,9 @@ static inl* handle_pointy_brace(subject* subj)
advance(subj); // advance past first <
// first try to match a URL autolink
- matchlen = scan_autolink_uri(subj->buffer, subj->pos);
+ matchlen = scan_autolink_uri(&subj->input, subj->pos);
if (matchlen > 0) {
- contents = chunk_buf(subj->buffer, subj->pos, matchlen - 1);
+ contents = chunk_dup(&subj->input, subj->pos, matchlen - 1);
subj->pos += matchlen;
return make_link(
@@ -691,11 +652,11 @@ static inl* handle_pointy_brace(subject* subj)
}
// next try to match an email autolink
- matchlen = scan_autolink_email(subj->buffer, subj->pos);
+ matchlen = scan_autolink_email(&subj->input, subj->pos);
if (matchlen > 0) {
gh_buf mail_url = GH_BUF_INIT;
- contents = chunk_buf(subj->buffer, subj->pos, matchlen - 1);
+ contents = chunk_dup(&subj->input, subj->pos, matchlen - 1);
subj->pos += matchlen;
gh_buf_puts(&mail_url, "mailto:");
@@ -709,9 +670,9 @@ static inl* handle_pointy_brace(subject* subj)
}
// finally, try to match an html tag
- matchlen = scan_html_tag(subj->buffer, subj->pos);
+ matchlen = scan_html_tag(&subj->input, subj->pos);
if (matchlen > 0) {
- contents = chunk_buf(subj->buffer, subj->pos - 1, matchlen + 1);
+ contents = chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);
subj->pos += matchlen;
return make_raw_html(contents);
}
@@ -776,12 +737,7 @@ static int link_label(subject* subj, chunk *raw_label)
}
}
if (c == ']') {
- *raw_label = chunk_buf(
- subj->buffer,
- startpos + 1,
- subj->pos - (startpos + 1)
- );
-
+ *raw_label = chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));
subj->label_nestlevel = 0;
advance(subj); // advance past ]
return 1;
@@ -813,25 +769,25 @@ static inl* handle_left_bracket(subject* subj)
if (found_label) {
if (peek_char(subj) == '(' &&
- ((sps = scan_spacechars(subj->buffer, subj->pos + 1)) > -1) &&
- ((n = scan_link_url(subj->buffer, subj->pos + 1 + sps)) > -1)) {
+ ((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) &&
+ ((n = scan_link_url(&subj->input, subj->pos + 1 + sps)) > -1)) {
// try to parse an explicit link:
starturl = subj->pos + 1 + sps; // after (
endurl = starturl + n;
- starttitle = endurl + scan_spacechars(subj->buffer, endurl);
+ starttitle = endurl + scan_spacechars(&subj->input, endurl);
// ensure there are spaces btw url and title
endtitle = (starttitle == endurl) ? starttitle :
- starttitle + scan_link_title(subj->buffer, starttitle);
+ starttitle + scan_link_title(&subj->input, starttitle);
- endall = endtitle + scan_spacechars(subj->buffer, endtitle);
+ endall = endtitle + scan_spacechars(&subj->input, endtitle);
- if (gh_buf_at(subj->buffer, endall) == ')') {
+ if (peek_at(subj, endall) == ')') {
subj->pos = endall + 1;
- url = chunk_buf(subj->buffer, starturl, endurl - starturl);
- title = chunk_buf(subj->buffer, starttitle, endtitle - starttitle);
+ url = chunk_dup(&subj->input, starturl, endurl - starturl);
+ title = chunk_dup(&subj->input, starttitle, endtitle - starttitle);
lab = parse_chunk_inlines(&rawlabel, NULL);
return make_link(lab, url, title);
@@ -850,7 +806,7 @@ static inl* handle_left_bracket(subject* subj)
// Check for reference link.
// First, see if there's another label:
- subj->pos = subj->pos + scan_spacechars(subj->buffer, endlabel);
+ subj->pos = subj->pos + scan_spacechars(&subj->input, endlabel);
reflabel = rawlabel;
// if followed by a nonempty link label, we change reflabel to it:
@@ -892,8 +848,8 @@ static inl* handle_newline(subject *subj)
advance(subj);
}
if (nlpos > 1 &&
- gh_buf_at(subj->buffer, nlpos - 1) == ' ' &&
- gh_buf_at(subj->buffer, nlpos - 2) == ' ') {
+ peek_at(subj, nlpos - 1) == ' ' &&
+ peek_at(subj, nlpos - 2) == ' ') {
return make_linebreak();
} else {
return make_softbreak();
@@ -917,30 +873,22 @@ extern inl* parse_inlines_while(subject* subj, int (*f)(subject*))
inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
{
- inl *result;
subject subj;
- gh_buf full_chunk = GH_BUF_INIT;
-
- gh_buf_set(&full_chunk, chunk->data, chunk->len);
- init_subject(&subj, &full_chunk, 0, refmap);
- result = parse_inlines_while(&subj, not_eof);
-
- gh_buf_free(&full_chunk);
- return result;
+ subject_from_chunk(&subj, chunk, refmap);
+ return parse_inlines_while(&subj, not_eof);
}
-static int find_special_char(subject *subj)
+static int subject_find_special_char(subject *subj)
{
int n = subj->pos + 1;
- int size = (int)gh_buf_len(subj->buffer);
- while (n < size) {
- if (strchr("\n\\`&_*[]buffer, n)))
+ while (n < subj->input.len) {
+ if (strchr("\n\\`&_*[]input.data[n]))
return n;
n++;
}
- return -1;
+ return subj->input.len;
}
// Parse an inline, advancing subject, and add it to last element.
@@ -973,11 +921,13 @@ static int parse_inline(subject* subj, inl ** last)
new = handle_pointy_brace(subj);
break;
case '_':
- if (subj->pos > 0 && (isalnum(gh_buf_at(subj->buffer, subj->pos - 1)) ||
- gh_buf_at(subj->buffer, subj->pos - 1) == '_')) {
- new = make_str(chunk_literal("_"));
- advance(subj);
- break;
+ if (subj->pos > 0) {
+ unsigned char prev = peek_at(subj, subj->pos - 1);
+ if (isalnum(prev) || prev == '_') {
+ new = make_str(chunk_literal("_"));
+ advance(subj);
+ break;
+ }
}
new = handle_strong_emph(subj, '_');
@@ -1002,18 +952,13 @@ static int parse_inline(subject* subj, inl ** last)
}
break;
default:
- text_literal:
- endpos = find_special_char(subj);
- if (endpos < 0) {
- endpos = gh_buf_len(subj->buffer);
- }
-
- contents = chunk_buf(subj->buffer, subj->pos, endpos - subj->pos);
+ endpos = subject_find_special_char(subj);
+ contents = chunk_dup(&subj->input, subj->pos, endpos - subj->pos);
subj->pos = endpos;
// if we're at a newline, strip trailing spaces.
if (peek_char(subj) == '\n') {
- chunk_trim(&contents);
+ chunk_rtrim(&contents);
}
new = make_str(contents);
@@ -1026,10 +971,10 @@ static int parse_inline(subject* subj, inl ** last)
return 1;
}
-extern inl* parse_inlines(gh_buf *input, int input_pos, reference** refmap)
+extern inl* parse_inlines(gh_buf *input, reference** refmap)
{
subject subj;
- init_subject(&subj, input, input_pos, refmap);
+ subject_from_buf(&subj, input, refmap);
return parse_inlines_while(&subj, not_eof);
}
@@ -1048,7 +993,7 @@ void spnl(subject* subj)
// Modify refmap if a reference is encountered.
// Return 0 if no reference found, otherwise position of subject
// after reference is parsed.
-extern int parse_reference(gh_buf *input, int input_pos, reference** refmap)
+extern int parse_reference(gh_buf *input, reference** refmap)
{
subject subj;
@@ -1058,9 +1003,9 @@ extern int parse_reference(gh_buf *input, int input_pos, reference** refmap)
int matchlen = 0;
int beforetitle;
- reference * new = NULL;
+ reference *new = NULL;
- init_subject(&subj, input, input_pos, NULL);
+ subject_from_buf(&subj, input, NULL);
// parse label:
if (!link_label(&subj, &lab))
@@ -1075,9 +1020,9 @@ extern int parse_reference(gh_buf *input, int input_pos, reference** refmap)
// parse link url:
spnl(&subj);
- matchlen = scan_link_url(subj.buffer, subj.pos);
+ matchlen = scan_link_url(&subj.input, subj.pos);
if (matchlen) {
- url = chunk_buf(subj.buffer, subj.pos, matchlen);
+ url = chunk_dup(&subj.input, subj.pos, matchlen);
subj.pos += matchlen;
} else {
return 0;
@@ -1086,9 +1031,9 @@ extern int parse_reference(gh_buf *input, int input_pos, reference** refmap)
// parse optional link_title
beforetitle = subj.pos;
spnl(&subj);
- matchlen = scan_link_title(subj.buffer, subj.pos);
+ matchlen = scan_link_title(&subj.input, subj.pos);
if (matchlen) {
- title = chunk_buf(subj.buffer, subj.pos, matchlen);
+ title = chunk_dup(&subj.input, subj.pos, matchlen);
subj.pos += matchlen;
} else {
subj.pos = beforetitle;
diff --git a/src/print.c b/src/print.c
index 0a87925..c262995 100644
--- a/src/print.c
+++ b/src/print.c
@@ -9,7 +9,7 @@ static void print_str(const unsigned char *s, int len)
int i;
if (len < 0)
- len = strlen(s);
+ len = strlen((char *)s);
putchar('"');
for (i = 0; i < len; ++i) {
diff --git a/src/scanners.h b/src/scanners.h
index b6e586b..f96c42d 100644
--- a/src/scanners.h
+++ b/src/scanners.h
@@ -1,15 +1,15 @@
-#include "buffer.h"
+#include "stmd.h"
-int scan_autolink_uri(const gh_buf *s, int pos);
-int scan_autolink_email(const gh_buf *s, int pos);
-int scan_html_tag(const gh_buf *s, int pos);
-int scan_html_block_tag(const gh_buf *s, int pos);
-int scan_link_url(const gh_buf *s, int pos);
-int scan_link_title(const gh_buf *s, int pos);
-int scan_spacechars(const gh_buf *s, int pos);
-int scan_atx_header_start(const gh_buf *s, int pos);
-int scan_setext_header_line(const gh_buf *s, int pos);
-int scan_hrule(const gh_buf *s, int pos);
-int scan_open_code_fence(const gh_buf *s, int pos);
-int scan_close_code_fence(const gh_buf *s, int pos, int len);
-int scan_entity(const gh_buf *s, int pos);
+int scan_autolink_uri(chunk *c, int offset);
+int scan_autolink_email(chunk *c, int offset);
+int scan_html_tag(chunk *c, int offset);
+int scan_html_block_tag(chunk *c, int offset);
+int scan_link_url(chunk *c, int offset);
+int scan_link_title(chunk *c, int offset);
+int scan_spacechars(chunk *c, int offset);
+int scan_atx_header_start(chunk *c, int offset);
+int scan_setext_header_line(chunk *c, int offset);
+int scan_hrule(chunk *c, int offset);
+int scan_open_code_fence(chunk *c, int offset);
+int scan_close_code_fence(chunk *c, int offset, int len);
+int scan_entity(chunk *c, int offset);
diff --git a/src/scanners.re b/src/scanners.re
index 7323ef9..5ac7c15 100644
--- a/src/scanners.re
+++ b/src/scanners.re
@@ -1,8 +1,15 @@
-#include "buffer.h"
+#include "scanners.h"
+
+#define SCAN_DATA \
+ const unsigned char *marker = NULL; \
+ const unsigned char *p = c->data + offset; \
+ const unsigned char *start = p; \
+ const unsigned char *end = c->data + c->len
/*!re2c
re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = p;
+ re2c:define:YYLIMIT = end;
re2c:define:YYMARKER = marker;
re2c:define:YYCTXMARKER = marker;
re2c:yyfill:enable = 0;
@@ -55,11 +62,9 @@
*/
// Try to match URI autolink after first <, returning number of chars matched.
-extern int scan_autolink_uri(const gh_buf *s, int pos)
+extern int scan_autolink_uri(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
scheme [:]([^\x00-\x20<>\\]|escaped_char)*[>] { return (p - start); }
.? { return 0; }
@@ -67,11 +72,9 @@ extern int scan_autolink_uri(const gh_buf *s, int pos)
}
// Try to match email autolink after first <, returning num of chars matched.
-extern int scan_autolink_email(const gh_buf *s, int pos)
+extern int scan_autolink_email(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+
[@]
@@ -83,11 +86,9 @@ extern int scan_autolink_email(const gh_buf *s, int pos)
}
// Try to match an HTML tag after first <, returning num of chars matched.
-extern int scan_html_tag(const gh_buf *s, int pos)
+extern int scan_html_tag(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
htmltag { return (p - start); }
.? { return 0; }
@@ -96,11 +97,9 @@ extern int scan_html_tag(const gh_buf *s, int pos)
// Try to match an HTML block tag including first <,
// returning num of chars matched.
-extern int scan_html_block_tag(const gh_buf *s, int pos)
+extern int scan_html_block_tag(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[<] [/] blocktagname (spacechar | [>]) { return (p - start); }
[<] blocktagname (spacechar | [/>]) { return (p - start); }
@@ -113,11 +112,9 @@ extern int scan_html_block_tag(const gh_buf *s, int pos)
// This may optionally be contained in <..>; otherwise
// whitespace and unbalanced right parentheses aren't allowed.
// Newlines aren't ever allowed.
-extern int scan_link_url(const gh_buf *s, int pos)
+extern int scan_link_url(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[ \n]* [<] ([^<>\n\\\x00] | escaped_char | [\\])* [>] { return (p - start); }
[ \n]* (reg_char+ | escaped_char | in_parens_nosp)* { return (p - start); }
@@ -128,11 +125,9 @@ extern int scan_link_url(const gh_buf *s, int pos)
// Try to match a link title (in single quotes, in double quotes, or
// in parentheses), returning number of chars matched. Allow one
// level of internal nesting (quotes within quotes).
-extern int scan_link_title(const gh_buf *s, int pos)
+extern int scan_link_title(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
["] (escaped_char|[^"\x00])* ["] { return (p - start); }
['] (escaped_char|[^'\x00])* ['] { return (p - start); }
@@ -142,10 +137,9 @@ extern int scan_link_title(const gh_buf *s, int pos)
}
// Match space characters, including newlines.
-extern int scan_spacechars(const gh_buf *s, int pos)
+extern int scan_spacechars(chunk *c, int offset)
{
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[ \t\n]* { return (p - start); }
. { return 0; }
@@ -153,11 +147,9 @@ extern int scan_spacechars(const gh_buf *s, int pos)
}
// Match ATX header start.
-extern int scan_atx_header_start(const gh_buf *s, int pos)
+extern int scan_atx_header_start(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[#]{1,6} ([ ]+|[\n]) { return (p - start); }
.? { return 0; }
@@ -166,10 +158,9 @@ extern int scan_atx_header_start(const gh_buf *s, int pos)
// Match sexext header line. Return 1 for level-1 header,
// 2 for level-2, 0 for no match.
-extern int scan_setext_header_line(const gh_buf *s, int pos)
+extern int scan_setext_header_line(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
+ SCAN_DATA;
/*!re2c
[=]+ [ ]* [\n] { return 1; }
[-]+ [ ]* [\n] { return 2; }
@@ -180,11 +171,9 @@ extern int scan_setext_header_line(const gh_buf *s, int pos)
// Scan a horizontal rule line: "...three or more hyphens, asterisks,
// or underscores on a line by themselves. If you wish, you may use
// spaces between the hyphens or asterisks."
-extern int scan_hrule(const gh_buf *s, int pos)
+extern int scan_hrule(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
([*][ ]*){3,} [ \t]* [\n] { return (p - start); }
([_][ ]*){3,} [ \t]* [\n] { return (p - start); }
@@ -194,11 +183,9 @@ extern int scan_hrule(const gh_buf *s, int pos)
}
// Scan an opening code fence.
-extern int scan_open_code_fence(const gh_buf *s, int pos)
+extern int scan_open_code_fence(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[`]{3,} / [^`\n\x00]*[\n] { return (p - start); }
[~]{3,} / [^~\n\x00]*[\n] { return (p - start); }
@@ -207,11 +194,9 @@ extern int scan_open_code_fence(const gh_buf *s, int pos)
}
// Scan a closing code fence with length at least len.
-extern int scan_close_code_fence(const gh_buf *s, int pos, int len)
+extern int scan_close_code_fence(chunk *c, int offset, int len)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
([`]{3,} | [~]{3,}) / spacechar* [\n]
{ if (p - start > len) {
@@ -225,11 +210,9 @@ extern int scan_close_code_fence(const gh_buf *s, int pos, int len)
// Scans an entity.
// Returns number of chars matched.
-extern int scan_entity(const gh_buf *s, int pos)
+extern int scan_entity(chunk *c, int offset)
{
- unsigned char * marker = NULL;
- unsigned char * p = &(s->ptr[pos]);
- unsigned char * start = p;
+ SCAN_DATA;
/*!re2c
[&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]
{ return (p - start); }
diff --git a/src/stmd.h b/src/stmd.h
index 3e284bd..4a3c399 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -1,17 +1,15 @@
+#ifndef _STDMD_H_
+#define _STDMD_H_
+
#include
#include
#include "buffer.h"
+#include "chunk.h"
#include "uthash.h"
#define VERSION "0.1"
#define CODE_INDENT 4
-typedef struct {
- const unsigned char *data;
- int len;
- int alloc;
-} chunk;
-
typedef struct Inline {
enum { INL_STRING, INL_SOFTBREAK, INL_LINEBREAK, INL_CODE, INL_RAW_HTML, INL_ENTITY,
INL_EMPH, INL_STRONG, INL_LINK, INL_IMAGE } tag;
@@ -79,7 +77,6 @@ typedef struct Block {
struct Block* parent;
struct Block* top;
gh_buf string_content;
- int string_pos;
inl* inline_content;
union {
struct ListData list_data;
@@ -91,10 +88,10 @@ typedef struct Block {
struct Block * prev;
} block;
-inl* parse_inlines(gh_buf *input, int input_pos, reference** refmap);
+inl* parse_inlines(gh_buf *input, reference** refmap);
void free_inlines(inl* e);
-int parse_reference(gh_buf *input, int input_pos, reference** refmap);
+int parse_reference(gh_buf *input, reference** refmap);
void free_reference(reference *ref);
void free_reference_map(reference **refmap);
@@ -117,3 +114,4 @@ void inlines_to_html(gh_buf *html, inl *b);
void utf8proc_case_fold(gh_buf *dest, const unsigned char *str, int len);
+#endif
--
cgit v1.2.3
From 460d46c62b0675f2fab6f103bb9f0d185a73eebb Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 3 Sep 2014 03:40:53 +0200
Subject: Add chunk.h
---
src/chunk.h | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
create mode 100644 src/chunk.h
diff --git a/src/chunk.h b/src/chunk.h
new file mode 100644
index 0000000..f3841ed
--- /dev/null
+++ b/src/chunk.h
@@ -0,0 +1,92 @@
+#ifndef _CHUNK_H_
+#define _CHUNK_H_
+
+#include
+#include
+#include
+#include
+#include "buffer.h"
+
+typedef struct {
+ const unsigned char *data;
+ int len;
+ int alloc;
+} chunk;
+
+static inline void chunk_free(chunk *c)
+{
+ if (c->alloc)
+ free((char *)c->data);
+
+ c->data = NULL;
+ c->alloc = 0;
+ c->len = 0;
+}
+
+static inline void chunk_ltrim(chunk *c)
+{
+ assert(!c->alloc);
+
+ while (c->len && isspace(c->data[0])) {
+ c->data++;
+ c->len--;
+ }
+}
+
+static inline void chunk_rtrim(chunk *c)
+{
+ while (c->len > 0) {
+ if (!isspace(c->data[c->len - 1]))
+ break;
+
+ c->len--;
+ }
+}
+
+static inline void chunk_trim(chunk *c)
+{
+ chunk_ltrim(c);
+ chunk_rtrim(c);
+}
+
+static inline int chunk_strchr(chunk *ch, int c, int offset)
+{
+ const unsigned char *p = memchr(ch->data + offset, c, ch->len - offset);
+ return p ? (int)(p - ch->data) : ch->len;
+}
+
+static inline unsigned char *chunk_to_cstr(chunk *c)
+{
+ unsigned char *str;
+
+ str = malloc(c->len + 1);
+ memcpy(str, c->data, c->len);
+ str[c->len] = 0;
+
+ return str;
+}
+
+static inline chunk chunk_literal(const char *data)
+{
+ chunk c = {(const unsigned char *)data, data ? strlen(data) : 0, 0};
+ return c;
+}
+
+static inline chunk chunk_dup(const chunk *ch, int pos, int len)
+{
+ chunk c = {ch->data + pos, len, 0};
+ return c;
+}
+
+static inline chunk chunk_buf_detach(gh_buf *buf)
+{
+ chunk c;
+
+ c.len = buf->size;
+ c.data = gh_buf_detach(buf);
+ c.alloc = 1;
+
+ return c;
+}
+
+#endif
--
cgit v1.2.3
From bb6d7c4a394e61574f5f32db60da5c5f5a5e5002 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 3 Sep 2014 03:54:11 +0200
Subject: 342/99
---
src/html/html.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/src/html/html.c b/src/html/html.c
index 27ffe58..3bd5df0 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -102,9 +102,26 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
case indented_code:
case fenced_code:
- /* TODO: fenced code lang attributes */
cr(html);
- gh_buf_puts(html, "");
+
+ gh_buf_puts(html, "tag == fenced_code) {
+ gh_buf *info = &b->attributes.fenced_code_data.info;
+
+ if (gh_buf_len(info) > 0) {
+ int first_tag = gh_buf_strchr(info, ' ', 0);
+ if (first_tag < 0)
+ first_tag = gh_buf_len(info);
+
+
+ gh_buf_puts(html, " class=\"");
+ escape_html(html, info->ptr, first_tag);
+ gh_buf_putc(html, '"');
+ }
+ }
+
+ gh_buf_puts(html, ">");
escape_html(html, b->string_content.ptr, b->string_content.size);
gh_buf_puts(html, "
");
cr(html);
--
cgit v1.2.3
From f5168c63ad305b3e331eb7d31efaf46b0541bba4 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 06:41:18 +0200
Subject: 368/73
---
src/blocks.c | 1 +
src/inlines.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/blocks.c b/src/blocks.c
index 94ff986..bd25d6c 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -57,6 +57,7 @@ bool is_blank(gh_buf *s, int offset)
return true;
case ' ':
offset++;
+ break;
default:
return false;
}
diff --git a/src/inlines.c b/src/inlines.c
index ef27a24..ced4673 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -123,7 +123,7 @@ inline static inl* make_linkable(int t, inl* label, chunk url, chunk title)
e->tag = t;
e->content.linkable.label = label;
e->content.linkable.url = chunk_to_cstr(&url);
- e->content.linkable.title = url.len ? chunk_to_cstr(&title) : NULL;
+ e->content.linkable.title = title.len ? chunk_to_cstr(&title) : NULL;
e->next = NULL;
return e;
}
--
cgit v1.2.3
From 28be4a59c940bd55ed4fef668091d52638925c3c Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 15:55:27 +0200
Subject: 379/62
---
src/blocks.c | 12 ++++++++----
src/html/html.c | 1 -
src/scanners.h | 53 ++++++++++++++++++++++++++++++++++++++++-------------
src/scanners.re | 38 +++++++++++++++-----------------------
4 files changed, 63 insertions(+), 41 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index bd25d6c..cf0e9e4 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -752,11 +752,15 @@ static void incorporate_line(gh_buf *line, int line_number, block** curptr)
add_line(container, &input, offset);
} else if (container->tag == fenced_code) {
+ matched = 0;
+
+ if (indent <= 3 &&
+ peek_at(&input, first_nonspace) == container->attributes.fenced_code_data.fence_char) {
+ int fence_len = scan_close_code_fence(&input, first_nonspace);
+ if (fence_len > container->attributes.fenced_code_data.fence_length)
+ matched = 1;
+ }
- matched = (indent <= 3
- && peek_at(&input, first_nonspace) == container->attributes.fenced_code_data.fence_char)
- && scan_close_code_fence(&input, first_nonspace,
- container->attributes.fenced_code_data.fence_length);
if (matched) {
// if closing fence, don't add line to container; instead, close it:
finalize(container, line_number);
diff --git a/src/html/html.c b/src/html/html.c
index 3bd5df0..2a65a63 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -6,7 +6,6 @@
#include "stmd.h"
#include "debug.h"
-#include "scanners.h"
#include "html/houdini.h"
// Functions to convert block and inline lists to HTML strings.
diff --git a/src/scanners.h b/src/scanners.h
index f96c42d..785d424 100644
--- a/src/scanners.h
+++ b/src/scanners.h
@@ -1,15 +1,42 @@
#include "stmd.h"
-int scan_autolink_uri(chunk *c, int offset);
-int scan_autolink_email(chunk *c, int offset);
-int scan_html_tag(chunk *c, int offset);
-int scan_html_block_tag(chunk *c, int offset);
-int scan_link_url(chunk *c, int offset);
-int scan_link_title(chunk *c, int offset);
-int scan_spacechars(chunk *c, int offset);
-int scan_atx_header_start(chunk *c, int offset);
-int scan_setext_header_line(chunk *c, int offset);
-int scan_hrule(chunk *c, int offset);
-int scan_open_code_fence(chunk *c, int offset);
-int scan_close_code_fence(chunk *c, int offset, int len);
-int scan_entity(chunk *c, int offset);
+extern int _scan_autolink_uri(const unsigned char *p);
+extern int _scan_autolink_email(const unsigned char *p);
+extern int _scan_html_tag(const unsigned char *p);
+extern int _scan_html_block_tag(const unsigned char *p);
+extern int _scan_link_url(const unsigned char *p);
+extern int _scan_link_title(const unsigned char *p);
+extern int _scan_spacechars(const unsigned char *p);
+extern int _scan_atx_header_start(const unsigned char *p);
+extern int _scan_setext_header_line(const unsigned char *p);
+extern int _scan_hrule(const unsigned char *p);
+extern int _scan_open_code_fence(const unsigned char *p);
+extern int _scan_close_code_fence(const unsigned char *p);
+extern int _scan_entity(const unsigned char *p);
+
+static int scan_at(int (*scanner)(const unsigned char *), chunk *c, int offset)
+{
+ int res;
+ unsigned char *ptr = (unsigned char *)c->data;
+ unsigned char lim = ptr[c->len];
+
+ ptr[c->len] = '\0';
+ res = scanner(ptr + offset);
+ ptr[c->len] = lim;
+
+ return res;
+}
+
+#define scan_autolink_uri(c, n) scan_at(&_scan_autolink_uri, c, n)
+#define scan_autolink_email(c, n) scan_at(&_scan_autolink_email, c, n)
+#define scan_html_tag(c, n) scan_at(&_scan_html_tag, c, n)
+#define scan_html_block_tag(c, n) scan_at(&_scan_html_block_tag, c, n)
+#define scan_link_url(c, n) scan_at(&_scan_link_url, c, n)
+#define scan_link_title(c, n) scan_at(&_scan_link_title, c, n)
+#define scan_spacechars(c, n) scan_at(&_scan_spacechars, c, n)
+#define scan_atx_header_start(c, n) scan_at(&_scan_atx_header_start, c, n)
+#define scan_setext_header_line(c, n) scan_at(&_scan_setext_header_line, c, n)
+#define scan_hrule(c, n) scan_at(&_scan_hrule, c, n)
+#define scan_open_code_fence(c, n) scan_at(&_scan_open_code_fence, c, n)
+#define scan_close_code_fence(c, n) scan_at(&_scan_close_code_fence, c, n)
+#define scan_entity(c, n) scan_at(&_scan_entity, c, n)
diff --git a/src/scanners.re b/src/scanners.re
index 5ac7c15..71103f6 100644
--- a/src/scanners.re
+++ b/src/scanners.re
@@ -1,15 +1,12 @@
-#include "scanners.h"
+#include
#define SCAN_DATA \
const unsigned char *marker = NULL; \
- const unsigned char *p = c->data + offset; \
const unsigned char *start = p; \
- const unsigned char *end = c->data + c->len
/*!re2c
re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = p;
- re2c:define:YYLIMIT = end;
re2c:define:YYMARKER = marker;
re2c:define:YYCTXMARKER = marker;
re2c:yyfill:enable = 0;
@@ -62,7 +59,7 @@
*/
// Try to match URI autolink after first <, returning number of chars matched.
-extern int scan_autolink_uri(chunk *c, int offset)
+extern int _scan_autolink_uri(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -72,7 +69,7 @@ extern int scan_autolink_uri(chunk *c, int offset)
}
// Try to match email autolink after first <, returning num of chars matched.
-extern int scan_autolink_email(chunk *c, int offset)
+extern int _scan_autolink_email(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -86,7 +83,7 @@ extern int scan_autolink_email(chunk *c, int offset)
}
// Try to match an HTML tag after first <, returning num of chars matched.
-extern int scan_html_tag(chunk *c, int offset)
+extern int _scan_html_tag(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -97,7 +94,7 @@ extern int scan_html_tag(chunk *c, int offset)
// Try to match an HTML block tag including first <,
// returning num of chars matched.
-extern int scan_html_block_tag(chunk *c, int offset)
+extern int _scan_html_block_tag(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -112,7 +109,7 @@ extern int scan_html_block_tag(chunk *c, int offset)
// This may optionally be contained in <..>; otherwise
// whitespace and unbalanced right parentheses aren't allowed.
// Newlines aren't ever allowed.
-extern int scan_link_url(chunk *c, int offset)
+extern int _scan_link_url(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -125,7 +122,7 @@ extern int scan_link_url(chunk *c, int offset)
// Try to match a link title (in single quotes, in double quotes, or
// in parentheses), returning number of chars matched. Allow one
// level of internal nesting (quotes within quotes).
-extern int scan_link_title(chunk *c, int offset)
+extern int _scan_link_title(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -137,7 +134,7 @@ extern int scan_link_title(chunk *c, int offset)
}
// Match space characters, including newlines.
-extern int scan_spacechars(chunk *c, int offset)
+extern int _scan_spacechars(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -147,7 +144,7 @@ extern int scan_spacechars(chunk *c, int offset)
}
// Match ATX header start.
-extern int scan_atx_header_start(chunk *c, int offset)
+extern int _scan_atx_header_start(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -158,7 +155,7 @@ extern int scan_atx_header_start(chunk *c, int offset)
// Match sexext header line. Return 1 for level-1 header,
// 2 for level-2, 0 for no match.
-extern int scan_setext_header_line(chunk *c, int offset)
+extern int _scan_setext_header_line(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -171,7 +168,7 @@ extern int scan_setext_header_line(chunk *c, int offset)
// Scan a horizontal rule line: "...three or more hyphens, asterisks,
// or underscores on a line by themselves. If you wish, you may use
// spaces between the hyphens or asterisks."
-extern int scan_hrule(chunk *c, int offset)
+extern int _scan_hrule(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -183,7 +180,7 @@ extern int scan_hrule(chunk *c, int offset)
}
// Scan an opening code fence.
-extern int scan_open_code_fence(chunk *c, int offset)
+extern int _scan_open_code_fence(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
@@ -194,23 +191,18 @@ extern int scan_open_code_fence(chunk *c, int offset)
}
// Scan a closing code fence with length at least len.
-extern int scan_close_code_fence(chunk *c, int offset, int len)
+extern int _scan_close_code_fence(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
- ([`]{3,} | [~]{3,}) / spacechar* [\n]
- { if (p - start > len) {
- return (p - start);
- } else {
- return 0;
- } }
+ ([`]{3,} | [~]{3,}) / spacechar* [\n] { return (p - start); }
.? { return 0; }
*/
}
// Scans an entity.
// Returns number of chars matched.
-extern int scan_entity(chunk *c, int offset)
+extern int _scan_entity(const unsigned char *p)
{
SCAN_DATA;
/*!re2c
--
cgit v1.2.3
From 45c1d9fadb3e8aab4a01bb27a4e2ece379902d1a Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 17:26:11 +0200
Subject: 426/15
---
runtests.pl | 3 ++
spec.txt | 6 ++--
src/html/html.c | 22 +++++-------
src/inlines.c | 105 +++++++++++++++++++++++++++++---------------------------
4 files changed, 69 insertions(+), 67 deletions(-)
diff --git a/runtests.pl b/runtests.pl
index 2e2b795..e53938d 100644
--- a/runtests.pl
+++ b/runtests.pl
@@ -49,6 +49,7 @@ sub tidy
s/ */ /;
# collapse space before /> in tag
s/ *\/>/\/>/;
+ s/>\n$/>/;
# skip blank line
if (/^$/) {
next;
@@ -89,8 +90,10 @@ sub dotest
print $markdown;
print "=== expected ===============\n";
print $html;
+ print "\n";
print "=== got ====================\n";
print $actual;
+ print "\n";
print color "black";
return 0;
}
diff --git a/spec.txt b/spec.txt
index 82ae0b6..d7e70f5 100644
--- a/spec.txt
+++ b/spec.txt
@@ -1682,7 +1682,7 @@ them.
[Foo bar]
.
-Foo bar
+Foo bar
.
The title may be omitted:
@@ -1745,7 +1745,7 @@ case-insensitive (see [matches](#matches)).
[αγω]
.
-αγω
+αγω
.
Here is a link reference definition with no corresponding link.
@@ -3688,7 +3688,7 @@ raw HTML:
.
.
-http://google.com?find=\*
+http://google.com?find=\*
.
.
diff --git a/src/html/html.c b/src/html/html.c
index 2a65a63..cdccf2a 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -50,17 +50,15 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
cr(html);
gh_buf_puts(html, "");
inlines_to_html(html, b->inline_content);
- gh_buf_puts(html, "
");
- cr(html);
+ gh_buf_puts(html, "
\n");
}
break;
case block_quote:
cr(html);
- gh_buf_puts(html, "");
+ gh_buf_puts(html, "\n");
blocks_to_html(html, b->children, false);
- gh_buf_puts(html, "
");
- cr(html);
+ gh_buf_puts(html, "
\n");
break;
case list_item:
@@ -68,8 +66,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
gh_buf_puts(html, "");
blocks_to_html(html, b->children, tight);
gh_buf_trim(html); /* TODO: rtrim */
- gh_buf_puts(html, "");
- cr(html);
+ gh_buf_puts(html, "\n");
break;
case list:
@@ -87,7 +84,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
blocks_to_html(html, b->children, data->tight);
gh_buf_puts(html, data->list_type == bullet ? "" : "");
- cr(html);
+ gh_buf_putc(html, '\n');
break;
case atx_header:
@@ -95,8 +92,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
cr(html);
gh_buf_printf(html, "", b->attributes.header_level);
inlines_to_html(html, b->inline_content);
- gh_buf_printf(html, "", b->attributes.header_level);
- cr(html);
+ gh_buf_printf(html, "\n", b->attributes.header_level);
break;
case indented_code:
@@ -122,8 +118,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
gh_buf_puts(html, ">");
escape_html(html, b->string_content.ptr, b->string_content.size);
- gh_buf_puts(html, "
");
- cr(html);
+ gh_buf_puts(html, "\n");
break;
case html_block:
@@ -131,8 +126,7 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
break;
case hrule:
- gh_buf_puts(html, "
");
- cr(html);
+ gh_buf_puts(html, "
\n");
break;
case reference_def:
diff --git a/src/inlines.c b/src/inlines.c
index ced4673..a0dcac9 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -1,8 +1,8 @@
#include
+#include
#include
#include
#include
-#include
#include "stmd.h"
#include "uthash.h"
@@ -18,7 +18,7 @@ typedef struct Subject {
reference* lookup_reference(reference** refmap, chunk *label);
reference* make_reference(chunk *label, chunk *url, chunk *title);
-static unsigned char *clean_url(chunk *url);
+static unsigned char *clean_url(chunk *url, int is_email);
static unsigned char *clean_title(chunk *title);
inline static unsigned char *chunk_to_cstr(chunk *c);
@@ -97,7 +97,7 @@ extern reference* make_reference(chunk *label, chunk *url, chunk *title)
reference *ref;
ref = malloc(sizeof(reference));
ref->label = normalize_reference(label);
- ref->url = clean_url(url);
+ ref->url = clean_url(url, 0);
ref->title = clean_title(title);
return ref;
}
@@ -116,14 +116,25 @@ extern void add_reference(reference** refmap, reference* ref)
}
}
+inline static inl* make_link_from_reference(inl* label, reference *ref)
+{
+ inl* e = (inl*) malloc(sizeof(inl));
+ e->tag = INL_LINK;
+ e->content.linkable.label = label;
+ e->content.linkable.url = strdup(ref->url);
+ e->content.linkable.title = ref->title ? strdup(ref->title) : NULL;
+ e->next = NULL;
+ return e;
+}
+
// Create an inline with a linkable string value.
-inline static inl* make_linkable(int t, inl* label, chunk url, chunk title)
+inline static inl* make_link(inl* label, chunk url, chunk title, int is_email)
{
inl* e = (inl*) malloc(sizeof(inl));
- e->tag = t;
+ e->tag = INL_LINK;
e->content.linkable.label = label;
- e->content.linkable.url = chunk_to_cstr(&url);
- e->content.linkable.title = title.len ? chunk_to_cstr(&title) : NULL;
+ e->content.linkable.url = clean_url(&url, is_email);
+ e->content.linkable.title = clean_title(&title);
e->next = NULL;
return e;
}
@@ -163,7 +174,6 @@ inline static inl* make_simple(int t)
#define make_entity(s) make_literal(INL_ENTITY, s)
#define make_linebreak() make_simple(INL_LINEBREAK)
#define make_softbreak() make_simple(INL_SOFTBREAK)
-#define make_link(label, url, title) make_linkable(INL_LINK, label, url, title)
#define make_emph(contents) make_inlines(INL_EMPH, contents)
#define make_strong(contents) make_inlines(INL_STRONG, contents)
@@ -309,37 +319,27 @@ static int scan_to_closing_backticks(subject* subj, int openticklength)
// space and newline characters into a single space.
static void normalize_whitespace(gh_buf *s)
{
- /* TODO */
-#if 0
bool last_char_was_space = false;
- int pos = 0;
- char c;
- while ((c = gh_buf_at(s, pos))) {
- switch (c) {
- case ' ':
- if (last_char_was_space) {
- bdelete(s, pos, 1);
- } else {
- pos++;
- }
- last_char_was_space = true;
- break;
- case '\n':
- if (last_char_was_space) {
- bdelete(s, pos, 1);
- } else {
- bdelete(s, pos, 1);
- binsertch(s, pos, 1, ' ');
- pos++;
- }
- last_char_was_space = true;
+ int r, w;
+
+ for (r = 0, w = 0; r < s->size; ++r) {
+ switch (s->ptr[r]) {
+ case ' ':
+ case '\n':
+ if (last_char_was_space)
break;
- default:
- pos++;
- last_char_was_space = false;
+
+ s->ptr[w++] = ' ';
+ last_char_was_space = true;
+ break;
+
+ default:
+ s->ptr[w++] = s->ptr[r];
+ last_char_was_space = false;
}
}
-#endif
+
+ gh_buf_truncate(s, w);
}
// Parse backtick code section or raw backticks, return an inline.
@@ -593,16 +593,19 @@ extern void unescape_buffer(gh_buf *buf)
// Clean a URL: remove surrounding whitespace and surrounding <>,
// and remove \ that escape punctuation.
-static unsigned char *clean_url(chunk *url)
+static unsigned char *clean_url(chunk *url, int is_email)
{
gh_buf buf = GH_BUF_INIT;
chunk_trim(url);
+ if (is_email)
+ gh_buf_puts(&buf, "mailto:");
+
if (url->data[0] == '<' && url->data[url->len - 1] == '>') {
- gh_buf_set(&buf, url->data + 1, url->len - 2);
+ gh_buf_put(&buf, url->data + 1, url->len - 2);
} else {
- gh_buf_set(&buf, url->data, url->len);
+ gh_buf_put(&buf, url->data, url->len);
}
unescape_buffer(&buf);
@@ -613,8 +616,13 @@ static unsigned char *clean_url(chunk *url)
static unsigned char *clean_title(chunk *title)
{
gh_buf buf = GH_BUF_INIT;
- unsigned char first = title->data[0];
- unsigned char last = title->data[title->len - 1];
+ unsigned char first, last;
+
+ if (title->len == 0)
+ return NULL;
+
+ first = title->data[0];
+ last = title->data[title->len - 1];
// remove surrounding quotes if any:
if ((first == '\'' && last == '\'') ||
@@ -647,25 +655,22 @@ static inl* handle_pointy_brace(subject* subj)
return make_link(
make_str_with_entities(&contents),
contents,
- chunk_literal("")
+ chunk_literal(""),
+ 0
);
}
// next try to match an email autolink
matchlen = scan_autolink_email(&subj->input, subj->pos);
if (matchlen > 0) {
- gh_buf mail_url = GH_BUF_INIT;
-
contents = chunk_dup(&subj->input, subj->pos, matchlen - 1);
subj->pos += matchlen;
- gh_buf_puts(&mail_url, "mailto:");
- gh_buf_put(&mail_url, contents.data, contents.len);
-
return make_link(
make_str_with_entities(&contents),
- chunk_buf_detach(&mail_url),
- chunk_literal("")
+ contents,
+ chunk_literal(""),
+ 1
);
}
@@ -790,7 +795,7 @@ static inl* handle_left_bracket(subject* subj)
title = chunk_dup(&subj->input, starttitle, endtitle - starttitle);
lab = parse_chunk_inlines(&rawlabel, NULL);
- return make_link(lab, url, title);
+ return make_link(lab, url, title, 0);
} else {
// if we get here, we matched a label but didn't get further:
subj->pos = endlabel;
@@ -821,7 +826,7 @@ static inl* handle_left_bracket(subject* subj)
ref = lookup_reference(subj->reference_map, &reflabel);
if (ref != NULL) { // found
lab = parse_chunk_inlines(&rawlabel, NULL);
- result = make_link(lab, chunk_literal(ref->url), chunk_literal(ref->title));
+ result = make_link_from_reference(lab, ref);
} else {
subj->pos = endlabel;
lab = parse_chunk_inlines(&rawlabel, subj->reference_map);
--
cgit v1.2.3
From 9830d3a05a374a0d05676301bd4065917b59ad53 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 17:42:12 +0200
Subject: 430/11
---
src/html/houdini_html_e.c | 4 ++--
src/html/html.c | 5 ++---
src/inlines.c | 14 +++-----------
3 files changed, 7 insertions(+), 16 deletions(-)
diff --git a/src/html/houdini_html_e.c b/src/html/houdini_html_e.c
index 5cdd3dd..95b6c41 100644
--- a/src/html/houdini_html_e.c
+++ b/src/html/houdini_html_e.c
@@ -62,8 +62,8 @@ houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
break;
/* The forward slash is only escaped in secure mode */
- if (src[i] == '/' && !secure) {
- gh_buf_putc(ob, '/');
+ if ((src[i] == '/' || src[i] == '\'') && !secure) {
+ gh_buf_putc(ob, src[i]);
} else {
gh_buf_puts(ob, HTML_ESCAPES[esc]);
}
diff --git a/src/html/html.c b/src/html/html.c
index cdccf2a..913a602 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -191,10 +191,9 @@ void inlines_to_html(gh_buf *html, inl* ils)
escape_href(html, ils->content.linkable.url, -1);
inlines_to_html(&scrap, ils->content.inlines);
- if (scrap.size) {
- gh_buf_puts(html, "\" alt=\"");
+ gh_buf_puts(html, "\" alt=\"");
+ if (scrap.size)
escape_html(html, scrap.ptr, scrap.size);
- }
gh_buf_clear(&scrap);
if (ils->content.linkable.title) {
diff --git a/src/inlines.c b/src/inlines.c
index a0dcac9..599be84 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -21,7 +21,6 @@ reference* make_reference(chunk *label, chunk *url, chunk *title);
static unsigned char *clean_url(chunk *url, int is_email);
static unsigned char *clean_title(chunk *title);
-inline static unsigned char *chunk_to_cstr(chunk *c);
inline static void chunk_free(chunk *c);
inline static void chunk_trim(chunk *c);
@@ -37,6 +36,8 @@ static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap);
static void subject_from_buf(subject *e, gh_buf *buffer, reference** refmap);
static int subject_find_special_char(subject *subj);
+static void normalize_whitespace(gh_buf *s);
+
extern void free_reference(reference *ref) {
free(ref->label);
free(ref->url);
@@ -62,19 +63,10 @@ extern void free_reference_map(reference **refmap) {
static unsigned char *normalize_reference(chunk *ref)
{
gh_buf normalized = GH_BUF_INIT;
- int r, w;
utf8proc_case_fold(&normalized, ref->data, ref->len);
gh_buf_trim(&normalized);
-
- for (r = 0, w = 0; r < normalized.size; ++r) {
- if (r && gh_buf_at(&normalized, r - 1) == ' ') {
- while (gh_buf_at(&normalized, r) == ' ')
- r++;
- }
-
- normalized.ptr[w++] = normalized.ptr[r];
- }
+ normalize_whitespace(&normalized);
return gh_buf_detach(&normalized);
}
--
cgit v1.2.3
From d8f44f1e4f0bd944ab43e6434a1579d670ed66cf Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 17:49:13 +0200
Subject: 433/8
---
spec.txt | 2 +-
src/html/html.c | 6 ++++--
src/inlines.c | 3 +++
src/print.c | 5 ++++-
4 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/spec.txt b/spec.txt
index d7e70f5..cfda2a3 100644
--- a/spec.txt
+++ b/spec.txt
@@ -3946,7 +3946,7 @@ But this is a link:
.
`
.
-http://foo.bar.`baz`
+http://foo.bar.`baz`
.
And this is an HTML tag:
diff --git a/src/html/html.c b/src/html/html.c
index 913a602..41b8fda 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -174,7 +174,8 @@ void inlines_to_html(gh_buf *html, inl* ils)
case INL_LINK:
gh_buf_puts(html, "content.linkable.url, -1);
+ if (ils->content.linkable.url)
+ escape_href(html, ils->content.linkable.url, -1);
if (ils->content.linkable.title) {
gh_buf_puts(html, "\" title=\"");
@@ -188,7 +189,8 @@ void inlines_to_html(gh_buf *html, inl* ils)
case INL_IMAGE:
gh_buf_puts(html, "content.linkable.url, -1);
+ if (ils->content.linkable.url)
+ escape_href(html, ils->content.linkable.url, -1);
inlines_to_html(&scrap, ils->content.inlines);
gh_buf_puts(html, "\" alt=\"");
diff --git a/src/inlines.c b/src/inlines.c
index 599be84..8e2e683 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -591,6 +591,9 @@ static unsigned char *clean_url(chunk *url, int is_email)
chunk_trim(url);
+ if (url->len == 0)
+ return NULL;
+
if (is_email)
gh_buf_puts(&buf, "mailto:");
diff --git a/src/print.c b/src/print.c
index c262995..832ad4f 100644
--- a/src/print.c
+++ b/src/print.c
@@ -153,7 +153,10 @@ extern void print_inlines(inl* ils, int indent)
case INL_LINK:
case INL_IMAGE:
printf("%s url=", ils->tag == INL_LINK ? "link" : "image");
- print_str(ils->content.linkable.url, -1);
+
+ if (ils->content.linkable.url)
+ print_str(ils->content.linkable.url, -1);
+
if (ils->content.linkable.title) {
printf(" title=");
print_str(ils->content.linkable.title, -1);
--
cgit v1.2.3
From 38220c56c9a888a0c00ff22fb82ba156fec1f6a8 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 17:54:37 +0200
Subject: 5 failed
---
spec.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/spec.txt b/spec.txt
index cfda2a3..a353d56 100644
--- a/spec.txt
+++ b/spec.txt
@@ -3688,7 +3688,7 @@ raw HTML:
.
.
-http://google.com?find=\*
+http://google.com?find=\*
.
.
@@ -4755,7 +4755,7 @@ braces:
.
[link]()
.
-link
+link
.
The destination cannot contain line breaks, even with pointy braces:
@@ -4821,7 +4821,7 @@ get unexpected results:
.
[link]("title")
.
-link
+link
.
Titles may be in single quotes, double quotes, or parentheses:
--
cgit v1.2.3
From 3ec98f55bd78572195f355a2ccb891df1c91b798 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 18:11:40 +0200
Subject: Default Makefile settings
---
Makefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 89ec68c..ed4ddd5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=-ggdb3 -O0 -Wall -Wextra -Wno-unused-variable -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-ggdb3 -O0 -Wall -Wno-unused-variable # -Werror
+CFLAGS=-g -O3 -Wall -Wextra -Wno-unused-variable -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS=-g -O3 -Wall -Wno-unused-variable # -Werror
SRCDIR=src
DATADIR=data
--
cgit v1.2.3
From 543c2c94d71adee42c7bd2f8027d75c87ed8120d Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 18:38:14 +0200
Subject: Rename to strbuf
---
src/blocks.c | 64 +++++++++++++++----------------
src/buffer.c | 86 ++++++++++++++++++++---------------------
src/buffer.h | 80 +++++++++++++++++++-------------------
src/chunk.h | 4 +-
src/html/houdini.h | 22 +++++------
src/html/houdini_href_e.c | 12 +++---
src/html/houdini_html_e.c | 10 ++---
src/html/html.c | 98 +++++++++++++++++++++++------------------------
src/inlines.c | 50 ++++++++++++------------
src/main.c | 4 +-
src/stmd.h | 16 ++++----
src/utf8.c | 6 +--
12 files changed, 226 insertions(+), 226 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index cf0e9e4..9faccd9 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -10,7 +10,7 @@
#define peek_at(i, n) (i)->data[n]
-static void incorporate_line(gh_buf *ln, int line_number, block** curptr);
+static void incorporate_line(strbuf *ln, int line_number, block** curptr);
static void finalize(block* b, int line_number);
static block* make_block(int tag, int start_line, int start_column)
@@ -28,7 +28,7 @@ static block* make_block(int tag, int start_line, int start_column)
e->parent = NULL;
e->top = NULL;
e->attributes.refmap = NULL;
- gh_buf_init(&e->string_content, 32);
+ strbuf_init(&e->string_content, 32);
e->inline_content = NULL;
e->next = NULL;
e->prev = NULL;
@@ -49,7 +49,7 @@ extern block* make_document()
}
// Returns true if line has only space characters, else false.
-bool is_blank(gh_buf *s, int offset)
+bool is_blank(strbuf *s, int offset)
{
while (offset < s->size) {
switch (s->ptr[offset]) {
@@ -85,10 +85,10 @@ static inline bool accepts_lines(int block_type)
static void add_line(block* block, chunk *ch, int offset)
{
assert(block->open);
- gh_buf_put(&block->string_content, ch->data + offset, ch->len - offset);
+ strbuf_put(&block->string_content, ch->data + offset, ch->len - offset);
}
-static void remove_trailing_blank_lines(gh_buf *ln)
+static void remove_trailing_blank_lines(strbuf *ln)
{
int i;
@@ -100,13 +100,13 @@ static void remove_trailing_blank_lines(gh_buf *ln)
}
if (i < 0) {
- gh_buf_clear(ln);
+ strbuf_clear(ln);
return;
}
- i = gh_buf_strchr(ln, '\n', i);
+ i = strbuf_strchr(ln, '\n', i);
if (i >= 0)
- gh_buf_truncate(ln, i);
+ strbuf_truncate(ln, i);
}
// Check to see if a block ends with a blank line, descending
@@ -164,10 +164,10 @@ static void finalize(block* b, int line_number)
switch (b->tag) {
case paragraph:
pos = 0;
- while (gh_buf_at(&b->string_content, 0) == '[' &&
+ while (strbuf_at(&b->string_content, 0) == '[' &&
(pos = parse_reference(&b->string_content, b->top->attributes.refmap))) {
- gh_buf_drop(&b->string_content, pos);
+ strbuf_drop(&b->string_content, pos);
}
if (is_blank(&b->string_content, 0)) {
b->tag = reference_def;
@@ -176,23 +176,23 @@ static void finalize(block* b, int line_number)
case indented_code:
remove_trailing_blank_lines(&b->string_content);
- gh_buf_putc(&b->string_content, '\n');
+ strbuf_putc(&b->string_content, '\n');
break;
case fenced_code:
// first line of contents becomes info
- firstlinelen = gh_buf_strchr(&b->string_content, '\n', 0);
+ firstlinelen = strbuf_strchr(&b->string_content, '\n', 0);
- gh_buf_init(&b->attributes.fenced_code_data.info, 0);
- gh_buf_set(
+ strbuf_init(&b->attributes.fenced_code_data.info, 0);
+ strbuf_set(
&b->attributes.fenced_code_data.info,
b->string_content.ptr,
firstlinelen
);
- gh_buf_drop(&b->string_content, firstlinelen + 1);
+ strbuf_drop(&b->string_content, firstlinelen + 1);
- gh_buf_trim(&b->attributes.fenced_code_data.info);
+ strbuf_trim(&b->attributes.fenced_code_data.info);
unescape_buffer(&b->attributes.fenced_code_data.info);
break;
@@ -265,9 +265,9 @@ extern void free_blocks(block* e)
while (e != NULL) {
next = e->next;
free_inlines(e->inline_content);
- gh_buf_free(&e->string_content);
+ strbuf_free(&e->string_content);
if (e->tag == fenced_code) {
- gh_buf_free(&e->attributes.fenced_code_data.info);
+ strbuf_free(&e->attributes.fenced_code_data.info);
} else if (e->tag == document) {
free_reference_map(e->attributes.refmap);
}
@@ -287,7 +287,7 @@ void process_inlines(block* cur, reference** refmap)
case setext_header:
cur->inline_content = parse_inlines(&cur->string_content, refmap);
// MEM
- // gh_buf_free(&cur->string_content);
+ // strbuf_free(&cur->string_content);
break;
default:
@@ -369,7 +369,7 @@ static int lists_match(struct ListData list_data,
list_data.bullet_char == item_data.bullet_char);
}
-static void expand_tabs(gh_buf *ob, const unsigned char *line, size_t size)
+static void expand_tabs(strbuf *ob, const unsigned char *line, size_t size)
{
size_t i = 0, tab = 0;
@@ -381,13 +381,13 @@ static void expand_tabs(gh_buf *ob, const unsigned char *line, size_t size)
}
if (i > org)
- gh_buf_put(ob, line + org, i - org);
+ strbuf_put(ob, line + org, i - org);
if (i >= size)
break;
do {
- gh_buf_putc(ob, ' '); tab++;
+ strbuf_putc(ob, ' '); tab++;
} while (tab % 4);
i++;
@@ -409,7 +409,7 @@ static block *finalize_document(block *document, int linenum)
extern block *stmd_parse_file(FILE *f)
{
- gh_buf line = GH_BUF_INIT;
+ strbuf line = GH_BUF_INIT;
unsigned char buffer[4096];
int linenum = 1;
block *document = make_document();
@@ -417,17 +417,17 @@ extern block *stmd_parse_file(FILE *f)
while (fgets((char *)buffer, sizeof(buffer), f)) {
expand_tabs(&line, buffer, strlen((char *)buffer));
incorporate_line(&line, linenum, &document);
- gh_buf_clear(&line);
+ strbuf_clear(&line);
linenum++;
}
- gh_buf_free(&line);
+ strbuf_free(&line);
return finalize_document(document, linenum);
}
extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
{
- gh_buf line = GH_BUF_INIT;
+ strbuf line = GH_BUF_INIT;
int linenum = 1;
const unsigned char *end = buffer + len;
block *document = make_document();
@@ -444,11 +444,11 @@ extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
}
incorporate_line(&line, linenum, &document);
- gh_buf_clear(&line);
+ strbuf_clear(&line);
linenum++;
}
- gh_buf_free(&line);
+ strbuf_free(&line);
return finalize_document(document, linenum);
}
@@ -471,7 +471,7 @@ static void chop_trailing_hashtags(chunk *ch)
}
// Process one line at a time, modifying a block.
-static void incorporate_line(gh_buf *line, int line_number, block** curptr)
+static void incorporate_line(strbuf *line, int line_number, block** curptr)
{
block* last_matched_container;
int offset = 0;
@@ -639,8 +639,8 @@ static void incorporate_line(gh_buf *line, int line_number, block** curptr)
} else if (container->tag == paragraph &&
(lev = scan_setext_header_line(&input, first_nonspace)) &&
// check that there is only one line in the paragraph:
- gh_buf_strrchr(&container->string_content, '\n',
- gh_buf_len(&container->string_content) - 2) < 0) {
+ strbuf_strrchr(&container->string_content, '\n',
+ strbuf_len(&container->string_content) - 2) < 0) {
container->tag = setext_header;
container->attributes.header_level = lev;
@@ -734,7 +734,7 @@ static void incorporate_line(gh_buf *line, int line_number, block** curptr)
container == last_matched_container &&
!blank &&
cur->tag == paragraph &&
- gh_buf_len(&cur->string_content) > 0) {
+ strbuf_len(&cur->string_content) > 0) {
add_line(cur, &input, offset);
diff --git a/src/buffer.c b/src/buffer.c
index dc4a405..90c2186 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -9,32 +9,32 @@
#include "buffer.h"
-/* Used as default value for gh_buf->ptr so that people can always
- * assume ptr is non-NULL and zero terminated even for new gh_bufs.
+/* Used as default value for strbuf->ptr so that people can always
+ * assume ptr is non-NULL and zero terminated even for new strbufs.
*/
-unsigned char gh_buf__initbuf[1];
-unsigned char gh_buf__oom[1];
+unsigned char strbuf__initbuf[1];
+unsigned char strbuf__oom[1];
#define ENSURE_SIZE(b, d) \
- if ((d) > buf->asize && gh_buf_grow(b, (d)) < 0)\
+ if ((d) > buf->asize && strbuf_grow(b, (d)) < 0)\
return -1;
-void gh_buf_init(gh_buf *buf, int initial_size)
+void strbuf_init(strbuf *buf, int initial_size)
{
buf->asize = 0;
buf->size = 0;
- buf->ptr = gh_buf__initbuf;
+ buf->ptr = strbuf__initbuf;
if (initial_size)
- gh_buf_grow(buf, initial_size);
+ strbuf_grow(buf, initial_size);
}
-int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom)
+int strbuf_try_grow(strbuf *buf, int target_size, bool mark_oom)
{
unsigned char *new_ptr;
int new_size;
- if (buf->ptr == gh_buf__oom)
+ if (buf->ptr == strbuf__oom)
return -1;
if (target_size <= buf->asize)
@@ -60,7 +60,7 @@ int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom)
if (!new_ptr) {
if (mark_oom)
- buf->ptr = gh_buf__oom;
+ buf->ptr = strbuf__oom;
return -1;
}
@@ -75,17 +75,17 @@ int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom)
return 0;
}
-void gh_buf_free(gh_buf *buf)
+void strbuf_free(strbuf *buf)
{
if (!buf) return;
- if (buf->ptr != gh_buf__initbuf && buf->ptr != gh_buf__oom)
+ if (buf->ptr != strbuf__initbuf && buf->ptr != strbuf__oom)
free(buf->ptr);
- gh_buf_init(buf, 0);
+ strbuf_init(buf, 0);
}
-void gh_buf_clear(gh_buf *buf)
+void strbuf_clear(strbuf *buf)
{
buf->size = 0;
@@ -93,10 +93,10 @@ void gh_buf_clear(gh_buf *buf)
buf->ptr[0] = '\0';
}
-int gh_buf_set(gh_buf *buf, const unsigned char *data, int len)
+int strbuf_set(strbuf *buf, const unsigned char *data, int len)
{
if (len <= 0 || data == NULL) {
- gh_buf_clear(buf);
+ strbuf_clear(buf);
} else {
if (data != buf->ptr) {
ENSURE_SIZE(buf, len + 1);
@@ -108,14 +108,14 @@ int gh_buf_set(gh_buf *buf, const unsigned char *data, int len)
return 0;
}
-int gh_buf_sets(gh_buf *buf, const char *string)
+int strbuf_sets(strbuf *buf, const char *string)
{
- return gh_buf_set(buf,
+ return strbuf_set(buf,
(const unsigned char *)string,
string ? strlen(string) : 0);
}
-int gh_buf_putc(gh_buf *buf, int c)
+int strbuf_putc(strbuf *buf, int c)
{
ENSURE_SIZE(buf, buf->size + 2);
buf->ptr[buf->size++] = c;
@@ -123,7 +123,7 @@ int gh_buf_putc(gh_buf *buf, int c)
return 0;
}
-int gh_buf_put(gh_buf *buf, const unsigned char *data, int len)
+int strbuf_put(strbuf *buf, const unsigned char *data, int len)
{
if (len <= 0)
return 0;
@@ -135,12 +135,12 @@ int gh_buf_put(gh_buf *buf, const unsigned char *data, int len)
return 0;
}
-int gh_buf_puts(gh_buf *buf, const char *string)
+int strbuf_puts(strbuf *buf, const char *string)
{
- return gh_buf_put(buf, (const unsigned char *)string, strlen(string));
+ return strbuf_put(buf, (const unsigned char *)string, strlen(string));
}
-int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap)
+int strbuf_vprintf(strbuf *buf, const char *format, va_list ap)
{
const int expected_size = buf->size + (strlen(format) * 2);
int len;
@@ -159,7 +159,7 @@ int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap)
if (len < 0) {
free(buf->ptr);
- buf->ptr = gh_buf__oom;
+ buf->ptr = strbuf__oom;
return -1;
}
@@ -174,19 +174,19 @@ int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap)
return 0;
}
-int gh_buf_printf(gh_buf *buf, const char *format, ...)
+int strbuf_printf(strbuf *buf, const char *format, ...)
{
int r;
va_list ap;
va_start(ap, format);
- r = gh_buf_vprintf(buf, format, ap);
+ r = strbuf_vprintf(buf, format, ap);
va_end(ap);
return r;
}
-void gh_buf_copy_cstr(char *data, int datasize, const gh_buf *buf)
+void strbuf_copy_cstr(char *data, int datasize, const strbuf *buf)
{
int copylen;
@@ -204,28 +204,28 @@ void gh_buf_copy_cstr(char *data, int datasize, const gh_buf *buf)
data[copylen] = '\0';
}
-void gh_buf_swap(gh_buf *buf_a, gh_buf *buf_b)
+void strbuf_swap(strbuf *buf_a, strbuf *buf_b)
{
- gh_buf t = *buf_a;
+ strbuf t = *buf_a;
*buf_a = *buf_b;
*buf_b = t;
}
-unsigned char *gh_buf_detach(gh_buf *buf)
+unsigned char *strbuf_detach(strbuf *buf)
{
unsigned char *data = buf->ptr;
- if (buf->asize == 0 || buf->ptr == gh_buf__oom)
+ if (buf->asize == 0 || buf->ptr == strbuf__oom)
return NULL;
- gh_buf_init(buf, 0);
+ strbuf_init(buf, 0);
return data;
}
-void gh_buf_attach(gh_buf *buf, unsigned char *ptr, int asize)
+void strbuf_attach(strbuf *buf, unsigned char *ptr, int asize)
{
- gh_buf_free(buf);
+ strbuf_free(buf);
if (ptr) {
buf->ptr = ptr;
@@ -235,18 +235,18 @@ void gh_buf_attach(gh_buf *buf, unsigned char *ptr, int asize)
else /* pass 0 to fall back on strlen + 1 */
buf->asize = buf->size + 1;
} else {
- gh_buf_grow(buf, asize);
+ strbuf_grow(buf, asize);
}
}
-int gh_buf_cmp(const gh_buf *a, const gh_buf *b)
+int strbuf_cmp(const strbuf *a, const strbuf *b)
{
int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size));
return (result != 0) ? result :
(a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
}
-int gh_buf_strchr(const gh_buf *buf, int c, int pos)
+int strbuf_strchr(const strbuf *buf, int c, int pos)
{
const unsigned char *p = memchr(buf->ptr + pos, c, buf->size - pos);
if (!p)
@@ -255,7 +255,7 @@ int gh_buf_strchr(const gh_buf *buf, int c, int pos)
return (int)(p - (const unsigned char *)buf->ptr);
}
-int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
+int strbuf_strrchr(const strbuf *buf, int c, int pos)
{
int i;
@@ -267,7 +267,7 @@ int gh_buf_strrchr(const gh_buf *buf, int c, int pos)
return -1;
}
-void gh_buf_truncate(gh_buf *buf, int len)
+void strbuf_truncate(strbuf *buf, int len)
{
if (len < buf->size) {
buf->size = len;
@@ -275,7 +275,7 @@ void gh_buf_truncate(gh_buf *buf, int len)
}
}
-void gh_buf_drop(gh_buf *buf, int n)
+void strbuf_drop(strbuf *buf, int n)
{
if (n > 0) {
buf->size = buf->size - n;
@@ -286,7 +286,7 @@ void gh_buf_drop(gh_buf *buf, int n)
}
}
-void gh_buf_trim(gh_buf *buf)
+void strbuf_trim(strbuf *buf)
{
int i = 0;
@@ -296,7 +296,7 @@ void gh_buf_trim(gh_buf *buf)
while (i < buf->size && isspace(buf->ptr[i]))
i++;
- gh_buf_drop(buf, i);
+ strbuf_drop(buf, i);
/* rtrim */
while (buf->size > 0) {
diff --git a/src/buffer.h b/src/buffer.h
index 0d5143e..6f45cbb 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -9,20 +9,20 @@
typedef struct {
unsigned char *ptr;
int asize, size;
-} gh_buf;
+} strbuf;
-extern unsigned char gh_buf__initbuf[];
-extern unsigned char gh_buf__oom[];
+extern unsigned char strbuf__initbuf[];
+extern unsigned char strbuf__oom[];
-#define GH_BUF_INIT { gh_buf__initbuf, 0, 0 }
+#define GH_BUF_INIT { strbuf__initbuf, 0, 0 }
/**
- * Initialize a gh_buf structure.
+ * Initialize a strbuf structure.
*
* For the cases where GH_BUF_INIT cannot be used to do static
* initialization.
*/
-extern void gh_buf_init(gh_buf *buf, int initial_size);
+extern void strbuf_init(strbuf *buf, int initial_size);
/**
* Attempt to grow the buffer to hold at least `target_size` bytes.
@@ -32,7 +32,7 @@ extern void gh_buf_init(gh_buf *buf, int initial_size);
* existing buffer content will be preserved, but calling code must handle
* that buffer was not expanded.
*/
-extern int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom);
+extern int strbuf_try_grow(strbuf *buf, int target_size, bool mark_oom);
/**
* Grow the buffer to hold at least `target_size` bytes.
@@ -42,71 +42,71 @@ extern int gh_buf_try_grow(gh_buf *buf, int target_size, bool mark_oom);
*
* @return 0 on success or -1 on failure
*/
-static inline int gh_buf_grow(gh_buf *buf, int target_size)
+static inline int strbuf_grow(strbuf *buf, int target_size)
{
- return gh_buf_try_grow(buf, target_size, true);
+ return strbuf_try_grow(buf, target_size, true);
}
-extern void gh_buf_free(gh_buf *buf);
-extern void gh_buf_swap(gh_buf *buf_a, gh_buf *buf_b);
+extern void strbuf_free(strbuf *buf);
+extern void strbuf_swap(strbuf *buf_a, strbuf *buf_b);
/**
- * Test if there have been any reallocation failures with this gh_buf.
+ * Test if there have been any reallocation failures with this strbuf.
*
- * Any function that writes to a gh_buf can fail due to memory allocation
- * issues. If one fails, the gh_buf will be marked with an OOM error and
- * further calls to modify the buffer will fail. Check gh_buf_oom() at the
+ * Any function that writes to a strbuf can fail due to memory allocation
+ * issues. If one fails, the strbuf will be marked with an OOM error and
+ * further calls to modify the buffer will fail. Check strbuf_oom() at the
* end of your sequence and it will be true if you ran out of memory at any
* point with that buffer.
*
* @return false if no error, true if allocation error
*/
-static inline bool gh_buf_oom(const gh_buf *buf)
+static inline bool strbuf_oom(const strbuf *buf)
{
- return (buf->ptr == gh_buf__oom);
+ return (buf->ptr == strbuf__oom);
}
-static inline size_t gh_buf_len(const gh_buf *buf)
+static inline size_t strbuf_len(const strbuf *buf)
{
return buf->size;
}
-extern int gh_buf_cmp(const gh_buf *a, const gh_buf *b);
+extern int strbuf_cmp(const strbuf *a, const strbuf *b);
-extern void gh_buf_attach(gh_buf *buf, unsigned char *ptr, int asize);
-extern unsigned char *gh_buf_detach(gh_buf *buf);
-extern void gh_buf_copy_cstr(char *data, int datasize, const gh_buf *buf);
+extern void strbuf_attach(strbuf *buf, unsigned char *ptr, int asize);
+extern unsigned char *strbuf_detach(strbuf *buf);
+extern void strbuf_copy_cstr(char *data, int datasize, const strbuf *buf);
-static inline const char *gh_buf_cstr(const gh_buf *buf)
+static inline const char *strbuf_cstr(const strbuf *buf)
{
return (char *)buf->ptr;
}
-#define gh_buf_at(buf, n) ((buf)->ptr[n])
+#define strbuf_at(buf, n) ((buf)->ptr[n])
/*
* Functions below that return int value error codes will return 0 on
* success or -1 on failure (which generally means an allocation failed).
- * Using a gh_buf where the allocation has failed with result in -1 from
+ * Using a strbuf where the allocation has failed with result in -1 from
* all further calls using that buffer. As a result, you can ignore the
* return code of these functions and call them in a series then just call
- * gh_buf_oom at the end.
+ * strbuf_oom at the end.
*/
-extern int gh_buf_set(gh_buf *buf, const unsigned char *data, int len);
-extern int gh_buf_sets(gh_buf *buf, const char *string);
-extern int gh_buf_putc(gh_buf *buf, int c);
-extern int gh_buf_put(gh_buf *buf, const unsigned char *data, int len);
-extern int gh_buf_puts(gh_buf *buf, const char *string);
-extern int gh_buf_printf(gh_buf *buf, const char *format, ...)
+extern int strbuf_set(strbuf *buf, const unsigned char *data, int len);
+extern int strbuf_sets(strbuf *buf, const char *string);
+extern int strbuf_putc(strbuf *buf, int c);
+extern int strbuf_put(strbuf *buf, const unsigned char *data, int len);
+extern int strbuf_puts(strbuf *buf, const char *string);
+extern int strbuf_printf(strbuf *buf, const char *format, ...)
__attribute__((format (printf, 2, 3)));
-extern int gh_buf_vprintf(gh_buf *buf, const char *format, va_list ap);
-extern void gh_buf_clear(gh_buf *buf);
-
-int gh_buf_strchr(const gh_buf *buf, int c, int pos);
-int gh_buf_strrchr(const gh_buf *buf, int c, int pos);
-void gh_buf_drop(gh_buf *buf, int n);
-void gh_buf_truncate(gh_buf *buf, int len);
-void gh_buf_trim(gh_buf *buf);
+extern int strbuf_vprintf(strbuf *buf, const char *format, va_list ap);
+extern void strbuf_clear(strbuf *buf);
+
+int strbuf_strchr(const strbuf *buf, int c, int pos);
+int strbuf_strrchr(const strbuf *buf, int c, int pos);
+void strbuf_drop(strbuf *buf, int n);
+void strbuf_truncate(strbuf *buf, int len);
+void strbuf_trim(strbuf *buf);
#endif
diff --git a/src/chunk.h b/src/chunk.h
index f3841ed..f37a2f3 100644
--- a/src/chunk.h
+++ b/src/chunk.h
@@ -78,12 +78,12 @@ static inline chunk chunk_dup(const chunk *ch, int pos, int len)
return c;
}
-static inline chunk chunk_buf_detach(gh_buf *buf)
+static inline chunk chunk_buf_detach(strbuf *buf)
{
chunk c;
c.len = buf->size;
- c.data = gh_buf_detach(buf);
+ c.data = strbuf_detach(buf);
c.alloc = 1;
return c;
diff --git a/src/html/houdini.h b/src/html/houdini.h
index 31fe917..1e54d20 100644
--- a/src/html/houdini.h
+++ b/src/html/houdini.h
@@ -25,17 +25,17 @@ extern "C" {
#define HOUDINI_ESCAPED_SIZE(x) (((x) * 12) / 10)
#define HOUDINI_UNESCAPED_SIZE(x) (x)
-extern int houdini_escape_html(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure);
-extern int houdini_unescape_html(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_escape_xml(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_escape_uri(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_escape_url(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_unescape_uri(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_unescape_url(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_escape_js(gh_buf *ob, const uint8_t *src, size_t size);
-extern int houdini_unescape_js(gh_buf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_html(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_html0(strbuf *ob, const uint8_t *src, size_t size, int secure);
+extern int houdini_unescape_html(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_xml(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_uri(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_url(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_href(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_unescape_uri(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_unescape_url(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_escape_js(strbuf *ob, const uint8_t *src, size_t size);
+extern int houdini_unescape_js(strbuf *ob, const uint8_t *src, size_t size);
#ifdef __cplusplus
}
diff --git a/src/html/houdini_href_e.c b/src/html/houdini_href_e.c
index b2a7d79..12456ce 100644
--- a/src/html/houdini_href_e.c
+++ b/src/html/houdini_href_e.c
@@ -49,7 +49,7 @@ static const char HREF_SAFE[] = {
};
int
-houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
+houdini_escape_href(strbuf *ob, const uint8_t *src, size_t size)
{
static const uint8_t hex_chars[] = "0123456789ABCDEF";
size_t i = 0, org;
@@ -63,7 +63,7 @@ houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
i++;
if (likely(i > org))
- gh_buf_put(ob, src + org, i - org);
+ strbuf_put(ob, src + org, i - org);
/* escaping */
if (i >= size)
@@ -73,14 +73,14 @@ houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
/* amp appears all the time in URLs, but needs
* HTML-entity escaping to be inside an href */
case '&':
- gh_buf_puts(ob, "&");
+ strbuf_puts(ob, "&");
break;
/* the single quote is a valid URL character
* according to the standard; it needs HTML
* entity escaping too */
case '\'':
- gh_buf_puts(ob, "'");
+ strbuf_puts(ob, "'");
break;
/* the space can be escaped to %20 or a plus
@@ -89,7 +89,7 @@ houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
* when building GET strings */
#if 0
case ' ':
- gh_buf_putc(ob, '+');
+ strbuf_putc(ob, '+');
break;
#endif
@@ -97,7 +97,7 @@ houdini_escape_href(gh_buf *ob, const uint8_t *src, size_t size)
default:
hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];
hex_str[2] = hex_chars[src[i] & 0xF];
- gh_buf_put(ob, hex_str, 3);
+ strbuf_put(ob, hex_str, 3);
}
i++;
diff --git a/src/html/houdini_html_e.c b/src/html/houdini_html_e.c
index 95b6c41..f2e86fe 100644
--- a/src/html/houdini_html_e.c
+++ b/src/html/houdini_html_e.c
@@ -45,7 +45,7 @@ static const char *HTML_ESCAPES[] = {
};
int
-houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
+houdini_escape_html0(strbuf *ob, const uint8_t *src, size_t size, int secure)
{
size_t i = 0, org, esc = 0;
@@ -55,7 +55,7 @@ houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
i++;
if (i > org)
- gh_buf_put(ob, src + org, i - org);
+ strbuf_put(ob, src + org, i - org);
/* escaping */
if (unlikely(i >= size))
@@ -63,9 +63,9 @@ houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
/* The forward slash is only escaped in secure mode */
if ((src[i] == '/' || src[i] == '\'') && !secure) {
- gh_buf_putc(ob, src[i]);
+ strbuf_putc(ob, src[i]);
} else {
- gh_buf_puts(ob, HTML_ESCAPES[esc]);
+ strbuf_puts(ob, HTML_ESCAPES[esc]);
}
i++;
@@ -75,7 +75,7 @@ houdini_escape_html0(gh_buf *ob, const uint8_t *src, size_t size, int secure)
}
int
-houdini_escape_html(gh_buf *ob, const uint8_t *src, size_t size)
+houdini_escape_html(strbuf *ob, const uint8_t *src, size_t size)
{
return houdini_escape_html0(ob, src, size, 1);
}
diff --git a/src/html/html.c b/src/html/html.c
index 41b8fda..a9356dd 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -10,7 +10,7 @@
// Functions to convert block and inline lists to HTML strings.
-static void escape_html(gh_buf *dest, const unsigned char *source, int length)
+static void escape_html(strbuf *dest, const unsigned char *source, int length)
{
if (length < 0)
length = strlen((char *)source);
@@ -18,7 +18,7 @@ static void escape_html(gh_buf *dest, const unsigned char *source, int length)
houdini_escape_html0(dest, source, (size_t)length, 0);
}
-static void escape_href(gh_buf *dest, const unsigned char *source, int length)
+static void escape_href(strbuf *dest, const unsigned char *source, int length)
{
if (length < 0)
length = strlen((char *)source);
@@ -26,14 +26,14 @@ static void escape_href(gh_buf *dest, const unsigned char *source, int length)
houdini_escape_href(dest, source, (size_t)length);
}
-static inline void cr(gh_buf *html)
+static inline void cr(strbuf *html)
{
if (html->size && html->ptr[html->size - 1] != '\n')
- gh_buf_putc(html, '\n');
+ strbuf_putc(html, '\n');
}
// Convert a block list to HTML. Returns 0 on success, and sets result.
-void blocks_to_html(gh_buf *html, block *b, bool tight)
+void blocks_to_html(strbuf *html, block *b, bool tight)
{
struct ListData *data;
@@ -48,25 +48,25 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
inlines_to_html(html, b->inline_content);
} else {
cr(html);
- gh_buf_puts(html, "");
+ strbuf_puts(html, "
");
inlines_to_html(html, b->inline_content);
- gh_buf_puts(html, "
\n");
+ strbuf_puts(html, "\n");
}
break;
case block_quote:
cr(html);
- gh_buf_puts(html, "\n");
+ strbuf_puts(html, "\n");
blocks_to_html(html, b->children, false);
- gh_buf_puts(html, "
\n");
+ strbuf_puts(html, "
\n");
break;
case list_item:
cr(html);
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
blocks_to_html(html, b->children, tight);
- gh_buf_trim(html); /* TODO: rtrim */
- gh_buf_puts(html, "\n");
+ strbuf_trim(html); /* TODO: rtrim */
+ strbuf_puts(html, "\n");
break;
case list:
@@ -75,58 +75,58 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
data = &(b->attributes.list_data);
if (data->start > 1) {
- gh_buf_printf(html, "<%s start=\"%d\">\n",
+ strbuf_printf(html, "<%s start=\"%d\">\n",
data->list_type == bullet ? "ul" : "ol",
data->start);
} else {
- gh_buf_puts(html, data->list_type == bullet ? "\n" : "\n");
+ strbuf_puts(html, data->list_type == bullet ? "\n" : "\n");
}
blocks_to_html(html, b->children, data->tight);
- gh_buf_puts(html, data->list_type == bullet ? "
" : "
");
- gh_buf_putc(html, '\n');
+ strbuf_puts(html, data->list_type == bullet ? "
" : "");
+ strbuf_putc(html, '\n');
break;
case atx_header:
case setext_header:
cr(html);
- gh_buf_printf(html, "", b->attributes.header_level);
+ strbuf_printf(html, "", b->attributes.header_level);
inlines_to_html(html, b->inline_content);
- gh_buf_printf(html, "\n", b->attributes.header_level);
+ strbuf_printf(html, "\n", b->attributes.header_level);
break;
case indented_code:
case fenced_code:
cr(html);
- gh_buf_puts(html, "tag == fenced_code) {
- gh_buf *info = &b->attributes.fenced_code_data.info;
+ strbuf *info = &b->attributes.fenced_code_data.info;
- if (gh_buf_len(info) > 0) {
- int first_tag = gh_buf_strchr(info, ' ', 0);
+ if (strbuf_len(info) > 0) {
+ int first_tag = strbuf_strchr(info, ' ', 0);
if (first_tag < 0)
- first_tag = gh_buf_len(info);
+ first_tag = strbuf_len(info);
- gh_buf_puts(html, " class=\"");
+ strbuf_puts(html, " class=\"");
escape_html(html, info->ptr, first_tag);
- gh_buf_putc(html, '"');
+ strbuf_putc(html, '"');
}
}
- gh_buf_puts(html, ">");
+ strbuf_puts(html, ">");
escape_html(html, b->string_content.ptr, b->string_content.size);
- gh_buf_puts(html, "
\n");
+ strbuf_puts(html, "\n");
break;
case html_block:
- gh_buf_put(html, b->string_content.ptr, b->string_content.size);
+ strbuf_put(html, b->string_content.ptr, b->string_content.size);
break;
case hrule:
- gh_buf_puts(html, "
\n");
+ strbuf_puts(html, "
\n");
break;
case reference_def:
@@ -141,9 +141,9 @@ void blocks_to_html(gh_buf *html, block *b, bool tight)
}
// Convert an inline list to HTML. Returns 0 on success, and sets result.
-void inlines_to_html(gh_buf *html, inl* ils)
+void inlines_to_html(strbuf *html, inl* ils)
{
- gh_buf scrap = GH_BUF_INIT;
+ strbuf scrap = GH_BUF_INIT;
while(ils != NULL) {
switch(ils->tag) {
@@ -152,70 +152,70 @@ void inlines_to_html(gh_buf *html, inl* ils)
break;
case INL_LINEBREAK:
- gh_buf_puts(html, "
\n");
+ strbuf_puts(html, "
\n");
break;
case INL_SOFTBREAK:
- gh_buf_putc(html, '\n');
+ strbuf_putc(html, '\n');
break;
case INL_CODE:
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
escape_html(html, ils->content.literal.data, ils->content.literal.len);
- gh_buf_puts(html, "
");
+ strbuf_puts(html, "
");
break;
case INL_RAW_HTML:
case INL_ENTITY:
- gh_buf_put(html,
+ strbuf_put(html,
ils->content.literal.data,
ils->content.literal.len);
break;
case INL_LINK:
- gh_buf_puts(html, "content.linkable.url)
escape_href(html, ils->content.linkable.url, -1);
if (ils->content.linkable.title) {
- gh_buf_puts(html, "\" title=\"");
+ strbuf_puts(html, "\" title=\"");
escape_html(html, ils->content.linkable.title, -1);
}
- gh_buf_puts(html, "\">");
+ strbuf_puts(html, "\">");
inlines_to_html(html, ils->content.inlines);
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
break;
case INL_IMAGE:
- gh_buf_puts(html, "content.linkable.url)
escape_href(html, ils->content.linkable.url, -1);
inlines_to_html(&scrap, ils->content.inlines);
- gh_buf_puts(html, "\" alt=\"");
+ strbuf_puts(html, "\" alt=\"");
if (scrap.size)
escape_html(html, scrap.ptr, scrap.size);
- gh_buf_clear(&scrap);
+ strbuf_clear(&scrap);
if (ils->content.linkable.title) {
- gh_buf_puts(html, "\" title=\"");
+ strbuf_puts(html, "\" title=\"");
escape_html(html, ils->content.linkable.title, -1);
}
- gh_buf_puts(html, "\"/>");
+ strbuf_puts(html, "\"/>");
break;
case INL_STRONG:
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
inlines_to_html(html, ils->content.inlines);
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
break;
case INL_EMPH:
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
inlines_to_html(html, ils->content.inlines);
- gh_buf_puts(html, "");
+ strbuf_puts(html, "");
break;
}
ils = ils->next;
diff --git a/src/inlines.c b/src/inlines.c
index 8e2e683..33973df 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -25,7 +25,7 @@ inline static void chunk_free(chunk *c);
inline static void chunk_trim(chunk *c);
inline static chunk chunk_literal(const char *data);
-inline static chunk chunk_buf_detach(gh_buf *buf);
+inline static chunk chunk_buf_detach(strbuf *buf);
inline static chunk chunk_dup(const chunk *ch, int pos, int len);
static inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
@@ -33,10 +33,10 @@ static inl *parse_inlines_while(subject* subj, int (*f)(subject*));
static int parse_inline(subject* subj, inl ** last);
static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap);
-static void subject_from_buf(subject *e, gh_buf *buffer, reference** refmap);
+static void subject_from_buf(subject *e, strbuf *buffer, reference** refmap);
static int subject_find_special_char(subject *subj);
-static void normalize_whitespace(gh_buf *s);
+static void normalize_whitespace(strbuf *s);
extern void free_reference(reference *ref) {
free(ref->label);
@@ -62,13 +62,13 @@ extern void free_reference_map(reference **refmap) {
// remove leading/trailing whitespace, case fold
static unsigned char *normalize_reference(chunk *ref)
{
- gh_buf normalized = GH_BUF_INIT;
+ strbuf normalized = GH_BUF_INIT;
utf8proc_case_fold(&normalized, ref->data, ref->len);
- gh_buf_trim(&normalized);
+ strbuf_trim(&normalized);
normalize_whitespace(&normalized);
- return gh_buf_detach(&normalized);
+ return strbuf_detach(&normalized);
}
// Returns reference if refmap contains a reference with matching
@@ -218,7 +218,7 @@ inline static inl* append_inlines(inl* a, inl* b)
return a;
}
-static void subject_from_buf(subject *e, gh_buf *buffer, reference** refmap)
+static void subject_from_buf(subject *e, strbuf *buffer, reference** refmap)
{
e->input.data = buffer->ptr;
e->input.len = buffer->size;
@@ -309,7 +309,7 @@ static int scan_to_closing_backticks(subject* subj, int openticklength)
// Destructively modify string, collapsing consecutive
// space and newline characters into a single space.
-static void normalize_whitespace(gh_buf *s)
+static void normalize_whitespace(strbuf *s)
{
bool last_char_was_space = false;
int r, w;
@@ -331,7 +331,7 @@ static void normalize_whitespace(gh_buf *s)
}
}
- gh_buf_truncate(s, w);
+ strbuf_truncate(s, w);
}
// Parse backtick code section or raw backticks, return an inline.
@@ -346,10 +346,10 @@ static inl* handle_backticks(subject *subj)
subj->pos = startpos; // rewind
return make_str(openticks);
} else {
- gh_buf buf = GH_BUF_INIT;
+ strbuf buf = GH_BUF_INIT;
- gh_buf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);
- gh_buf_trim(&buf);
+ strbuf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);
+ strbuf_trim(&buf);
normalize_whitespace(&buf);
return make_code(chunk_buf_detach(&buf));
@@ -569,7 +569,7 @@ static inl *make_str_with_entities(chunk *content)
}
// Destructively unescape a string: remove backslashes before punctuation chars.
-extern void unescape_buffer(gh_buf *buf)
+extern void unescape_buffer(strbuf *buf)
{
int r, w;
@@ -580,14 +580,14 @@ extern void unescape_buffer(gh_buf *buf)
buf->ptr[w++] = buf->ptr[r];
}
- gh_buf_truncate(buf, w);
+ strbuf_truncate(buf, w);
}
// Clean a URL: remove surrounding whitespace and surrounding <>,
// and remove \ that escape punctuation.
static unsigned char *clean_url(chunk *url, int is_email)
{
- gh_buf buf = GH_BUF_INIT;
+ strbuf buf = GH_BUF_INIT;
chunk_trim(url);
@@ -595,22 +595,22 @@ static unsigned char *clean_url(chunk *url, int is_email)
return NULL;
if (is_email)
- gh_buf_puts(&buf, "mailto:");
+ strbuf_puts(&buf, "mailto:");
if (url->data[0] == '<' && url->data[url->len - 1] == '>') {
- gh_buf_put(&buf, url->data + 1, url->len - 2);
+ strbuf_put(&buf, url->data + 1, url->len - 2);
} else {
- gh_buf_put(&buf, url->data, url->len);
+ strbuf_put(&buf, url->data, url->len);
}
unescape_buffer(&buf);
- return gh_buf_detach(&buf);
+ return strbuf_detach(&buf);
}
// Clean a title: remove surrounding quotes and remove \ that escape punctuation.
static unsigned char *clean_title(chunk *title)
{
- gh_buf buf = GH_BUF_INIT;
+ strbuf buf = GH_BUF_INIT;
unsigned char first, last;
if (title->len == 0)
@@ -623,13 +623,13 @@ static unsigned char *clean_title(chunk *title)
if ((first == '\'' && last == '\'') ||
(first == '(' && last == ')') ||
(first == '"' && last == '"')) {
- gh_buf_set(&buf, title->data + 1, title->len - 2);
+ strbuf_set(&buf, title->data + 1, title->len - 2);
} else {
- gh_buf_set(&buf, title->data, title->len);
+ strbuf_set(&buf, title->data, title->len);
}
unescape_buffer(&buf);
- return gh_buf_detach(&buf);
+ return strbuf_detach(&buf);
}
// Parse an autolink or HTML tag.
@@ -971,7 +971,7 @@ static int parse_inline(subject* subj, inl ** last)
return 1;
}
-extern inl* parse_inlines(gh_buf *input, reference** refmap)
+extern inl* parse_inlines(strbuf *input, reference** refmap)
{
subject subj;
subject_from_buf(&subj, input, refmap);
@@ -993,7 +993,7 @@ void spnl(subject* subj)
// Modify refmap if a reference is encountered.
// Return 0 if no reference found, otherwise position of subject
// after reference is parsed.
-extern int parse_reference(gh_buf *input, reference** refmap)
+extern int parse_reference(strbuf *input, reference** refmap)
{
subject subj;
diff --git a/src/main.c b/src/main.c
index e1abedc..7cf67e2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,14 +14,14 @@ void print_usage()
static void print_document(block *document, bool ast)
{
- gh_buf html = GH_BUF_INIT;
+ strbuf html = GH_BUF_INIT;
if (ast) {
print_blocks(document, 0);
} else {
blocks_to_html(&html, document, false);
printf("%s", html.ptr);
- gh_buf_free(&html);
+ strbuf_free(&html);
}
}
diff --git a/src/stmd.h b/src/stmd.h
index 4a3c399..2e86f3a 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -50,7 +50,7 @@ struct FencedCodeData {
int fence_length;
int fence_offset;
char fence_char;
- gh_buf info;
+ strbuf info;
};
typedef struct Block {
@@ -76,7 +76,7 @@ typedef struct Block {
struct Block* last_child;
struct Block* parent;
struct Block* top;
- gh_buf string_content;
+ strbuf string_content;
inl* inline_content;
union {
struct ListData list_data;
@@ -88,15 +88,15 @@ typedef struct Block {
struct Block * prev;
} block;
-inl* parse_inlines(gh_buf *input, reference** refmap);
+inl* parse_inlines(strbuf *input, reference** refmap);
void free_inlines(inl* e);
-int parse_reference(gh_buf *input, reference** refmap);
+int parse_reference(strbuf *input, reference** refmap);
void free_reference(reference *ref);
void free_reference_map(reference **refmap);
void add_reference(reference** refmap, reference* ref);
-void unescape_buffer(gh_buf *buf);
+void unescape_buffer(strbuf *buf);
extern block* make_document();
extern block* add_child(block* parent,
@@ -109,9 +109,9 @@ extern block *stmd_parse_file(FILE *f);
void print_inlines(inl* ils, int indent);
void print_blocks(block* blk, int indent);
-void blocks_to_html(gh_buf *html, block *b, bool tight);
-void inlines_to_html(gh_buf *html, inl *b);
+void blocks_to_html(strbuf *html, block *b, bool tight);
+void inlines_to_html(strbuf *html, inl *b);
-void utf8proc_case_fold(gh_buf *dest, const unsigned char *str, int len);
+void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
#endif
diff --git a/src/utf8.c b/src/utf8.c
index 32c78a4..cebd872 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -84,7 +84,7 @@ ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst)
return length;
}
-void utf8proc_encode_char(int32_t uc, gh_buf *buf)
+void utf8proc_encode_char(int32_t uc, strbuf *buf)
{
unsigned char dst[4];
int len = 0;
@@ -119,10 +119,10 @@ void utf8proc_encode_char(int32_t uc, gh_buf *buf)
assert(false);
}
- gh_buf_put(buf, dst, len);
+ strbuf_put(buf, dst, len);
}
-void utf8proc_case_fold(gh_buf *dest, const unsigned char *str, int len)
+void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len)
{
int32_t c;
--
cgit v1.2.3
From 647b15968c95ec268d6d728eea73756c7ba648a8 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 18:42:49 +0200
Subject: Rename inl
---
src/html/html.c | 2 +-
src/inlines.c | 88 ++++++++++++++++++++++++++++-----------------------------
src/print.c | 2 +-
src/stmd.h | 34 ++++++++++++++--------
4 files changed, 68 insertions(+), 58 deletions(-)
diff --git a/src/html/html.c b/src/html/html.c
index a9356dd..53521b8 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -141,7 +141,7 @@ void blocks_to_html(strbuf *html, block *b, bool tight)
}
// Convert an inline list to HTML. Returns 0 on success, and sets result.
-void inlines_to_html(strbuf *html, inl* ils)
+void inlines_to_html(strbuf *html, struct inl* ils)
{
strbuf scrap = GH_BUF_INIT;
diff --git a/src/inlines.c b/src/inlines.c
index 33973df..301125e 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -28,9 +28,9 @@ inline static chunk chunk_literal(const char *data);
inline static chunk chunk_buf_detach(strbuf *buf);
inline static chunk chunk_dup(const chunk *ch, int pos, int len);
-static inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
-static inl *parse_inlines_while(subject* subj, int (*f)(subject*));
-static int parse_inline(subject* subj, inl ** last);
+static struct inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
+static struct inl *parse_inlines_while(subject* subj, int (*f)(subject*));
+static int parse_inline(subject* subj, struct inl ** last);
static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap);
static void subject_from_buf(subject *e, strbuf *buffer, reference** refmap);
@@ -108,9 +108,9 @@ extern void add_reference(reference** refmap, reference* ref)
}
}
-inline static inl* make_link_from_reference(inl* label, reference *ref)
+inline static struct inl* make_link_from_reference(struct inl* label, reference *ref)
{
- inl* e = (inl*) malloc(sizeof(inl));
+ struct inl* e = (struct inl*) malloc(sizeof(struct inl));
e->tag = INL_LINK;
e->content.linkable.label = label;
e->content.linkable.url = strdup(ref->url);
@@ -120,9 +120,9 @@ inline static inl* make_link_from_reference(inl* label, reference *ref)
}
// Create an inline with a linkable string value.
-inline static inl* make_link(inl* label, chunk url, chunk title, int is_email)
+inline static struct inl* make_link(struct inl* label, chunk url, chunk title, int is_email)
{
- inl* e = (inl*) malloc(sizeof(inl));
+ struct inl* e = (struct inl*) malloc(sizeof(struct inl));
e->tag = INL_LINK;
e->content.linkable.label = label;
e->content.linkable.url = clean_url(&url, is_email);
@@ -131,9 +131,9 @@ inline static inl* make_link(inl* label, chunk url, chunk title, int is_email)
return e;
}
-inline static inl* make_inlines(int t, inl* contents)
+inline static struct inl* make_inlines(int t, struct inl* contents)
{
- inl* e = (inl*) malloc(sizeof(inl));
+ struct inl* e = (struct inl*) malloc(sizeof(struct inl));
e->tag = t;
e->content.inlines = contents;
e->next = NULL;
@@ -141,9 +141,9 @@ inline static inl* make_inlines(int t, inl* contents)
}
// Create an inline with a literal string value.
-inline static inl* make_literal(int t, chunk s)
+inline static struct inl* make_literal(int t, chunk s)
{
- inl* e = (inl*) malloc(sizeof(inl));
+ struct inl* e = (struct inl*) malloc(sizeof(struct inl));
e->tag = t;
e->content.literal = s;
e->next = NULL;
@@ -151,9 +151,9 @@ inline static inl* make_literal(int t, chunk s)
}
// Create an inline with no value.
-inline static inl* make_simple(int t)
+inline static struct inl* make_simple(int t)
{
- inl* e = (inl*) malloc(sizeof(inl));
+ struct inl* e = (struct inl*) malloc(sizeof(struct inl));
e->tag = t;
e->next = NULL;
return e;
@@ -170,9 +170,9 @@ inline static inl* make_simple(int t)
#define make_strong(contents) make_inlines(INL_STRONG, contents)
// Free an inline list.
-extern void free_inlines(inl* e)
+extern void free_inlines(struct inl* e)
{
- inl * next;
+ struct inl * next;
while (e != NULL) {
switch (e->tag){
case INL_STRING:
@@ -205,12 +205,12 @@ extern void free_inlines(inl* e)
// Append inline list b to the end of inline list a.
// Return pointer to head of new list.
-inline static inl* append_inlines(inl* a, inl* b)
+inline static struct inl* append_inlines(struct inl* a, struct inl* b)
{
if (a == NULL) { // NULL acts like an empty list
return b;
}
- inl* cur = a;
+ struct inl* cur = a;
while (cur->next) {
cur = cur->next;
}
@@ -336,7 +336,7 @@ static void normalize_whitespace(strbuf *s)
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
-static inl* handle_backticks(subject *subj)
+static struct inl* handle_backticks(subject *subj)
{
chunk openticks = take_while(subj, isbacktick);
int startpos = subj->pos;
@@ -382,15 +382,15 @@ static int scan_delims(subject* subj, char c, bool * can_open, bool * can_close)
// Parse strong/emph or a fallback.
// Assumes the subject has '_' or '*' at the current position.
-static inl* handle_strong_emph(subject* subj, char c)
+static struct inl* handle_strong_emph(subject* subj, char c)
{
bool can_open, can_close;
- inl * result = NULL;
- inl ** last = malloc(sizeof(inl *));
- inl * new;
- inl * il;
- inl * first_head = NULL;
- inl * first_close = NULL;
+ struct inl * result = NULL;
+ struct inl ** last = malloc(sizeof(struct inl *));
+ struct inl * new;
+ struct inl * il;
+ struct inl * first_head = NULL;
+ struct inl * first_close = NULL;
int first_close_delims = 0;
int numdelims;
@@ -508,7 +508,7 @@ done:
}
// Parse backslash-escape or just a backslash, returning an inline.
-static inl* handle_backslash(subject *subj)
+static struct inl* handle_backslash(subject *subj)
{
advance(subj);
unsigned char nextchar = peek_char(subj);
@@ -525,10 +525,10 @@ static inl* handle_backslash(subject *subj)
// Parse an entity or a regular "&" string.
// Assumes the subject has an '&' character at the current position.
-static inl* handle_entity(subject* subj)
+static struct inl* handle_entity(subject* subj)
{
int match;
- inl *result;
+ struct inl *result;
match = scan_entity(&subj->input, subj->pos);
if (match) {
result = make_entity(chunk_dup(&subj->input, subj->pos, match));
@@ -542,10 +542,10 @@ static inl* handle_entity(subject* subj)
// Like make_str, but parses entities.
// Returns an inline sequence consisting of str and entity elements.
-static inl *make_str_with_entities(chunk *content)
+static struct inl *make_str_with_entities(chunk *content)
{
- inl *result = NULL;
- inl *new;
+ struct inl *result = NULL;
+ struct inl *new;
int searchpos;
char c;
subject subj;
@@ -634,7 +634,7 @@ static unsigned char *clean_title(chunk *title)
// Parse an autolink or HTML tag.
// Assumes the subject has a '<' character at the current position.
-static inl* handle_pointy_brace(subject* subj)
+static struct inl* handle_pointy_brace(subject* subj)
{
int matchlen = 0;
chunk contents;
@@ -693,7 +693,7 @@ static inl* handle_pointy_brace(subject* subj)
static int link_label(subject* subj, chunk *raw_label)
{
int nestlevel = 0;
- inl* tmp = NULL;
+ struct inl* tmp = NULL;
int startpos = subj->pos;
if (subj->label_nestlevel) {
@@ -751,10 +751,10 @@ static int link_label(subject* subj, chunk *raw_label)
}
// Parse a link or the link portion of an image, or return a fallback.
-static inl* handle_left_bracket(subject* subj)
+static struct inl* handle_left_bracket(subject* subj)
{
- inl *lab = NULL;
- inl *result = NULL;
+ struct inl *lab = NULL;
+ struct inl *result = NULL;
reference *ref;
int n;
int sps;
@@ -838,7 +838,7 @@ static inl* handle_left_bracket(subject* subj)
// Parse a hard or soft linebreak, returning an inline.
// Assumes the subject has a newline at the current position.
-static inl* handle_newline(subject *subj)
+static struct inl* handle_newline(subject *subj)
{
int nlpos = subj->pos;
// skip over newline
@@ -862,16 +862,16 @@ inline static int not_eof(subject* subj)
}
// Parse inlines while a predicate is satisfied. Return inlines.
-extern inl* parse_inlines_while(subject* subj, int (*f)(subject*))
+extern struct inl* parse_inlines_while(subject* subj, int (*f)(subject*))
{
- inl* result = NULL;
- inl** last = &result;
+ struct inl* result = NULL;
+ struct inl** last = &result;
while ((*f)(subj) && parse_inline(subj, last)) {
}
return result;
}
-inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
+struct inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
{
subject subj;
subject_from_chunk(&subj, chunk, refmap);
@@ -894,9 +894,9 @@ static int subject_find_special_char(subject *subj)
// Parse an inline, advancing subject, and add it to last element.
// Adjust tail to point to new last element of list.
// Return 0 if no inline can be parsed, 1 otherwise.
-static int parse_inline(subject* subj, inl ** last)
+static int parse_inline(subject* subj, struct inl ** last)
{
- inl* new = NULL;
+ struct inl* new = NULL;
chunk contents;
unsigned char c;
int endpos;
@@ -971,7 +971,7 @@ static int parse_inline(subject* subj, inl ** last)
return 1;
}
-extern inl* parse_inlines(strbuf *input, reference** refmap)
+extern struct inl* parse_inlines(strbuf *input, reference** refmap)
{
subject subj;
subject_from_buf(&subj, input, refmap);
diff --git a/src/print.c b/src/print.c
index 832ad4f..63f63c8 100644
--- a/src/print.c
+++ b/src/print.c
@@ -117,7 +117,7 @@ extern void print_blocks(block* b, int indent)
}
// Prettyprint an inline list, for debugging.
-extern void print_inlines(inl* ils, int indent)
+extern void print_inlines(struct inl* ils, int indent)
{
while(ils != NULL) {
for (int i=0; i < indent; i++) {
diff --git a/src/stmd.h b/src/stmd.h
index 2e86f3a..9ed33ec 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -10,20 +10,30 @@
#define VERSION "0.1"
#define CODE_INDENT 4
-typedef struct Inline {
- enum { INL_STRING, INL_SOFTBREAK, INL_LINEBREAK, INL_CODE, INL_RAW_HTML, INL_ENTITY,
- INL_EMPH, INL_STRONG, INL_LINK, INL_IMAGE } tag;
+struct inl {
+ enum {
+ INL_STRING,
+ INL_SOFTBREAK,
+ INL_LINEBREAK,
+ INL_CODE,
+ INL_RAW_HTML,
+ INL_ENTITY,
+ INL_EMPH,
+ INL_STRONG,
+ INL_LINK,
+ INL_IMAGE
+ } tag;
union {
chunk literal;
- struct Inline *inlines;
+ struct inl *inlines;
struct {
- struct Inline *label;
+ struct inl *label;
unsigned char *url;
unsigned char *title;
} linkable;
} content;
- struct Inline *next;
-} inl;
+ struct inl *next;
+};
typedef struct Reference {
unsigned char *label;
@@ -77,7 +87,7 @@ typedef struct Block {
struct Block* parent;
struct Block* top;
strbuf string_content;
- inl* inline_content;
+ struct inl* inline_content;
union {
struct ListData list_data;
struct FencedCodeData fenced_code_data;
@@ -88,8 +98,8 @@ typedef struct Block {
struct Block * prev;
} block;
-inl* parse_inlines(strbuf *input, reference** refmap);
-void free_inlines(inl* e);
+struct inl* parse_inlines(strbuf *input, reference** refmap);
+void free_inlines(struct inl* e);
int parse_reference(strbuf *input, reference** refmap);
void free_reference(reference *ref);
@@ -106,11 +116,11 @@ void free_blocks(block* e);
extern block *stmd_parse_document(const unsigned char *buffer, size_t len);
extern block *stmd_parse_file(FILE *f);
-void print_inlines(inl* ils, int indent);
+void print_inlines(struct inl* ils, int indent);
void print_blocks(block* blk, int indent);
void blocks_to_html(strbuf *html, block *b, bool tight);
-void inlines_to_html(strbuf *html, inl *b);
+void inlines_to_html(strbuf *html, struct inl *b);
void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
--
cgit v1.2.3
From 9e4855365b920c2a80b0f1ab6937280f0b504334 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 18:45:44 +0200
Subject: Rename `inl`
---
src/html/html.c | 2 +-
src/inlines.c | 88 ++++++++++++++++++++++++++++-----------------------------
src/print.c | 2 +-
src/stmd.h | 28 ++++++++++--------
4 files changed, 62 insertions(+), 58 deletions(-)
diff --git a/src/html/html.c b/src/html/html.c
index 53521b8..a7bb21a 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -141,7 +141,7 @@ void blocks_to_html(strbuf *html, block *b, bool tight)
}
// Convert an inline list to HTML. Returns 0 on success, and sets result.
-void inlines_to_html(strbuf *html, struct inl* ils)
+void inlines_to_html(strbuf *html, node_inl* ils)
{
strbuf scrap = GH_BUF_INIT;
diff --git a/src/inlines.c b/src/inlines.c
index 301125e..6bb89da 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -28,9 +28,9 @@ inline static chunk chunk_literal(const char *data);
inline static chunk chunk_buf_detach(strbuf *buf);
inline static chunk chunk_dup(const chunk *ch, int pos, int len);
-static struct inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
-static struct inl *parse_inlines_while(subject* subj, int (*f)(subject*));
-static int parse_inline(subject* subj, struct inl ** last);
+static node_inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
+static node_inl *parse_inlines_while(subject* subj, int (*f)(subject*));
+static int parse_inline(subject* subj, node_inl ** last);
static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap);
static void subject_from_buf(subject *e, strbuf *buffer, reference** refmap);
@@ -108,9 +108,9 @@ extern void add_reference(reference** refmap, reference* ref)
}
}
-inline static struct inl* make_link_from_reference(struct inl* label, reference *ref)
+inline static node_inl* make_link_from_reference(node_inl* label, reference *ref)
{
- struct inl* e = (struct inl*) malloc(sizeof(struct inl));
+ node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = INL_LINK;
e->content.linkable.label = label;
e->content.linkable.url = strdup(ref->url);
@@ -120,9 +120,9 @@ inline static struct inl* make_link_from_reference(struct inl* label, reference
}
// Create an inline with a linkable string value.
-inline static struct inl* make_link(struct inl* label, chunk url, chunk title, int is_email)
+inline static node_inl* make_link(node_inl* label, chunk url, chunk title, int is_email)
{
- struct inl* e = (struct inl*) malloc(sizeof(struct inl));
+ node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = INL_LINK;
e->content.linkable.label = label;
e->content.linkable.url = clean_url(&url, is_email);
@@ -131,9 +131,9 @@ inline static struct inl* make_link(struct inl* label, chunk url, chunk title, i
return e;
}
-inline static struct inl* make_inlines(int t, struct inl* contents)
+inline static node_inl* make_inlines(int t, node_inl* contents)
{
- struct inl* e = (struct inl*) malloc(sizeof(struct inl));
+ node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = t;
e->content.inlines = contents;
e->next = NULL;
@@ -141,9 +141,9 @@ inline static struct inl* make_inlines(int t, struct inl* contents)
}
// Create an inline with a literal string value.
-inline static struct inl* make_literal(int t, chunk s)
+inline static node_inl* make_literal(int t, chunk s)
{
- struct inl* e = (struct inl*) malloc(sizeof(struct inl));
+ node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = t;
e->content.literal = s;
e->next = NULL;
@@ -151,9 +151,9 @@ inline static struct inl* make_literal(int t, chunk s)
}
// Create an inline with no value.
-inline static struct inl* make_simple(int t)
+inline static node_inl* make_simple(int t)
{
- struct inl* e = (struct inl*) malloc(sizeof(struct inl));
+ node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = t;
e->next = NULL;
return e;
@@ -170,9 +170,9 @@ inline static struct inl* make_simple(int t)
#define make_strong(contents) make_inlines(INL_STRONG, contents)
// Free an inline list.
-extern void free_inlines(struct inl* e)
+extern void free_inlines(node_inl* e)
{
- struct inl * next;
+ node_inl * next;
while (e != NULL) {
switch (e->tag){
case INL_STRING:
@@ -205,12 +205,12 @@ extern void free_inlines(struct inl* e)
// Append inline list b to the end of inline list a.
// Return pointer to head of new list.
-inline static struct inl* append_inlines(struct inl* a, struct inl* b)
+inline static node_inl* append_inlines(node_inl* a, node_inl* b)
{
if (a == NULL) { // NULL acts like an empty list
return b;
}
- struct inl* cur = a;
+ node_inl* cur = a;
while (cur->next) {
cur = cur->next;
}
@@ -336,7 +336,7 @@ static void normalize_whitespace(strbuf *s)
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
-static struct inl* handle_backticks(subject *subj)
+static node_inl* handle_backticks(subject *subj)
{
chunk openticks = take_while(subj, isbacktick);
int startpos = subj->pos;
@@ -382,15 +382,15 @@ static int scan_delims(subject* subj, char c, bool * can_open, bool * can_close)
// Parse strong/emph or a fallback.
// Assumes the subject has '_' or '*' at the current position.
-static struct inl* handle_strong_emph(subject* subj, char c)
+static node_inl* handle_strong_emph(subject* subj, char c)
{
bool can_open, can_close;
- struct inl * result = NULL;
- struct inl ** last = malloc(sizeof(struct inl *));
- struct inl * new;
- struct inl * il;
- struct inl * first_head = NULL;
- struct inl * first_close = NULL;
+ node_inl * result = NULL;
+ node_inl ** last = malloc(sizeof(node_inl *));
+ node_inl * new;
+ node_inl * il;
+ node_inl * first_head = NULL;
+ node_inl * first_close = NULL;
int first_close_delims = 0;
int numdelims;
@@ -508,7 +508,7 @@ done:
}
// Parse backslash-escape or just a backslash, returning an inline.
-static struct inl* handle_backslash(subject *subj)
+static node_inl* handle_backslash(subject *subj)
{
advance(subj);
unsigned char nextchar = peek_char(subj);
@@ -525,10 +525,10 @@ static struct inl* handle_backslash(subject *subj)
// Parse an entity or a regular "&" string.
// Assumes the subject has an '&' character at the current position.
-static struct inl* handle_entity(subject* subj)
+static node_inl* handle_entity(subject* subj)
{
int match;
- struct inl *result;
+ node_inl *result;
match = scan_entity(&subj->input, subj->pos);
if (match) {
result = make_entity(chunk_dup(&subj->input, subj->pos, match));
@@ -542,10 +542,10 @@ static struct inl* handle_entity(subject* subj)
// Like make_str, but parses entities.
// Returns an inline sequence consisting of str and entity elements.
-static struct inl *make_str_with_entities(chunk *content)
+static node_inl *make_str_with_entities(chunk *content)
{
- struct inl *result = NULL;
- struct inl *new;
+ node_inl *result = NULL;
+ node_inl *new;
int searchpos;
char c;
subject subj;
@@ -634,7 +634,7 @@ static unsigned char *clean_title(chunk *title)
// Parse an autolink or HTML tag.
// Assumes the subject has a '<' character at the current position.
-static struct inl* handle_pointy_brace(subject* subj)
+static node_inl* handle_pointy_brace(subject* subj)
{
int matchlen = 0;
chunk contents;
@@ -693,7 +693,7 @@ static struct inl* handle_pointy_brace(subject* subj)
static int link_label(subject* subj, chunk *raw_label)
{
int nestlevel = 0;
- struct inl* tmp = NULL;
+ node_inl* tmp = NULL;
int startpos = subj->pos;
if (subj->label_nestlevel) {
@@ -751,10 +751,10 @@ static int link_label(subject* subj, chunk *raw_label)
}
// Parse a link or the link portion of an image, or return a fallback.
-static struct inl* handle_left_bracket(subject* subj)
+static node_inl* handle_left_bracket(subject* subj)
{
- struct inl *lab = NULL;
- struct inl *result = NULL;
+ node_inl *lab = NULL;
+ node_inl *result = NULL;
reference *ref;
int n;
int sps;
@@ -838,7 +838,7 @@ static struct inl* handle_left_bracket(subject* subj)
// Parse a hard or soft linebreak, returning an inline.
// Assumes the subject has a newline at the current position.
-static struct inl* handle_newline(subject *subj)
+static node_inl* handle_newline(subject *subj)
{
int nlpos = subj->pos;
// skip over newline
@@ -862,16 +862,16 @@ inline static int not_eof(subject* subj)
}
// Parse inlines while a predicate is satisfied. Return inlines.
-extern struct inl* parse_inlines_while(subject* subj, int (*f)(subject*))
+extern node_inl* parse_inlines_while(subject* subj, int (*f)(subject*))
{
- struct inl* result = NULL;
- struct inl** last = &result;
+ node_inl* result = NULL;
+ node_inl** last = &result;
while ((*f)(subj) && parse_inline(subj, last)) {
}
return result;
}
-struct inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
+node_inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
{
subject subj;
subject_from_chunk(&subj, chunk, refmap);
@@ -894,9 +894,9 @@ static int subject_find_special_char(subject *subj)
// Parse an inline, advancing subject, and add it to last element.
// Adjust tail to point to new last element of list.
// Return 0 if no inline can be parsed, 1 otherwise.
-static int parse_inline(subject* subj, struct inl ** last)
+static int parse_inline(subject* subj, node_inl ** last)
{
- struct inl* new = NULL;
+ node_inl* new = NULL;
chunk contents;
unsigned char c;
int endpos;
@@ -971,7 +971,7 @@ static int parse_inline(subject* subj, struct inl ** last)
return 1;
}
-extern struct inl* parse_inlines(strbuf *input, reference** refmap)
+extern node_inl* parse_inlines(strbuf *input, reference** refmap)
{
subject subj;
subject_from_buf(&subj, input, refmap);
diff --git a/src/print.c b/src/print.c
index 63f63c8..01e9136 100644
--- a/src/print.c
+++ b/src/print.c
@@ -117,7 +117,7 @@ extern void print_blocks(block* b, int indent)
}
// Prettyprint an inline list, for debugging.
-extern void print_inlines(struct inl* ils, int indent)
+extern void print_inlines(node_inl* ils, int indent)
{
while(ils != NULL) {
for (int i=0; i < indent; i++) {
diff --git a/src/stmd.h b/src/stmd.h
index 9ed33ec..dbc8c8c 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -10,7 +10,7 @@
#define VERSION "0.1"
#define CODE_INDENT 4
-struct inl {
+struct node_inl {
enum {
INL_STRING,
INL_SOFTBREAK,
@@ -25,22 +25,26 @@ struct inl {
} tag;
union {
chunk literal;
- struct inl *inlines;
+ struct node_inl *inlines;
struct {
- struct inl *label;
+ struct node_inl *label;
unsigned char *url;
unsigned char *title;
} linkable;
} content;
- struct inl *next;
+ struct node_inl *next;
};
-typedef struct Reference {
+typedef struct node_inl node_inl;
+
+struct reference {
unsigned char *label;
unsigned char *url;
unsigned char *title;
- UT_hash_handle hh; // used by uthash
-} reference;
+ UT_hash_handle hh; // used by uthash
+};
+
+typedef struct reference reference;
// Types for blocks
@@ -87,7 +91,7 @@ typedef struct Block {
struct Block* parent;
struct Block* top;
strbuf string_content;
- struct inl* inline_content;
+ node_inl* inline_content;
union {
struct ListData list_data;
struct FencedCodeData fenced_code_data;
@@ -98,8 +102,8 @@ typedef struct Block {
struct Block * prev;
} block;
-struct inl* parse_inlines(strbuf *input, reference** refmap);
-void free_inlines(struct inl* e);
+node_inl* parse_inlines(strbuf *input, reference** refmap);
+void free_inlines(node_inl* e);
int parse_reference(strbuf *input, reference** refmap);
void free_reference(reference *ref);
@@ -116,11 +120,11 @@ void free_blocks(block* e);
extern block *stmd_parse_document(const unsigned char *buffer, size_t len);
extern block *stmd_parse_file(FILE *f);
-void print_inlines(struct inl* ils, int indent);
+void print_inlines(node_inl* ils, int indent);
void print_blocks(block* blk, int indent);
void blocks_to_html(strbuf *html, block *b, bool tight);
-void inlines_to_html(strbuf *html, struct inl *b);
+void inlines_to_html(strbuf *html, node_inl *b);
void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
--
cgit v1.2.3
From 19ba82d7a30bd999a25fc303a8516056880abc9d Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 18:49:33 +0200
Subject: Rename node_block
---
src/blocks.c | 100 ++++++++++++++++++++++++++++----------------------------
src/html/html.c | 6 ++--
src/main.c | 4 +--
src/print.c | 4 +--
src/stmd.h | 57 +++++++++++++++++---------------
5 files changed, 87 insertions(+), 84 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index 9faccd9..d74ceb2 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -10,13 +10,13 @@
#define peek_at(i, n) (i)->data[n]
-static void incorporate_line(strbuf *ln, int line_number, block** curptr);
-static void finalize(block* b, int line_number);
+static void incorporate_line(strbuf *ln, int line_number, node_block** curptr);
+static void finalize(node_block* b, int line_number);
-static block* make_block(int tag, int start_line, int start_column)
+static node_block* make_block(int tag, int start_line, int start_column)
{
- block* e;
- e = (block*) malloc(sizeof(block));
+ node_block* e;
+ e = (node_block*) malloc(sizeof(node_block));
e->tag = tag;
e->open = true;
e->last_line_blank = false;
@@ -35,10 +35,10 @@ static block* make_block(int tag, int start_line, int start_column)
return e;
}
-// Create a root document block.
-extern block* make_document()
+// Create a root document node_block.
+extern node_block* make_document()
{
- block * e = make_block(document, 1, 1);
+ node_block * e = make_block(document, 1, 1);
reference * map = NULL;
reference ** refmap;
refmap = (reference**) malloc(sizeof(reference*));
@@ -82,10 +82,10 @@ static inline bool accepts_lines(int block_type)
block_type == fenced_code);
}
-static void add_line(block* block, chunk *ch, int offset)
+static void add_line(node_block* node_block, chunk *ch, int offset)
{
- assert(block->open);
- strbuf_put(&block->string_content, ch->data + offset, ch->len - offset);
+ assert(node_block->open);
+ strbuf_put(&node_block->string_content, ch->data + offset, ch->len - offset);
}
static void remove_trailing_blank_lines(strbuf *ln)
@@ -109,25 +109,25 @@ static void remove_trailing_blank_lines(strbuf *ln)
strbuf_truncate(ln, i);
}
-// Check to see if a block ends with a blank line, descending
+// Check to see if a node_block ends with a blank line, descending
// if needed into lists and sublists.
-static bool ends_with_blank_line(block* block)
+static bool ends_with_blank_line(node_block* node_block)
{
- if (block->last_line_blank) {
+ if (node_block->last_line_blank) {
return true;
}
- if ((block->tag == list || block->tag == list_item) && block->last_child) {
- return ends_with_blank_line(block->last_child);
+ if ((node_block->tag == list || node_block->tag == list_item) && node_block->last_child) {
+ return ends_with_blank_line(node_block->last_child);
} else {
return false;
}
}
// Break out of all containing lists
-static int break_out_of_lists(block ** bptr, int line_number)
+static int break_out_of_lists(node_block ** bptr, int line_number)
{
- block * container = *bptr;
- block * b = container->top;
+ node_block * container = *bptr;
+ node_block * b = container->top;
// find first containing list:
while (b && b->tag != list) {
b = b->last_child;
@@ -144,15 +144,15 @@ static int break_out_of_lists(block ** bptr, int line_number)
}
-static void finalize(block* b, int line_number)
+static void finalize(node_block* b, int line_number)
{
int firstlinelen;
int pos;
- block* item;
- block* subitem;
+ node_block* item;
+ node_block* subitem;
if (!b->open)
- return; // don't do anything if the block is already closed
+ return; // don't do anything if the node_block is already closed
b->open = false;
if (line_number > b->start_line) {
@@ -230,20 +230,20 @@ static void finalize(block* b, int line_number)
}
}
-// Add a block as child of another. Return pointer to child.
-extern block* add_child(block* parent,
+// Add a node_block as child of another. Return pointer to child.
+extern node_block* add_child(node_block* parent,
int block_type, int start_line, int start_column)
{
assert(parent);
- // if 'parent' isn't the kind of block that can accept this child,
- // then back up til we hit a block that can.
+ // if 'parent' isn't the kind of node_block that can accept this child,
+ // then back up til we hit a node_block that can.
while (!can_contain(parent->tag, block_type)) {
finalize(parent, start_line);
parent = parent->parent;
}
- block* child = make_block(block_type, start_line, start_column);
+ node_block* child = make_block(block_type, start_line, start_column);
child->parent = parent;
child->top = parent->top;
@@ -258,10 +258,10 @@ extern block* add_child(block* parent,
return child;
}
-// Free a block list and any children.
-extern void free_blocks(block* e)
+// Free a node_block list and any children.
+extern void free_blocks(node_block* e)
{
- block * next;
+ node_block * next;
while (e != NULL) {
next = e->next;
free_inlines(e->inline_content);
@@ -277,9 +277,9 @@ extern void free_blocks(block* e)
}
}
-// Walk through block and all children, recursively, parsing
+// Walk through node_block and all children, recursively, parsing
// string content into inline content where appropriate.
-void process_inlines(block* cur, reference** refmap)
+void process_inlines(node_block* cur, reference** refmap)
{
switch (cur->tag) {
case paragraph:
@@ -294,7 +294,7 @@ void process_inlines(block* cur, reference** refmap)
break;
}
- block *child = cur->children;
+ node_block *child = cur->children;
while (child != NULL) {
process_inlines(child, refmap);
child = child->next;
@@ -394,7 +394,7 @@ static void expand_tabs(strbuf *ob, const unsigned char *line, size_t size)
}
}
-static block *finalize_document(block *document, int linenum)
+static node_block *finalize_document(node_block *document, int linenum)
{
while (document != document->top) {
finalize(document, linenum);
@@ -407,12 +407,12 @@ static block *finalize_document(block *document, int linenum)
return document;
}
-extern block *stmd_parse_file(FILE *f)
+extern node_block *stmd_parse_file(FILE *f)
{
strbuf line = GH_BUF_INIT;
unsigned char buffer[4096];
int linenum = 1;
- block *document = make_document();
+ node_block *document = make_document();
while (fgets((char *)buffer, sizeof(buffer), f)) {
expand_tabs(&line, buffer, strlen((char *)buffer));
@@ -425,12 +425,12 @@ extern block *stmd_parse_file(FILE *f)
return finalize_document(document, linenum);
}
-extern block *stmd_parse_document(const unsigned char *buffer, size_t len)
+extern node_block *stmd_parse_document(const unsigned char *buffer, size_t len)
{
strbuf line = GH_BUF_INIT;
int linenum = 1;
const unsigned char *end = buffer + len;
- block *document = make_document();
+ node_block *document = make_document();
while (buffer < end) {
const unsigned char *eol = memchr(buffer, '\n', end - buffer);
@@ -470,18 +470,18 @@ static void chop_trailing_hashtags(chunk *ch)
ch->len = n + 1;
}
-// Process one line at a time, modifying a block.
-static void incorporate_line(strbuf *line, int line_number, block** curptr)
+// Process one line at a time, modifying a node_block.
+static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
{
- block* last_matched_container;
+ node_block* last_matched_container;
int offset = 0;
int matched = 0;
int lev = 0;
int i;
struct ListData * data = NULL;
bool all_matched = true;
- block* container;
- block* cur = *curptr;
+ node_block* container;
+ node_block* cur = *curptr;
bool blank = false;
int first_nonspace;
int indent;
@@ -493,8 +493,8 @@ static void incorporate_line(strbuf *line, int line_number, block** curptr)
// container starts at the document root.
container = cur->top;
- // for each containing block, try to parse the associated line start.
- // bail out on failure: container will point to the last matching block.
+ // for each containing node_block, try to parse the associated line start.
+ // bail out on failure: container will point to the last matching node_block.
while (container->last_child && container->last_child->open) {
container = container->last_child;
@@ -570,7 +570,7 @@ static void incorporate_line(strbuf *line, int line_number, block** curptr)
}
if (!all_matched) {
- container = container->parent; // back up to last matching block
+ container = container->parent; // back up to last matching node_block
break;
}
}
@@ -582,7 +582,7 @@ static void incorporate_line(strbuf *line, int line_number, block** curptr)
break_out_of_lists(&container, line_number);
}
- // unless last matched container is code block, try new container starts:
+ // unless last matched container is code node_block, try new container starts:
while (container->tag != fenced_code && container->tag != indented_code &&
container->tag != html_block) {
@@ -713,7 +713,7 @@ static void incorporate_line(strbuf *line, int line_number, block** curptr)
indent = first_nonspace - offset;
blank = peek_at(&input, first_nonspace) == '\n';
- // block quote lines are never blank as they start with >
+ // node_block quote lines are never blank as they start with >
// and we don't count blanks in fenced code for purposes of tight/loose
// lists or breaking out of lists. we also don't set last_line_blank
// on an empty list item.
@@ -724,7 +724,7 @@ static void incorporate_line(strbuf *line, int line_number, block** curptr)
container->children == NULL &&
container->start_line == line_number));
- block *cont = container;
+ node_block *cont = container;
while (cont->parent) {
cont->parent->last_line_blank = false;
cont = cont->parent;
diff --git a/src/html/html.c b/src/html/html.c
index a7bb21a..6041fde 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -8,7 +8,7 @@
#include "debug.h"
#include "html/houdini.h"
-// Functions to convert block and inline lists to HTML strings.
+// Functions to convert node_block and inline lists to HTML strings.
static void escape_html(strbuf *dest, const unsigned char *source, int length)
{
@@ -32,8 +32,8 @@ static inline void cr(strbuf *html)
strbuf_putc(html, '\n');
}
-// Convert a block list to HTML. Returns 0 on success, and sets result.
-void blocks_to_html(strbuf *html, block *b, bool tight)
+// Convert a node_block list to HTML. Returns 0 on success, and sets result.
+void blocks_to_html(strbuf *html, node_block *b, bool tight)
{
struct ListData *data;
diff --git a/src/main.c b/src/main.c
index 7cf67e2..90bb16d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,7 +12,7 @@ void print_usage()
printf(" --version Print version\n");
}
-static void print_document(block *document, bool ast)
+static void print_document(node_block *document, bool ast)
{
strbuf html = GH_BUF_INIT;
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
int i, numfps = 0;
bool ast = false;
int files[argc];
- block *document = NULL;
+ node_block *document = NULL;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--version") == 0) {
diff --git a/src/print.c b/src/print.c
index 01e9136..069d299 100644
--- a/src/print.c
+++ b/src/print.c
@@ -32,9 +32,9 @@ static void print_str(const unsigned char *s, int len)
putchar('"');
}
-// Functions to pretty-print inline and block lists, for debugging.
+// Functions to pretty-print inline and node_block lists, for debugging.
// Prettyprint an inline list, for debugging.
-extern void print_blocks(block* b, int indent)
+extern void print_blocks(node_block* b, int indent)
{
struct ListData *data;
diff --git a/src/stmd.h b/src/stmd.h
index dbc8c8c..957ab03 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -67,29 +67,30 @@ struct FencedCodeData {
strbuf info;
};
-typedef struct Block {
- enum { document,
- block_quote,
- list,
- list_item,
- fenced_code,
- indented_code,
- html_block,
- paragraph,
- atx_header,
- setext_header,
- hrule,
- reference_def
+struct node_block {
+ enum {
+ document,
+ block_quote,
+ list,
+ list_item,
+ fenced_code,
+ indented_code,
+ html_block,
+ paragraph,
+ atx_header,
+ setext_header,
+ hrule,
+ reference_def
} tag;
int start_line;
int start_column;
int end_line;
bool open;
bool last_line_blank;
- struct Block* children;
- struct Block* last_child;
- struct Block* parent;
- struct Block* top;
+ struct node_block* children;
+ struct node_block* last_child;
+ struct node_block* parent;
+ struct node_block* top;
strbuf string_content;
node_inl* inline_content;
union {
@@ -98,9 +99,11 @@ typedef struct Block {
int header_level;
reference** refmap;
} attributes;
- struct Block * next;
- struct Block * prev;
-} block;
+ struct node_block * next;
+ struct node_block * prev;
+};
+
+typedef struct node_block node_block;
node_inl* parse_inlines(strbuf *input, reference** refmap);
void free_inlines(node_inl* e);
@@ -112,18 +115,18 @@ void free_reference_map(reference **refmap);
void add_reference(reference** refmap, reference* ref);
void unescape_buffer(strbuf *buf);
-extern block* make_document();
-extern block* add_child(block* parent,
+extern node_block* make_document();
+extern node_block* add_child(node_block* parent,
int block_type, int start_line, int start_column);
-void free_blocks(block* e);
+void free_blocks(node_block* e);
-extern block *stmd_parse_document(const unsigned char *buffer, size_t len);
-extern block *stmd_parse_file(FILE *f);
+extern node_block *stmd_parse_document(const unsigned char *buffer, size_t len);
+extern node_block *stmd_parse_file(FILE *f);
void print_inlines(node_inl* ils, int indent);
-void print_blocks(block* blk, int indent);
+void print_blocks(node_block* blk, int indent);
-void blocks_to_html(strbuf *html, block *b, bool tight);
+void blocks_to_html(strbuf *html, node_block *b, bool tight);
void inlines_to_html(strbuf *html, node_inl *b);
void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
--
cgit v1.2.3
From 806ff17755c90579afc68914b251b80e2f8c4b77 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 18:56:52 +0200
Subject: Rename block literals
---
src/blocks.c | 110 ++++++++++++++++++++++++++++----------------------------
src/html/html.c | 26 +++++++-------
src/print.c | 24 ++++++-------
src/stmd.h | 43 +++++++++++-----------
4 files changed, 100 insertions(+), 103 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index d74ceb2..f671b5e 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -38,7 +38,7 @@ static node_block* make_block(int tag, int start_line, int start_column)
// Create a root document node_block.
extern node_block* make_document()
{
- node_block * e = make_block(document, 1, 1);
+ node_block * e = make_block(BLOCK_DOCUMENT, 1, 1);
reference * map = NULL;
reference ** refmap;
refmap = (reference**) malloc(sizeof(reference*));
@@ -68,18 +68,18 @@ bool is_blank(strbuf *s, int offset)
static inline bool can_contain(int parent_type, int child_type)
{
- return ( parent_type == document ||
- parent_type == block_quote ||
- parent_type == list_item ||
- (parent_type == list && child_type == list_item) );
+ return ( parent_type == BLOCK_DOCUMENT ||
+ parent_type == BLOCK_BQUOTE ||
+ parent_type == BLOCK_LIST_ITEM ||
+ (parent_type == BLOCK_LIST && child_type == BLOCK_LIST_ITEM) );
}
static inline bool accepts_lines(int block_type)
{
- return (block_type == paragraph ||
- block_type == atx_header ||
- block_type == indented_code ||
- block_type == fenced_code);
+ return (block_type == BLOCK_PARAGRAPH ||
+ block_type == BLOCK_ATX_HEADER ||
+ block_type == BLOCK_INDENTED_CODE ||
+ block_type == BLOCK_FENCED_CODE);
}
static void add_line(node_block* node_block, chunk *ch, int offset)
@@ -116,7 +116,7 @@ static bool ends_with_blank_line(node_block* node_block)
if (node_block->last_line_blank) {
return true;
}
- if ((node_block->tag == list || node_block->tag == list_item) && node_block->last_child) {
+ if ((node_block->tag == BLOCK_LIST || node_block->tag == BLOCK_LIST_ITEM) && node_block->last_child) {
return ends_with_blank_line(node_block->last_child);
} else {
return false;
@@ -128,8 +128,8 @@ static int break_out_of_lists(node_block ** bptr, int line_number)
{
node_block * container = *bptr;
node_block * b = container->top;
- // find first containing list:
- while (b && b->tag != list) {
+ // find first containing BLOCK_LIST:
+ while (b && b->tag != BLOCK_LIST) {
b = b->last_child;
}
if (b) {
@@ -162,7 +162,7 @@ static void finalize(node_block* b, int line_number)
}
switch (b->tag) {
- case paragraph:
+ case BLOCK_PARAGRAPH:
pos = 0;
while (strbuf_at(&b->string_content, 0) == '[' &&
(pos = parse_reference(&b->string_content, b->top->attributes.refmap))) {
@@ -170,16 +170,16 @@ static void finalize(node_block* b, int line_number)
strbuf_drop(&b->string_content, pos);
}
if (is_blank(&b->string_content, 0)) {
- b->tag = reference_def;
+ b->tag = BLOCK_REFERENCE_DEF;
}
break;
- case indented_code:
+ case BLOCK_INDENTED_CODE:
remove_trailing_blank_lines(&b->string_content);
strbuf_putc(&b->string_content, '\n');
break;
- case fenced_code:
+ case BLOCK_FENCED_CODE:
// first line of contents becomes info
firstlinelen = strbuf_strchr(&b->string_content, '\n', 0);
@@ -196,7 +196,7 @@ static void finalize(node_block* b, int line_number)
unescape_buffer(&b->attributes.fenced_code_data.info);
break;
- case list: // determine tight/loose status
+ case BLOCK_LIST: // determine tight/loose status
b->attributes.list_data.tight = true; // tight by default
item = b->children;
@@ -266,9 +266,9 @@ extern void free_blocks(node_block* e)
next = e->next;
free_inlines(e->inline_content);
strbuf_free(&e->string_content);
- if (e->tag == fenced_code) {
+ if (e->tag == BLOCK_FENCED_CODE) {
strbuf_free(&e->attributes.fenced_code_data.info);
- } else if (e->tag == document) {
+ } else if (e->tag == BLOCK_DOCUMENT) {
free_reference_map(e->attributes.refmap);
}
free_blocks(e->children);
@@ -282,9 +282,9 @@ extern void free_blocks(node_block* e)
void process_inlines(node_block* cur, reference** refmap)
{
switch (cur->tag) {
- case paragraph:
- case atx_header:
- case setext_header:
+ case BLOCK_PARAGRAPH:
+ case BLOCK_ATX_HEADER:
+ case BLOCK_SETEXT_HEADER:
cur->inline_content = parse_inlines(&cur->string_content, refmap);
// MEM
// strbuf_free(&cur->string_content);
@@ -507,7 +507,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
indent = first_nonspace - offset;
blank = peek_at(&input, first_nonspace) == '\n';
- if (container->tag == block_quote) {
+ if (container->tag == BLOCK_BQUOTE) {
matched = indent <= 3 && peek_at(&input, first_nonspace) == '>';
if (matched) {
offset = first_nonspace + 1;
@@ -517,7 +517,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
all_matched = false;
}
- } else if (container->tag == list_item) {
+ } else if (container->tag == BLOCK_LIST_ITEM) {
if (indent >= container->attributes.list_data.marker_offset +
container->attributes.list_data.padding) {
@@ -529,7 +529,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
all_matched = false;
}
- } else if (container->tag == indented_code) {
+ } else if (container->tag == BLOCK_INDENTED_CODE) {
if (indent >= CODE_INDENT) {
offset += CODE_INDENT;
@@ -539,13 +539,13 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
all_matched = false;
}
- } else if (container->tag == atx_header ||
- container->tag == setext_header) {
+ } else if (container->tag == BLOCK_ATX_HEADER ||
+ container->tag == BLOCK_SETEXT_HEADER) {
// a header can never contain more than one line
all_matched = false;
- } else if (container->tag == fenced_code) {
+ } else if (container->tag == BLOCK_FENCED_CODE) {
// skip optional spaces of fence offset
i = container->attributes.fenced_code_data.fence_offset;
@@ -554,13 +554,13 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
i--;
}
- } else if (container->tag == html_block) {
+ } else if (container->tag == BLOCK_HTML) {
if (blank) {
all_matched = false;
}
- } else if (container->tag == paragraph) {
+ } else if (container->tag == BLOCK_PARAGRAPH) {
if (blank) {
container->last_line_blank = true;
@@ -583,8 +583,8 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
}
// unless last matched container is code node_block, try new container starts:
- while (container->tag != fenced_code && container->tag != indented_code &&
- container->tag != html_block) {
+ while (container->tag != BLOCK_FENCED_CODE && container->tag != BLOCK_INDENTED_CODE &&
+ container->tag != BLOCK_HTML) {
first_nonspace = offset;
while (peek_at(&input, first_nonspace) == ' ')
@@ -594,9 +594,9 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
blank = peek_at(&input, first_nonspace) == '\n';
if (indent >= CODE_INDENT) {
- if (cur->tag != paragraph && !blank) {
+ if (cur->tag != BLOCK_PARAGRAPH && !blank) {
offset += CODE_INDENT;
- container = add_child(container, indented_code, line_number, offset + 1);
+ container = add_child(container, BLOCK_INDENTED_CODE, line_number, offset + 1);
} else { // indent > 4 in lazy line
break;
}
@@ -607,12 +607,12 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
// optional following character
if (peek_at(&input, offset) == ' ')
offset++;
- container = add_child(container, block_quote, line_number, offset + 1);
+ container = add_child(container, BLOCK_BQUOTE, line_number, offset + 1);
} else if ((matched = scan_atx_header_start(&input, first_nonspace))) {
offset = first_nonspace + matched;
- container = add_child(container, atx_header, line_number, offset + 1);
+ container = add_child(container, BLOCK_ATX_HEADER, line_number, offset + 1);
int hashpos = chunk_strchr(&input, '#', first_nonspace);
int level = 0;
@@ -625,7 +625,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
} else if ((matched = scan_open_code_fence(&input, first_nonspace))) {
- container = add_child(container, fenced_code, line_number, first_nonspace + 1);
+ container = add_child(container, BLOCK_FENCED_CODE, line_number, first_nonspace + 1);
container->attributes.fenced_code_data.fence_char = peek_at(&input, first_nonspace);
container->attributes.fenced_code_data.fence_length = matched;
container->attributes.fenced_code_data.fence_offset = first_nonspace - offset;
@@ -633,24 +633,24 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
} else if ((matched = scan_html_block_tag(&input, first_nonspace))) {
- container = add_child(container, html_block, line_number, first_nonspace + 1);
+ container = add_child(container, BLOCK_HTML, line_number, first_nonspace + 1);
// note, we don't adjust offset because the tag is part of the text
- } else if (container->tag == paragraph &&
+ } else if (container->tag == BLOCK_PARAGRAPH &&
(lev = scan_setext_header_line(&input, first_nonspace)) &&
// check that there is only one line in the paragraph:
strbuf_strrchr(&container->string_content, '\n',
strbuf_len(&container->string_content) - 2) < 0) {
- container->tag = setext_header;
+ container->tag = BLOCK_SETEXT_HEADER;
container->attributes.header_level = lev;
offset = input.len - 1;
- } else if (!(container->tag == paragraph && !all_matched) &&
+ } else if (!(container->tag == BLOCK_PARAGRAPH && !all_matched) &&
(matched = scan_hrule(&input, first_nonspace))) {
// it's only now that we know the line is not part of a setext header:
- container = add_child(container, hrule, line_number, first_nonspace + 1);
+ container = add_child(container, BLOCK_HRULE, line_number, first_nonspace + 1);
finalize(container, line_number);
container = container->parent;
offset = input.len - 1;
@@ -679,15 +679,15 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
data->marker_offset = indent;
- if (container->tag != list ||
+ if (container->tag != BLOCK_LIST ||
!lists_match(container->attributes.list_data, *data)) {
- container = add_child(container, list, line_number,
+ container = add_child(container, BLOCK_LIST, line_number,
first_nonspace + 1);
container->attributes.list_data = *data;
}
// add the list item
- container = add_child(container, list_item, line_number,
+ container = add_child(container, BLOCK_LIST_ITEM, line_number,
first_nonspace + 1);
/* TODO: static */
container->attributes.list_data = *data;
@@ -718,9 +718,9 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
// lists or breaking out of lists. we also don't set last_line_blank
// on an empty list item.
container->last_line_blank = (blank &&
- container->tag != block_quote &&
- container->tag != fenced_code &&
- !(container->tag == list_item &&
+ container->tag != BLOCK_BQUOTE &&
+ container->tag != BLOCK_FENCED_CODE &&
+ !(container->tag == BLOCK_LIST_ITEM &&
container->children == NULL &&
container->start_line == line_number));
@@ -733,7 +733,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
if (cur != last_matched_container &&
container == last_matched_container &&
!blank &&
- cur->tag == paragraph &&
+ cur->tag == BLOCK_PARAGRAPH &&
strbuf_len(&cur->string_content) > 0) {
add_line(cur, &input, offset);
@@ -747,11 +747,11 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
assert(cur != NULL);
}
- if (container->tag == indented_code) {
+ if (container->tag == BLOCK_INDENTED_CODE) {
add_line(container, &input, offset);
- } else if (container->tag == fenced_code) {
+ } else if (container->tag == BLOCK_FENCED_CODE) {
matched = 0;
if (indent <= 3 &&
@@ -769,7 +769,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
add_line(container, &input, offset);
}
- } else if (container->tag == html_block) {
+ } else if (container->tag == BLOCK_HTML) {
add_line(container, &input, offset);
@@ -777,7 +777,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
// ??? do nothing
- } else if (container->tag == atx_header) {
+ } else if (container->tag == BLOCK_ATX_HEADER) {
chop_trailing_hashtags(&input);
add_line(container, &input, first_nonspace);
@@ -788,10 +788,10 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
add_line(container, &input, first_nonspace);
- } else if (container->tag != hrule && container->tag != setext_header) {
+ } else if (container->tag != BLOCK_HRULE && container->tag != BLOCK_SETEXT_HEADER) {
// create paragraph container for line
- container = add_child(container, paragraph, line_number, first_nonspace + 1);
+ container = add_child(container, BLOCK_PARAGRAPH, line_number, first_nonspace + 1);
add_line(container, &input, first_nonspace);
} else {
diff --git a/src/html/html.c b/src/html/html.c
index 6041fde..758ec80 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -39,11 +39,11 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
while(b != NULL) {
switch(b->tag) {
- case document:
+ case BLOCK_DOCUMENT:
blocks_to_html(html, b->children, false);
break;
- case paragraph:
+ case BLOCK_PARAGRAPH:
if (tight) {
inlines_to_html(html, b->inline_content);
} else {
@@ -54,14 +54,14 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
}
break;
- case block_quote:
+ case BLOCK_BQUOTE:
cr(html);
strbuf_puts(html, "\n");
blocks_to_html(html, b->children, false);
strbuf_puts(html, "
\n");
break;
- case list_item:
+ case BLOCK_LIST_ITEM:
cr(html);
strbuf_puts(html, "");
blocks_to_html(html, b->children, tight);
@@ -69,7 +69,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
strbuf_puts(html, "\n");
break;
- case list:
+ case BLOCK_LIST:
// make sure a list starts at the beginning of the line:
cr(html);
data = &(b->attributes.list_data);
@@ -87,21 +87,21 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
strbuf_putc(html, '\n');
break;
- case atx_header:
- case setext_header:
+ case BLOCK_ATX_HEADER:
+ case BLOCK_SETEXT_HEADER:
cr(html);
strbuf_printf(html, "", b->attributes.header_level);
inlines_to_html(html, b->inline_content);
strbuf_printf(html, "\n", b->attributes.header_level);
break;
- case indented_code:
- case fenced_code:
+ case BLOCK_INDENTED_CODE:
+ case BLOCK_FENCED_CODE:
cr(html);
strbuf_puts(html, "tag == fenced_code) {
+ if (b->tag == BLOCK_FENCED_CODE) {
strbuf *info = &b->attributes.fenced_code_data.info;
if (strbuf_len(info) > 0) {
@@ -121,15 +121,15 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
strbuf_puts(html, "
\n");
break;
- case html_block:
+ case BLOCK_HTML:
strbuf_put(html, b->string_content.ptr, b->string_content.size);
break;
- case hrule:
+ case BLOCK_HRULE:
strbuf_puts(html, "
\n");
break;
- case reference_def:
+ case BLOCK_REFERENCE_DEF:
break;
default:
diff --git a/src/print.c b/src/print.c
index 069d299..0ff86fa 100644
--- a/src/print.c
+++ b/src/print.c
@@ -45,20 +45,20 @@ extern void print_blocks(node_block* b, int indent)
}
switch(b->tag) {
- case document:
+ case BLOCK_DOCUMENT:
printf("document\n");
print_blocks(b->children, indent + 2);
break;
- case block_quote:
+ case BLOCK_BQUOTE:
printf("block_quote\n");
print_blocks(b->children, indent + 2);
break;
- case list_item:
+ case BLOCK_LIST_ITEM:
data = &(b->attributes.list_data);
printf("list_item\n");
print_blocks(b->children, indent + 2);
break;
- case list:
+ case BLOCK_LIST:
data = &(b->attributes.list_data);
if (data->list_type == ordered) {
printf("list (type=ordered tight=%s start=%d delim=%s)\n",
@@ -72,27 +72,27 @@ extern void print_blocks(node_block* b, int indent)
}
print_blocks(b->children, indent + 2);
break;
- case atx_header:
+ case BLOCK_ATX_HEADER:
printf("atx_header (level=%d)\n", b->attributes.header_level);
print_inlines(b->inline_content, indent + 2);
break;
- case setext_header:
+ case BLOCK_SETEXT_HEADER:
printf("setext_header (level=%d)\n", b->attributes.header_level);
print_inlines(b->inline_content, indent + 2);
break;
- case paragraph:
+ case BLOCK_PARAGRAPH:
printf("paragraph\n");
print_inlines(b->inline_content, indent + 2);
break;
- case hrule:
+ case BLOCK_HRULE:
printf("hrule\n");
break;
- case indented_code:
+ case BLOCK_INDENTED_CODE:
printf("indented_code ");
print_str(b->string_content.ptr, -1);
putchar('\n');
break;
- case fenced_code:
+ case BLOCK_FENCED_CODE:
printf("fenced_code length=%d info=",
b->attributes.fenced_code_data.fence_length);
print_str(b->attributes.fenced_code_data.info.ptr, -1);
@@ -100,12 +100,12 @@ extern void print_blocks(node_block* b, int indent)
print_str(b->string_content.ptr, -1);
putchar('\n');
break;
- case html_block:
+ case BLOCK_HTML:
printf("html_block ");
print_str(b->string_content.ptr, -1);
putchar('\n');
break;
- case reference_def:
+ case BLOCK_REFERENCE_DEF:
printf("reference_def\n");
break;
default:
diff --git a/src/stmd.h b/src/stmd.h
index 957ab03..65063fa 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -67,30 +67,29 @@ struct FencedCodeData {
strbuf info;
};
-struct node_block {
- enum {
- document,
- block_quote,
- list,
- list_item,
- fenced_code,
- indented_code,
- html_block,
- paragraph,
- atx_header,
- setext_header,
- hrule,
- reference_def
+typedef struct Block {
+ enum { BLOCK_DOCUMENT,
+ BLOCK_BQUOTE,
+ BLOCK_LIST,
+ BLOCK_LIST_ITEM,
+ BLOCK_FENCED_CODE,
+ BLOCK_INDENTED_CODE,
+ BLOCK_HTML,
+ BLOCK_PARAGRAPH,
+ BLOCK_ATX_HEADER,
+ BLOCK_SETEXT_HEADER,
+ BLOCK_HRULE,
+ BLOCK_REFERENCE_DEF
} tag;
int start_line;
int start_column;
int end_line;
bool open;
bool last_line_blank;
- struct node_block* children;
- struct node_block* last_child;
- struct node_block* parent;
- struct node_block* top;
+ struct Block* children;
+ struct Block* last_child;
+ struct Block* parent;
+ struct Block* top;
strbuf string_content;
node_inl* inline_content;
union {
@@ -99,11 +98,9 @@ struct node_block {
int header_level;
reference** refmap;
} attributes;
- struct node_block * next;
- struct node_block * prev;
-};
-
-typedef struct node_block node_block;
+ struct Block * next;
+ struct Block * prev;
+} node_block;
node_inl* parse_inlines(strbuf *input, reference** refmap);
void free_inlines(node_inl* e);
--
cgit v1.2.3
From 8308ed0259a9ee02c55070db656b389c7b4be71d Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 19:09:23 +0200
Subject: Formatting
---
src/stmd.h | 101 +++++++++++++++++++++++++++++++++----------------------------
1 file changed, 54 insertions(+), 47 deletions(-)
diff --git a/src/stmd.h b/src/stmd.h
index 65063fa..be65371 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -49,58 +49,65 @@ typedef struct reference reference;
// Types for blocks
struct ListData {
- enum { bullet,
- ordered } list_type;
- int marker_offset;
- int padding;
- int start;
- enum { period,
- parens } delimiter;
- unsigned char bullet_char;
- bool tight;
+ enum {
+ bullet,
+ ordered
+ } list_type;
+ int marker_offset;
+ int padding;
+ int start;
+ enum {
+ period,
+ parens
+ } delimiter;
+ unsigned char bullet_char;
+ bool tight;
};
struct FencedCodeData {
- int fence_length;
- int fence_offset;
- char fence_char;
- strbuf info;
+ int fence_length;
+ int fence_offset;
+ char fence_char;
+ strbuf info;
+};
+
+struct node_block {
+ enum {
+ BLOCK_DOCUMENT,
+ BLOCK_BQUOTE,
+ BLOCK_LIST,
+ BLOCK_LIST_ITEM,
+ BLOCK_FENCED_CODE,
+ BLOCK_INDENTED_CODE,
+ BLOCK_HTML,
+ BLOCK_PARAGRAPH,
+ BLOCK_ATX_HEADER,
+ BLOCK_SETEXT_HEADER,
+ BLOCK_HRULE,
+ BLOCK_REFERENCE_DEF
+ } tag;
+ int start_line;
+ int start_column;
+ int end_line;
+ bool open;
+ bool last_line_blank;
+ struct node_block* children;
+ struct node_block* last_child;
+ struct node_block* parent;
+ struct node_block* top;
+ strbuf string_content;
+ node_inl* inline_content;
+ union {
+ struct ListData list_data;
+ struct FencedCodeData fenced_code_data;
+ int header_level;
+ reference** refmap;
+ } attributes;
+ struct node_block * next;
+ struct node_block * prev;
};
-typedef struct Block {
- enum { BLOCK_DOCUMENT,
- BLOCK_BQUOTE,
- BLOCK_LIST,
- BLOCK_LIST_ITEM,
- BLOCK_FENCED_CODE,
- BLOCK_INDENTED_CODE,
- BLOCK_HTML,
- BLOCK_PARAGRAPH,
- BLOCK_ATX_HEADER,
- BLOCK_SETEXT_HEADER,
- BLOCK_HRULE,
- BLOCK_REFERENCE_DEF
- } tag;
- int start_line;
- int start_column;
- int end_line;
- bool open;
- bool last_line_blank;
- struct Block* children;
- struct Block* last_child;
- struct Block* parent;
- struct Block* top;
- strbuf string_content;
- node_inl* inline_content;
- union {
- struct ListData list_data;
- struct FencedCodeData fenced_code_data;
- int header_level;
- reference** refmap;
- } attributes;
- struct Block * next;
- struct Block * prev;
-} node_block;
+typedef struct node_block node_block;
node_inl* parse_inlines(strbuf *input, reference** refmap);
void free_inlines(node_inl* e);
--
cgit v1.2.3
From add5dd1b9a9ba8c58cdc6ca0bb62d287acb56278 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 19:40:27 +0200
Subject: Remove warnings
---
Makefile | 4 ++--
src/inlines.c | 17 +++++++++++++++--
src/scanners.re | 41 ++++++++++++++++++++++++-----------------
3 files changed, 41 insertions(+), 21 deletions(-)
diff --git a/Makefile b/Makefile
index ed4ddd5..0d2eb8b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=-g -O3 -Wall -Wextra -Wno-unused-variable -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-g -O3 -Wall -Wno-unused-variable # -Werror
+CFLAGS=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS=-g -O3 -Wall -Werror
SRCDIR=src
DATADIR=data
diff --git a/src/inlines.c b/src/inlines.c
index 6bb89da..5e0f3e5 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -108,13 +108,26 @@ extern void add_reference(reference** refmap, reference* ref)
}
}
+static unsigned char *bufdup(const unsigned char *buf)
+{
+ unsigned char *new = NULL;
+
+ if (!buf) {
+ int len = strlen((char *)buf);
+ new = malloc(len + 1);
+ memcpy(new, buf, len + 1);
+ }
+
+ return new;
+}
+
inline static node_inl* make_link_from_reference(node_inl* label, reference *ref)
{
node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = INL_LINK;
e->content.linkable.label = label;
- e->content.linkable.url = strdup(ref->url);
- e->content.linkable.title = ref->title ? strdup(ref->title) : NULL;
+ e->content.linkable.url = bufdup(ref->url);
+ e->content.linkable.title = bufdup(ref->title);
e->next = NULL;
return e;
}
diff --git a/src/scanners.re b/src/scanners.re
index 71103f6..28aba9d 100644
--- a/src/scanners.re
+++ b/src/scanners.re
@@ -1,9 +1,5 @@
#include
-#define SCAN_DATA \
- const unsigned char *marker = NULL; \
- const unsigned char *start = p; \
-
/*!re2c
re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = p;
@@ -61,7 +57,8 @@
// Try to match URI autolink after first <, returning number of chars matched.
extern int _scan_autolink_uri(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
scheme [:]([^\x00-\x20<>\\]|escaped_char)*[>] { return (p - start); }
.? { return 0; }
@@ -71,7 +68,8 @@ extern int _scan_autolink_uri(const unsigned char *p)
// Try to match email autolink after first <, returning num of chars matched.
extern int _scan_autolink_email(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+
[@]
@@ -85,7 +83,8 @@ extern int _scan_autolink_email(const unsigned char *p)
// Try to match an HTML tag after first <, returning num of chars matched.
extern int _scan_html_tag(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
htmltag { return (p - start); }
.? { return 0; }
@@ -96,7 +95,8 @@ extern int _scan_html_tag(const unsigned char *p)
// returning num of chars matched.
extern int _scan_html_block_tag(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
[<] [/] blocktagname (spacechar | [>]) { return (p - start); }
[<] blocktagname (spacechar | [/>]) { return (p - start); }
@@ -111,7 +111,8 @@ extern int _scan_html_block_tag(const unsigned char *p)
// Newlines aren't ever allowed.
extern int _scan_link_url(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
[ \n]* [<] ([^<>\n\\\x00] | escaped_char | [\\])* [>] { return (p - start); }
[ \n]* (reg_char+ | escaped_char | in_parens_nosp)* { return (p - start); }
@@ -124,7 +125,8 @@ extern int _scan_link_url(const unsigned char *p)
// level of internal nesting (quotes within quotes).
extern int _scan_link_title(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
["] (escaped_char|[^"\x00])* ["] { return (p - start); }
['] (escaped_char|[^'\x00])* ['] { return (p - start); }
@@ -136,7 +138,7 @@ extern int _scan_link_title(const unsigned char *p)
// Match space characters, including newlines.
extern int _scan_spacechars(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *start = p; \
/*!re2c
[ \t\n]* { return (p - start); }
. { return 0; }
@@ -146,7 +148,8 @@ extern int _scan_spacechars(const unsigned char *p)
// Match ATX header start.
extern int _scan_atx_header_start(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
[#]{1,6} ([ ]+|[\n]) { return (p - start); }
.? { return 0; }
@@ -157,7 +160,7 @@ extern int _scan_atx_header_start(const unsigned char *p)
// 2 for level-2, 0 for no match.
extern int _scan_setext_header_line(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
/*!re2c
[=]+ [ ]* [\n] { return 1; }
[-]+ [ ]* [\n] { return 2; }
@@ -170,7 +173,8 @@ extern int _scan_setext_header_line(const unsigned char *p)
// spaces between the hyphens or asterisks."
extern int _scan_hrule(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
([*][ ]*){3,} [ \t]* [\n] { return (p - start); }
([_][ ]*){3,} [ \t]* [\n] { return (p - start); }
@@ -182,7 +186,8 @@ extern int _scan_hrule(const unsigned char *p)
// Scan an opening code fence.
extern int _scan_open_code_fence(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
[`]{3,} / [^`\n\x00]*[\n] { return (p - start); }
[~]{3,} / [^~\n\x00]*[\n] { return (p - start); }
@@ -193,7 +198,8 @@ extern int _scan_open_code_fence(const unsigned char *p)
// Scan a closing code fence with length at least len.
extern int _scan_close_code_fence(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
([`]{3,} | [~]{3,}) / spacechar* [\n] { return (p - start); }
.? { return 0; }
@@ -204,7 +210,8 @@ extern int _scan_close_code_fence(const unsigned char *p)
// Returns number of chars matched.
extern int _scan_entity(const unsigned char *p)
{
- SCAN_DATA;
+ const unsigned char *marker = NULL;
+ const unsigned char *start = p;
/*!re2c
[&] ([#] ([Xx][A-Fa-f0-9]{1,8}|[0-9]{1,8}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]
{ return (p - start); }
--
cgit v1.2.3
From d260c800c90e024714a6d84e28ac2caea70866e7 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 20:04:12 +0200
Subject: This spec was correct
---
spec.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spec.txt b/spec.txt
index a353d56..616cb96 100644
--- a/spec.txt
+++ b/spec.txt
@@ -3688,7 +3688,7 @@ raw HTML:
.
.
-http://google.com?find=\*
+http://google.com?find=\*
.
.
--
cgit v1.2.3
From 278b89d092cae8fe9cdd6346c69512886d36abbd Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 4 Sep 2014 20:04:21 +0200
Subject: Silly me
---
src/inlines.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/inlines.c b/src/inlines.c
index 5e0f3e5..6b17027 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -112,7 +112,7 @@ static unsigned char *bufdup(const unsigned char *buf)
{
unsigned char *new = NULL;
- if (!buf) {
+ if (buf) {
int len = strlen((char *)buf);
new = malloc(len + 1);
memcpy(new, buf, len + 1);
--
cgit v1.2.3
From 61e3e606e64221eaa5cf3d83dc598d5a42818d10 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Sat, 6 Sep 2014 20:48:05 +0200
Subject: UTF8-aware detabbing and entity handling
---
Makefile | 13 ++++++-----
src/blocks.c | 35 ++++++------------------------
src/html/houdini.h | 2 ++
src/html/html.c | 1 -
src/inlines.c | 63 ++++++++++++++++++++++--------------------------------
src/print.c | 5 -----
src/stmd.h | 3 ---
src/utf8.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------
8 files changed, 95 insertions(+), 86 deletions(-)
diff --git a/Makefile b/Makefile
index 0d2eb8b..b5e487d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-g -O3 -Wall -Werror
+CFLAGS=-g -pg -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS=-g -pg -O3 -Wall -Werror
SRCDIR=src
DATADIR=data
@@ -41,11 +41,11 @@ testjs: spec.txt
benchjs:
node js/bench.js ${BENCHINP}
-HTML_OBJ=$(SRCDIR)/html/html.o $(SRCDIR)/html/houdini_href_e.o $(SRCDIR)/html/houdini_html_e.o
+HTML_OBJ=$(SRCDIR)/html/html.o $(SRCDIR)/html/houdini_href_e.o $(SRCDIR)/html/houdini_html_e.o $(SRCDIR)/html/houdini_html_u.o
STMD_OBJ=$(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/utf8.o
-$(PROG): $(SRCDIR)/main.c $(HTML_OBJ) $(STMD_OBJ)
- $(CC) $(LDFLAGS) -o $@ $^
+$(PROG): $(SRCDIR)/html/html_unescape.h $(SRCDIR)/case_fold_switch.inc $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c
+ $(CC) $(LDFLAGS) -o $@ $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c
$(SRCDIR)/scanners.c: $(SRCDIR)/scanners.re
re2c --case-insensitive -bis $< > $@ || (rm $@ && false)
@@ -53,6 +53,9 @@ $(SRCDIR)/scanners.c: $(SRCDIR)/scanners.re
$(SRCDIR)/case_fold_switch.inc: $(DATADIR)/CaseFolding-3.2.0.txt
perl mkcasefold.pl < $< > $@
+$(SRCDIR)/html/html_unescape.h: $(SRCDIR)/html/html_unescape.gperf
+ gperf -I -t -N find_entity -H hash_entity -K entity -C -l --null-strings -m5 $< > $@
+
.PHONY: leakcheck clean fuzztest dingus upload
dingus:
diff --git a/src/blocks.c b/src/blocks.c
index f671b5e..8c7d49c 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -5,6 +5,8 @@
#include
#include "stmd.h"
+#include "utf8.h"
+#include "html/houdini.h"
#include "scanners.h"
#include "uthash.h"
@@ -184,7 +186,7 @@ static void finalize(node_block* b, int line_number)
firstlinelen = strbuf_strchr(&b->string_content, '\n', 0);
strbuf_init(&b->attributes.fenced_code_data.info, 0);
- strbuf_set(
+ houdini_unescape_html_f(
&b->attributes.fenced_code_data.info,
b->string_content.ptr,
firstlinelen
@@ -369,31 +371,6 @@ static int lists_match(struct ListData list_data,
list_data.bullet_char == item_data.bullet_char);
}
-static void expand_tabs(strbuf *ob, const unsigned char *line, size_t size)
-{
- size_t i = 0, tab = 0;
-
- while (i < size) {
- size_t org = i;
-
- while (i < size && line[i] != '\t') {
- i++; tab++;
- }
-
- if (i > org)
- strbuf_put(ob, line + org, i - org);
-
- if (i >= size)
- break;
-
- do {
- strbuf_putc(ob, ' '); tab++;
- } while (tab % 4);
-
- i++;
- }
-}
-
static node_block *finalize_document(node_block *document, int linenum)
{
while (document != document->top) {
@@ -415,7 +392,7 @@ extern node_block *stmd_parse_file(FILE *f)
node_block *document = make_document();
while (fgets((char *)buffer, sizeof(buffer), f)) {
- expand_tabs(&line, buffer, strlen((char *)buffer));
+ utf8proc_detab(&line, buffer, strlen((char *)buffer));
incorporate_line(&line, linenum, &document);
strbuf_clear(&line);
linenum++;
@@ -436,10 +413,10 @@ extern node_block *stmd_parse_document(const unsigned char *buffer, size_t len)
const unsigned char *eol = memchr(buffer, '\n', end - buffer);
if (!eol) {
- expand_tabs(&line, buffer, end - buffer);
+ utf8proc_detab(&line, buffer, end - buffer);
buffer = end;
} else {
- expand_tabs(&line, buffer, (eol - buffer) + 1);
+ utf8proc_detab(&line, buffer, (eol - buffer) + 1);
buffer += (eol - buffer) + 1;
}
diff --git a/src/html/houdini.h b/src/html/houdini.h
index 1e54d20..5fd690d 100644
--- a/src/html/houdini.h
+++ b/src/html/houdini.h
@@ -25,9 +25,11 @@ extern "C" {
#define HOUDINI_ESCAPED_SIZE(x) (((x) * 12) / 10)
#define HOUDINI_UNESCAPED_SIZE(x) (x)
+extern size_t houdini_unescape_ent(strbuf *ob, const uint8_t *src, size_t size);
extern int houdini_escape_html(strbuf *ob, const uint8_t *src, size_t size);
extern int houdini_escape_html0(strbuf *ob, const uint8_t *src, size_t size, int secure);
extern int houdini_unescape_html(strbuf *ob, const uint8_t *src, size_t size);
+extern void houdini_unescape_html_f(strbuf *ob, const uint8_t *src, size_t size);
extern int houdini_escape_xml(strbuf *ob, const uint8_t *src, size_t size);
extern int houdini_escape_uri(strbuf *ob, const uint8_t *src, size_t size);
extern int houdini_escape_url(strbuf *ob, const uint8_t *src, size_t size);
diff --git a/src/html/html.c b/src/html/html.c
index 758ec80..595dfcd 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -166,7 +166,6 @@ void inlines_to_html(strbuf *html, node_inl* ils)
break;
case INL_RAW_HTML:
- case INL_ENTITY:
strbuf_put(html,
ils->content.literal.data,
ils->content.literal.len);
diff --git a/src/inlines.c b/src/inlines.c
index 6b17027..7b27150 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -5,6 +5,8 @@
#include
#include "stmd.h"
+#include "html/houdini.h"
+#include "utf8.h"
#include "uthash.h"
#include "scanners.h"
@@ -176,7 +178,6 @@ inline static node_inl* make_simple(int t)
#define make_str(s) make_literal(INL_STRING, s)
#define make_code(s) make_literal(INL_CODE, s)
#define make_raw_html(s) make_literal(INL_RAW_HTML, s)
-#define make_entity(s) make_literal(INL_ENTITY, s)
#define make_linebreak() make_simple(INL_LINEBREAK)
#define make_softbreak() make_simple(INL_SOFTBREAK)
#define make_emph(contents) make_inlines(INL_EMPH, contents)
@@ -191,7 +192,6 @@ extern void free_inlines(node_inl* e)
case INL_STRING:
case INL_RAW_HTML:
case INL_CODE:
- case INL_ENTITY:
chunk_free(&e->content.literal);
break;
case INL_LINEBREAK:
@@ -540,45 +540,34 @@ static node_inl* handle_backslash(subject *subj)
// Assumes the subject has an '&' character at the current position.
static node_inl* handle_entity(subject* subj)
{
- int match;
- node_inl *result;
- match = scan_entity(&subj->input, subj->pos);
- if (match) {
- result = make_entity(chunk_dup(&subj->input, subj->pos, match));
- subj->pos += match;
- } else {
- advance(subj);
- result = make_str(chunk_literal("&"));
- }
- return result;
+ strbuf ent = GH_BUF_INIT;
+ size_t len;
+
+ advance(subj);
+
+ len = houdini_unescape_ent(&ent,
+ subj->input.data + subj->pos,
+ subj->input.len - subj->pos
+ );
+
+ if (len == 0)
+ return make_str(chunk_literal("&"));
+
+ subj->pos += len;
+ return make_str(chunk_buf_detach(&ent));
}
// Like make_str, but parses entities.
// Returns an inline sequence consisting of str and entity elements.
static node_inl *make_str_with_entities(chunk *content)
{
- node_inl *result = NULL;
- node_inl *new;
- int searchpos;
- char c;
- subject subj;
-
- subject_from_chunk(&subj, content, NULL);
+ strbuf unescaped = GH_BUF_INIT;
- while ((c = peek_char(&subj))) {
- switch (c) {
- case '&':
- new = handle_entity(&subj);
- break;
- default:
- searchpos = chunk_strchr(&subj.input, '&', subj.pos);
- new = make_str(chunk_dup(&subj.input, subj.pos, searchpos - subj.pos));
- subj.pos = searchpos;
- }
- result = append_inlines(result, new);
+ if (houdini_unescape_html(&unescaped, content->data, (size_t)content->len)) {
+ return make_str(chunk_buf_detach(&unescaped));
+ } else {
+ return make_str(*content);
}
-
- return result;
}
// Destructively unescape a string: remove backslashes before punctuation chars.
@@ -611,9 +600,9 @@ static unsigned char *clean_url(chunk *url, int is_email)
strbuf_puts(&buf, "mailto:");
if (url->data[0] == '<' && url->data[url->len - 1] == '>') {
- strbuf_put(&buf, url->data + 1, url->len - 2);
+ houdini_unescape_html_f(&buf, url->data + 1, url->len - 2);
} else {
- strbuf_put(&buf, url->data, url->len);
+ houdini_unescape_html_f(&buf, url->data, url->len);
}
unescape_buffer(&buf);
@@ -636,9 +625,9 @@ static unsigned char *clean_title(chunk *title)
if ((first == '\'' && last == '\'') ||
(first == '(' && last == ')') ||
(first == '"' && last == '"')) {
- strbuf_set(&buf, title->data + 1, title->len - 2);
+ houdini_unescape_html_f(&buf, title->data + 1, title->len - 2);
} else {
- strbuf_set(&buf, title->data, title->len);
+ houdini_unescape_html_f(&buf, title->data, title->len);
}
unescape_buffer(&buf);
diff --git a/src/print.c b/src/print.c
index 0ff86fa..9240dac 100644
--- a/src/print.c
+++ b/src/print.c
@@ -145,11 +145,6 @@ extern void print_inlines(node_inl* ils, int indent)
print_str(ils->content.literal.data, ils->content.literal.len);
putchar('\n');
break;
- case INL_ENTITY:
- printf("entity ");
- print_str(ils->content.literal.data, ils->content.literal.len);
- putchar('\n');
- break;
case INL_LINK:
case INL_IMAGE:
printf("%s url=", ils->tag == INL_LINK ? "link" : "image");
diff --git a/src/stmd.h b/src/stmd.h
index be65371..c80eeda 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -17,7 +17,6 @@ struct node_inl {
INL_LINEBREAK,
INL_CODE,
INL_RAW_HTML,
- INL_ENTITY,
INL_EMPH,
INL_STRONG,
INL_LINK,
@@ -133,6 +132,4 @@ void print_blocks(node_block* blk, int indent);
void blocks_to_html(strbuf *html, node_block *b, bool tight);
void inlines_to_html(strbuf *html, node_inl *b);
-void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
-
#endif
diff --git a/src/utf8.c b/src/utf8.c
index cebd872..12d7ba5 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -3,7 +3,7 @@
#include
#include
-#include "stmd.h"
+#include "utf8.h"
static const int8_t utf8proc_utf8class[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -23,6 +23,12 @@ static const int8_t utf8proc_utf8class[256] = {
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 };
+static void encode_unknown(strbuf *buf)
+{
+ static const unsigned char repl[] = {239, 191, 189};
+ strbuf_put(buf, repl, 3);
+}
+
ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len)
{
ssize_t length, i;
@@ -46,6 +52,46 @@ ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len)
return length;
}
+void utf8proc_detab(strbuf *ob, const unsigned char *line, size_t size)
+{
+ static const unsigned char whitespace[] = " ";
+
+ size_t i = 0, tab = 0;
+
+ while (i < size) {
+ size_t org = i;
+
+ while (i < size && line[i] != '\t' && line[i] <= 0x80) {
+ i++; tab++;
+ }
+
+ if (i > org)
+ strbuf_put(ob, line + org, i - org);
+
+ if (i >= size)
+ break;
+
+ if (line[i] == '\t') {
+ int numspaces = 4 - (tab % 4);
+ strbuf_put(ob, whitespace, numspaces);
+ i += 1;
+ tab += numspaces;
+ } else {
+ ssize_t charlen = utf8proc_charlen(line + i, size - i);
+
+ if (charlen < 0) {
+ encode_unknown(ob);
+ i++;
+ } else {
+ strbuf_put(ob, line + i, charlen);
+ i += charlen;
+ }
+
+ tab += 1;
+ }
+ }
+}
+
ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst)
{
ssize_t length;
@@ -89,9 +135,9 @@ void utf8proc_encode_char(int32_t uc, strbuf *buf)
unsigned char dst[4];
int len = 0;
- if (uc < 0x00) {
- assert(false);
- } else if (uc < 0x80) {
+ assert(uc >= 0);
+
+ if (uc < 0x80) {
dst[0] = uc;
len = 1;
} else if (uc < 0x800) {
@@ -116,7 +162,8 @@ void utf8proc_encode_char(int32_t uc, strbuf *buf)
dst[3] = 0x80 + (uc & 0x3F);
len = 4;
} else {
- assert(false);
+ encode_unknown(buf);
+ return;
}
strbuf_put(buf, dst, len);
@@ -133,7 +180,7 @@ void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len)
ssize_t char_len = utf8proc_iterate(str, len, &c);
if (char_len < 0) {
- bufpush(0xFFFD);
+ encode_unknown(dest);
continue;
}
--
cgit v1.2.3
From a5cf11dac52606141dd246f88d8c59688462e395 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Sat, 6 Sep 2014 20:48:54 +0200
Subject: Entity declarations
---
src/html/houdini_html_u.c | 99 +
src/html/html_unescape.gperf | 2131 +++++++++
src/html/html_unescape.h | 9746 ++++++++++++++++++++++++++++++++++++++++++
src/utf8.h | 12 +
4 files changed, 11988 insertions(+)
create mode 100644 src/html/houdini_html_u.c
create mode 100644 src/html/html_unescape.gperf
create mode 100644 src/html/html_unescape.h
create mode 100644 src/utf8.h
diff --git a/src/html/houdini_html_u.c b/src/html/houdini_html_u.c
new file mode 100644
index 0000000..762f980
--- /dev/null
+++ b/src/html/houdini_html_u.c
@@ -0,0 +1,99 @@
+#include
+#include
+#include
+
+#include "houdini.h"
+#include "utf8.h"
+#include "html_unescape.h"
+
+size_t
+houdini_unescape_ent(strbuf *ob, const uint8_t *src, size_t size)
+{
+ size_t i = 0;
+
+ if (size > 3 && src[0] == '#') {
+ int codepoint = 0;
+
+ if (_isdigit(src[1])) {
+ for (i = 1; i < size && _isdigit(src[i]); ++i)
+ codepoint = (codepoint * 10) + (src[i] - '0');
+ }
+
+ else if (src[1] == 'x' || src[1] == 'X') {
+ for (i = 2; i < size && _isxdigit(src[i]); ++i)
+ codepoint = (codepoint * 16) + ((src[i] | 32) % 39 - 9);
+ }
+
+ if (i < size && src[i] == ';') {
+ utf8proc_encode_char(codepoint, ob);
+ return i + 1;
+ }
+ }
+
+ else {
+ if (size > MAX_WORD_LENGTH)
+ size = MAX_WORD_LENGTH;
+
+ for (i = MIN_WORD_LENGTH; i < size; ++i) {
+ if (src[i] == ' ')
+ break;
+
+ if (src[i] == ';') {
+ const struct html_ent *entity = find_entity((char *)src, i);
+
+ if (entity != NULL) {
+ strbuf_put(ob, entity->utf8, entity->utf8_len);
+ return i + 1;
+ }
+
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+houdini_unescape_html(strbuf *ob, const uint8_t *src, size_t size)
+{
+ size_t i = 0, org, ent;
+
+ while (i < size) {
+ org = i;
+ while (i < size && src[i] != '&')
+ i++;
+
+ if (likely(i > org)) {
+ if (unlikely(org == 0)) {
+ if (i >= size)
+ return 0;
+
+ strbuf_grow(ob, HOUDINI_UNESCAPED_SIZE(size));
+ }
+
+ strbuf_put(ob, src + org, i - org);
+ }
+
+ /* escaping */
+ if (i >= size)
+ break;
+
+ i++;
+
+ ent = houdini_unescape_ent(ob, src + i, size - i);
+ i += ent;
+
+ /* not really an entity */
+ if (ent == 0)
+ strbuf_putc(ob, '&');
+ }
+
+ return 1;
+}
+
+void houdini_unescape_html_f(strbuf *ob, const uint8_t *src, size_t size)
+{
+ if (!houdini_unescape_html(ob, src, size))
+ strbuf_put(ob, src, size);
+}
diff --git a/src/html/html_unescape.gperf b/src/html/html_unescape.gperf
new file mode 100644
index 0000000..4d46f67
--- /dev/null
+++ b/src/html/html_unescape.gperf
@@ -0,0 +1,2131 @@
+struct html_ent {
+ const char *entity;
+ unsigned int utf8_len;
+ unsigned char utf8[4];
+};
+%%
+"Aacute", 2, {195, 129}
+"aacute", 2, {195, 161}
+"Abreve", 2, {196, 130}
+"abreve", 2, {196, 131}
+"ac", 3, {226, 136, 190}
+"acd", 3, {226, 136, 191}
+"acE", 3, {226, 136, 190}
+"Acirc", 2, {195, 130}
+"acirc", 2, {195, 162}
+"acute", 2, {194, 180}
+"Acy", 2, {208, 144}
+"acy", 2, {208, 176}
+"AElig", 2, {195, 134}
+"aelig", 2, {195, 166}
+"af", 3, {226, 129, 161}
+"Afr", 4, {240, 157, 148, 132}
+"afr", 4, {240, 157, 148, 158}
+"Agrave", 2, {195, 128}
+"agrave", 2, {195, 160}
+"alefsym", 3, {226, 132, 181}
+"aleph", 3, {226, 132, 181}
+"Alpha", 2, {206, 145}
+"alpha", 2, {206, 177}
+"Amacr", 2, {196, 128}
+"amacr", 2, {196, 129}
+"amalg", 3, {226, 168, 191}
+"amp", 1, {38}
+"AMP", 1, {38}
+"andand", 3, {226, 169, 149}
+"And", 3, {226, 169, 147}
+"and", 3, {226, 136, 167}
+"andd", 3, {226, 169, 156}
+"andslope", 3, {226, 169, 152}
+"andv", 3, {226, 169, 154}
+"ang", 3, {226, 136, 160}
+"ange", 3, {226, 166, 164}
+"angle", 3, {226, 136, 160}
+"angmsdaa", 3, {226, 166, 168}
+"angmsdab", 3, {226, 166, 169}
+"angmsdac", 3, {226, 166, 170}
+"angmsdad", 3, {226, 166, 171}
+"angmsdae", 3, {226, 166, 172}
+"angmsdaf", 3, {226, 166, 173}
+"angmsdag", 3, {226, 166, 174}
+"angmsdah", 3, {226, 166, 175}
+"angmsd", 3, {226, 136, 161}
+"angrt", 3, {226, 136, 159}
+"angrtvb", 3, {226, 138, 190}
+"angrtvbd", 3, {226, 166, 157}
+"angsph", 3, {226, 136, 162}
+"angst", 2, {195, 133}
+"angzarr", 3, {226, 141, 188}
+"Aogon", 2, {196, 132}
+"aogon", 2, {196, 133}
+"Aopf", 4, {240, 157, 148, 184}
+"aopf", 4, {240, 157, 149, 146}
+"apacir", 3, {226, 169, 175}
+"ap", 3, {226, 137, 136}
+"apE", 3, {226, 169, 176}
+"ape", 3, {226, 137, 138}
+"apid", 3, {226, 137, 139}
+"apos", 1, {39}
+"ApplyFunction", 3, {226, 129, 161}
+"approx", 3, {226, 137, 136}
+"approxeq", 3, {226, 137, 138}
+"Aring", 2, {195, 133}
+"aring", 2, {195, 165}
+"Ascr", 4, {240, 157, 146, 156}
+"ascr", 4, {240, 157, 146, 182}
+"Assign", 3, {226, 137, 148}
+"ast", 1, {42}
+"asymp", 3, {226, 137, 136}
+"asympeq", 3, {226, 137, 141}
+"Atilde", 2, {195, 131}
+"atilde", 2, {195, 163}
+"Auml", 2, {195, 132}
+"auml", 2, {195, 164}
+"awconint", 3, {226, 136, 179}
+"awint", 3, {226, 168, 145}
+"backcong", 3, {226, 137, 140}
+"backepsilon", 2, {207, 182}
+"backprime", 3, {226, 128, 181}
+"backsim", 3, {226, 136, 189}
+"backsimeq", 3, {226, 139, 141}
+"Backslash", 3, {226, 136, 150}
+"Barv", 3, {226, 171, 167}
+"barvee", 3, {226, 138, 189}
+"barwed", 3, {226, 140, 133}
+"Barwed", 3, {226, 140, 134}
+"barwedge", 3, {226, 140, 133}
+"bbrk", 3, {226, 142, 181}
+"bbrktbrk", 3, {226, 142, 182}
+"bcong", 3, {226, 137, 140}
+"Bcy", 2, {208, 145}
+"bcy", 2, {208, 177}
+"bdquo", 3, {226, 128, 158}
+"becaus", 3, {226, 136, 181}
+"because", 3, {226, 136, 181}
+"Because", 3, {226, 136, 181}
+"bemptyv", 3, {226, 166, 176}
+"bepsi", 2, {207, 182}
+"bernou", 3, {226, 132, 172}
+"Bernoullis", 3, {226, 132, 172}
+"Beta", 2, {206, 146}
+"beta", 2, {206, 178}
+"beth", 3, {226, 132, 182}
+"between", 3, {226, 137, 172}
+"Bfr", 4, {240, 157, 148, 133}
+"bfr", 4, {240, 157, 148, 159}
+"bigcap", 3, {226, 139, 130}
+"bigcirc", 3, {226, 151, 175}
+"bigcup", 3, {226, 139, 131}
+"bigodot", 3, {226, 168, 128}
+"bigoplus", 3, {226, 168, 129}
+"bigotimes", 3, {226, 168, 130}
+"bigsqcup", 3, {226, 168, 134}
+"bigstar", 3, {226, 152, 133}
+"bigtriangledown", 3, {226, 150, 189}
+"bigtriangleup", 3, {226, 150, 179}
+"biguplus", 3, {226, 168, 132}
+"bigvee", 3, {226, 139, 129}
+"bigwedge", 3, {226, 139, 128}
+"bkarow", 3, {226, 164, 141}
+"blacklozenge", 3, {226, 167, 171}
+"blacksquare", 3, {226, 150, 170}
+"blacktriangle", 3, {226, 150, 180}
+"blacktriangledown", 3, {226, 150, 190}
+"blacktriangleleft", 3, {226, 151, 130}
+"blacktriangleright", 3, {226, 150, 184}
+"blank", 3, {226, 144, 163}
+"blk12", 3, {226, 150, 146}
+"blk14", 3, {226, 150, 145}
+"blk34", 3, {226, 150, 147}
+"block", 3, {226, 150, 136}
+"bne", 1, {61}
+"bnequiv", 3, {226, 137, 161}
+"bNot", 3, {226, 171, 173}
+"bnot", 3, {226, 140, 144}
+"Bopf", 4, {240, 157, 148, 185}
+"bopf", 4, {240, 157, 149, 147}
+"bot", 3, {226, 138, 165}
+"bottom", 3, {226, 138, 165}
+"bowtie", 3, {226, 139, 136}
+"boxbox", 3, {226, 167, 137}
+"boxdl", 3, {226, 148, 144}
+"boxdL", 3, {226, 149, 149}
+"boxDl", 3, {226, 149, 150}
+"boxDL", 3, {226, 149, 151}
+"boxdr", 3, {226, 148, 140}
+"boxdR", 3, {226, 149, 146}
+"boxDr", 3, {226, 149, 147}
+"boxDR", 3, {226, 149, 148}
+"boxh", 3, {226, 148, 128}
+"boxH", 3, {226, 149, 144}
+"boxhd", 3, {226, 148, 172}
+"boxHd", 3, {226, 149, 164}
+"boxhD", 3, {226, 149, 165}
+"boxHD", 3, {226, 149, 166}
+"boxhu", 3, {226, 148, 180}
+"boxHu", 3, {226, 149, 167}
+"boxhU", 3, {226, 149, 168}
+"boxHU", 3, {226, 149, 169}
+"boxminus", 3, {226, 138, 159}
+"boxplus", 3, {226, 138, 158}
+"boxtimes", 3, {226, 138, 160}
+"boxul", 3, {226, 148, 152}
+"boxuL", 3, {226, 149, 155}
+"boxUl", 3, {226, 149, 156}
+"boxUL", 3, {226, 149, 157}
+"boxur", 3, {226, 148, 148}
+"boxuR", 3, {226, 149, 152}
+"boxUr", 3, {226, 149, 153}
+"boxUR", 3, {226, 149, 154}
+"boxv", 3, {226, 148, 130}
+"boxV", 3, {226, 149, 145}
+"boxvh", 3, {226, 148, 188}
+"boxvH", 3, {226, 149, 170}
+"boxVh", 3, {226, 149, 171}
+"boxVH", 3, {226, 149, 172}
+"boxvl", 3, {226, 148, 164}
+"boxvL", 3, {226, 149, 161}
+"boxVl", 3, {226, 149, 162}
+"boxVL", 3, {226, 149, 163}
+"boxvr", 3, {226, 148, 156}
+"boxvR", 3, {226, 149, 158}
+"boxVr", 3, {226, 149, 159}
+"boxVR", 3, {226, 149, 160}
+"bprime", 3, {226, 128, 181}
+"breve", 2, {203, 152}
+"Breve", 2, {203, 152}
+"brvbar", 2, {194, 166}
+"bscr", 4, {240, 157, 146, 183}
+"Bscr", 3, {226, 132, 172}
+"bsemi", 3, {226, 129, 143}
+"bsim", 3, {226, 136, 189}
+"bsime", 3, {226, 139, 141}
+"bsolb", 3, {226, 167, 133}
+"bsol", 1, {92}
+"bsolhsub", 3, {226, 159, 136}
+"bull", 3, {226, 128, 162}
+"bullet", 3, {226, 128, 162}
+"bump", 3, {226, 137, 142}
+"bumpE", 3, {226, 170, 174}
+"bumpe", 3, {226, 137, 143}
+"Bumpeq", 3, {226, 137, 142}
+"bumpeq", 3, {226, 137, 143}
+"Cacute", 2, {196, 134}
+"cacute", 2, {196, 135}
+"capand", 3, {226, 169, 132}
+"capbrcup", 3, {226, 169, 137}
+"capcap", 3, {226, 169, 139}
+"cap", 3, {226, 136, 169}
+"Cap", 3, {226, 139, 146}
+"capcup", 3, {226, 169, 135}
+"capdot", 3, {226, 169, 128}
+"CapitalDifferentialD", 3, {226, 133, 133}
+"caps", 3, {226, 136, 169}
+"caret", 3, {226, 129, 129}
+"caron", 2, {203, 135}
+"Cayleys", 3, {226, 132, 173}
+"ccaps", 3, {226, 169, 141}
+"Ccaron", 2, {196, 140}
+"ccaron", 2, {196, 141}
+"Ccedil", 2, {195, 135}
+"ccedil", 2, {195, 167}
+"Ccirc", 2, {196, 136}
+"ccirc", 2, {196, 137}
+"Cconint", 3, {226, 136, 176}
+"ccups", 3, {226, 169, 140}
+"ccupssm", 3, {226, 169, 144}
+"Cdot", 2, {196, 138}
+"cdot", 2, {196, 139}
+"cedil", 2, {194, 184}
+"Cedilla", 2, {194, 184}
+"cemptyv", 3, {226, 166, 178}
+"cent", 2, {194, 162}
+"centerdot", 2, {194, 183}
+"CenterDot", 2, {194, 183}
+"cfr", 4, {240, 157, 148, 160}
+"Cfr", 3, {226, 132, 173}
+"CHcy", 2, {208, 167}
+"chcy", 2, {209, 135}
+"check", 3, {226, 156, 147}
+"checkmark", 3, {226, 156, 147}
+"Chi", 2, {206, 167}
+"chi", 2, {207, 135}
+"circ", 2, {203, 134}
+"circeq", 3, {226, 137, 151}
+"circlearrowleft", 3, {226, 134, 186}
+"circlearrowright", 3, {226, 134, 187}
+"circledast", 3, {226, 138, 155}
+"circledcirc", 3, {226, 138, 154}
+"circleddash", 3, {226, 138, 157}
+"CircleDot", 3, {226, 138, 153}
+"circledR", 2, {194, 174}
+"circledS", 3, {226, 147, 136}
+"CircleMinus", 3, {226, 138, 150}
+"CirclePlus", 3, {226, 138, 149}
+"CircleTimes", 3, {226, 138, 151}
+"cir", 3, {226, 151, 139}
+"cirE", 3, {226, 167, 131}
+"cire", 3, {226, 137, 151}
+"cirfnint", 3, {226, 168, 144}
+"cirmid", 3, {226, 171, 175}
+"cirscir", 3, {226, 167, 130}
+"ClockwiseContourIntegral", 3, {226, 136, 178}
+"CloseCurlyDoubleQuote", 3, {226, 128, 157}
+"CloseCurlyQuote", 3, {226, 128, 153}
+"clubs", 3, {226, 153, 163}
+"clubsuit", 3, {226, 153, 163}
+"colon", 1, {58}
+"Colon", 3, {226, 136, 183}
+"Colone", 3, {226, 169, 180}
+"colone", 3, {226, 137, 148}
+"coloneq", 3, {226, 137, 148}
+"comma", 1, {44}
+"commat", 1, {64}
+"comp", 3, {226, 136, 129}
+"compfn", 3, {226, 136, 152}
+"complement", 3, {226, 136, 129}
+"complexes", 3, {226, 132, 130}
+"cong", 3, {226, 137, 133}
+"congdot", 3, {226, 169, 173}
+"Congruent", 3, {226, 137, 161}
+"conint", 3, {226, 136, 174}
+"Conint", 3, {226, 136, 175}
+"ContourIntegral", 3, {226, 136, 174}
+"copf", 4, {240, 157, 149, 148}
+"Copf", 3, {226, 132, 130}
+"coprod", 3, {226, 136, 144}
+"Coproduct", 3, {226, 136, 144}
+"copy", 2, {194, 169}
+"COPY", 2, {194, 169}
+"copysr", 3, {226, 132, 151}
+"CounterClockwiseContourIntegral", 3, {226, 136, 179}
+"crarr", 3, {226, 134, 181}
+"cross", 3, {226, 156, 151}
+"Cross", 3, {226, 168, 175}
+"Cscr", 4, {240, 157, 146, 158}
+"cscr", 4, {240, 157, 146, 184}
+"csub", 3, {226, 171, 143}
+"csube", 3, {226, 171, 145}
+"csup", 3, {226, 171, 144}
+"csupe", 3, {226, 171, 146}
+"ctdot", 3, {226, 139, 175}
+"cudarrl", 3, {226, 164, 184}
+"cudarrr", 3, {226, 164, 181}
+"cuepr", 3, {226, 139, 158}
+"cuesc", 3, {226, 139, 159}
+"cularr", 3, {226, 134, 182}
+"cularrp", 3, {226, 164, 189}
+"cupbrcap", 3, {226, 169, 136}
+"cupcap", 3, {226, 169, 134}
+"CupCap", 3, {226, 137, 141}
+"cup", 3, {226, 136, 170}
+"Cup", 3, {226, 139, 147}
+"cupcup", 3, {226, 169, 138}
+"cupdot", 3, {226, 138, 141}
+"cupor", 3, {226, 169, 133}
+"cups", 3, {226, 136, 170}
+"curarr", 3, {226, 134, 183}
+"curarrm", 3, {226, 164, 188}
+"curlyeqprec", 3, {226, 139, 158}
+"curlyeqsucc", 3, {226, 139, 159}
+"curlyvee", 3, {226, 139, 142}
+"curlywedge", 3, {226, 139, 143}
+"curren", 2, {194, 164}
+"curvearrowleft", 3, {226, 134, 182}
+"curvearrowright", 3, {226, 134, 183}
+"cuvee", 3, {226, 139, 142}
+"cuwed", 3, {226, 139, 143}
+"cwconint", 3, {226, 136, 178}
+"cwint", 3, {226, 136, 177}
+"cylcty", 3, {226, 140, 173}
+"dagger", 3, {226, 128, 160}
+"Dagger", 3, {226, 128, 161}
+"daleth", 3, {226, 132, 184}
+"darr", 3, {226, 134, 147}
+"Darr", 3, {226, 134, 161}
+"dArr", 3, {226, 135, 147}
+"dash", 3, {226, 128, 144}
+"Dashv", 3, {226, 171, 164}
+"dashv", 3, {226, 138, 163}
+"dbkarow", 3, {226, 164, 143}
+"dblac", 2, {203, 157}
+"Dcaron", 2, {196, 142}
+"dcaron", 2, {196, 143}
+"Dcy", 2, {208, 148}
+"dcy", 2, {208, 180}
+"ddagger", 3, {226, 128, 161}
+"ddarr", 3, {226, 135, 138}
+"DD", 3, {226, 133, 133}
+"dd", 3, {226, 133, 134}
+"DDotrahd", 3, {226, 164, 145}
+"ddotseq", 3, {226, 169, 183}
+"deg", 2, {194, 176}
+"Del", 3, {226, 136, 135}
+"Delta", 2, {206, 148}
+"delta", 2, {206, 180}
+"demptyv", 3, {226, 166, 177}
+"dfisht", 3, {226, 165, 191}
+"Dfr", 4, {240, 157, 148, 135}
+"dfr", 4, {240, 157, 148, 161}
+"dHar", 3, {226, 165, 165}
+"dharl", 3, {226, 135, 131}
+"dharr", 3, {226, 135, 130}
+"DiacriticalAcute", 2, {194, 180}
+"DiacriticalDot", 2, {203, 153}
+"DiacriticalDoubleAcute", 2, {203, 157}
+"DiacriticalGrave", 1, {96}
+"DiacriticalTilde", 2, {203, 156}
+"diam", 3, {226, 139, 132}
+"diamond", 3, {226, 139, 132}
+"Diamond", 3, {226, 139, 132}
+"diamondsuit", 3, {226, 153, 166}
+"diams", 3, {226, 153, 166}
+"die", 2, {194, 168}
+"DifferentialD", 3, {226, 133, 134}
+"digamma", 2, {207, 157}
+"disin", 3, {226, 139, 178}
+"div", 2, {195, 183}
+"divide", 2, {195, 183}
+"divideontimes", 3, {226, 139, 135}
+"divonx", 3, {226, 139, 135}
+"DJcy", 2, {208, 130}
+"djcy", 2, {209, 146}
+"dlcorn", 3, {226, 140, 158}
+"dlcrop", 3, {226, 140, 141}
+"dollar", 1, {36}
+"Dopf", 4, {240, 157, 148, 187}
+"dopf", 4, {240, 157, 149, 149}
+"Dot", 2, {194, 168}
+"dot", 2, {203, 153}
+"DotDot", 3, {226, 131, 156}
+"doteq", 3, {226, 137, 144}
+"doteqdot", 3, {226, 137, 145}
+"DotEqual", 3, {226, 137, 144}
+"dotminus", 3, {226, 136, 184}
+"dotplus", 3, {226, 136, 148}
+"dotsquare", 3, {226, 138, 161}
+"doublebarwedge", 3, {226, 140, 134}
+"DoubleContourIntegral", 3, {226, 136, 175}
+"DoubleDot", 2, {194, 168}
+"DoubleDownArrow", 3, {226, 135, 147}
+"DoubleLeftArrow", 3, {226, 135, 144}
+"DoubleLeftRightArrow", 3, {226, 135, 148}
+"DoubleLeftTee", 3, {226, 171, 164}
+"DoubleLongLeftArrow", 3, {226, 159, 184}
+"DoubleLongLeftRightArrow", 3, {226, 159, 186}
+"DoubleLongRightArrow", 3, {226, 159, 185}
+"DoubleRightArrow", 3, {226, 135, 146}
+"DoubleRightTee", 3, {226, 138, 168}
+"DoubleUpArrow", 3, {226, 135, 145}
+"DoubleUpDownArrow", 3, {226, 135, 149}
+"DoubleVerticalBar", 3, {226, 136, 165}
+"DownArrowBar", 3, {226, 164, 147}
+"downarrow", 3, {226, 134, 147}
+"DownArrow", 3, {226, 134, 147}
+"Downarrow", 3, {226, 135, 147}
+"DownArrowUpArrow", 3, {226, 135, 181}
+"DownBreve", 2, {204, 145}
+"downdownarrows", 3, {226, 135, 138}
+"downharpoonleft", 3, {226, 135, 131}
+"downharpoonright", 3, {226, 135, 130}
+"DownLeftRightVector", 3, {226, 165, 144}
+"DownLeftTeeVector", 3, {226, 165, 158}
+"DownLeftVectorBar", 3, {226, 165, 150}
+"DownLeftVector", 3, {226, 134, 189}
+"DownRightTeeVector", 3, {226, 165, 159}
+"DownRightVectorBar", 3, {226, 165, 151}
+"DownRightVector", 3, {226, 135, 129}
+"DownTeeArrow", 3, {226, 134, 167}
+"DownTee", 3, {226, 138, 164}
+"drbkarow", 3, {226, 164, 144}
+"drcorn", 3, {226, 140, 159}
+"drcrop", 3, {226, 140, 140}
+"Dscr", 4, {240, 157, 146, 159}
+"dscr", 4, {240, 157, 146, 185}
+"DScy", 2, {208, 133}
+"dscy", 2, {209, 149}
+"dsol", 3, {226, 167, 182}
+"Dstrok", 2, {196, 144}
+"dstrok", 2, {196, 145}
+"dtdot", 3, {226, 139, 177}
+"dtri", 3, {226, 150, 191}
+"dtrif", 3, {226, 150, 190}
+"duarr", 3, {226, 135, 181}
+"duhar", 3, {226, 165, 175}
+"dwangle", 3, {226, 166, 166}
+"DZcy", 2, {208, 143}
+"dzcy", 2, {209, 159}
+"dzigrarr", 3, {226, 159, 191}
+"Eacute", 2, {195, 137}
+"eacute", 2, {195, 169}
+"easter", 3, {226, 169, 174}
+"Ecaron", 2, {196, 154}
+"ecaron", 2, {196, 155}
+"Ecirc", 2, {195, 138}
+"ecirc", 2, {195, 170}
+"ecir", 3, {226, 137, 150}
+"ecolon", 3, {226, 137, 149}
+"Ecy", 2, {208, 173}
+"ecy", 2, {209, 141}
+"eDDot", 3, {226, 169, 183}
+"Edot", 2, {196, 150}
+"edot", 2, {196, 151}
+"eDot", 3, {226, 137, 145}
+"ee", 3, {226, 133, 135}
+"efDot", 3, {226, 137, 146}
+"Efr", 4, {240, 157, 148, 136}
+"efr", 4, {240, 157, 148, 162}
+"eg", 3, {226, 170, 154}
+"Egrave", 2, {195, 136}
+"egrave", 2, {195, 168}
+"egs", 3, {226, 170, 150}
+"egsdot", 3, {226, 170, 152}
+"el", 3, {226, 170, 153}
+"Element", 3, {226, 136, 136}
+"elinters", 3, {226, 143, 167}
+"ell", 3, {226, 132, 147}
+"els", 3, {226, 170, 149}
+"elsdot", 3, {226, 170, 151}
+"Emacr", 2, {196, 146}
+"emacr", 2, {196, 147}
+"empty", 3, {226, 136, 133}
+"emptyset", 3, {226, 136, 133}
+"EmptySmallSquare", 3, {226, 151, 187}
+"emptyv", 3, {226, 136, 133}
+"EmptyVerySmallSquare", 3, {226, 150, 171}
+"emsp13", 3, {226, 128, 132}
+"emsp14", 3, {226, 128, 133}
+"emsp", 3, {226, 128, 131}
+"ENG", 2, {197, 138}
+"eng", 2, {197, 139}
+"ensp", 3, {226, 128, 130}
+"Eogon", 2, {196, 152}
+"eogon", 2, {196, 153}
+"Eopf", 4, {240, 157, 148, 188}
+"eopf", 4, {240, 157, 149, 150}
+"epar", 3, {226, 139, 149}
+"eparsl", 3, {226, 167, 163}
+"eplus", 3, {226, 169, 177}
+"epsi", 2, {206, 181}
+"Epsilon", 2, {206, 149}
+"epsilon", 2, {206, 181}
+"epsiv", 2, {207, 181}
+"eqcirc", 3, {226, 137, 150}
+"eqcolon", 3, {226, 137, 149}
+"eqsim", 3, {226, 137, 130}
+"eqslantgtr", 3, {226, 170, 150}
+"eqslantless", 3, {226, 170, 149}
+"Equal", 3, {226, 169, 181}
+"equals", 1, {61}
+"EqualTilde", 3, {226, 137, 130}
+"equest", 3, {226, 137, 159}
+"Equilibrium", 3, {226, 135, 140}
+"equiv", 3, {226, 137, 161}
+"equivDD", 3, {226, 169, 184}
+"eqvparsl", 3, {226, 167, 165}
+"erarr", 3, {226, 165, 177}
+"erDot", 3, {226, 137, 147}
+"escr", 3, {226, 132, 175}
+"Escr", 3, {226, 132, 176}
+"esdot", 3, {226, 137, 144}
+"Esim", 3, {226, 169, 179}
+"esim", 3, {226, 137, 130}
+"Eta", 2, {206, 151}
+"eta", 2, {206, 183}
+"ETH", 2, {195, 144}
+"eth", 2, {195, 176}
+"Euml", 2, {195, 139}
+"euml", 2, {195, 171}
+"euro", 3, {226, 130, 172}
+"excl", 1, {33}
+"exist", 3, {226, 136, 131}
+"Exists", 3, {226, 136, 131}
+"expectation", 3, {226, 132, 176}
+"exponentiale", 3, {226, 133, 135}
+"ExponentialE", 3, {226, 133, 135}
+"fallingdotseq", 3, {226, 137, 146}
+"Fcy", 2, {208, 164}
+"fcy", 2, {209, 132}
+"female", 3, {226, 153, 128}
+"ffilig", 3, {239, 172, 131}
+"fflig", 3, {239, 172, 128}
+"ffllig", 3, {239, 172, 132}
+"Ffr", 4, {240, 157, 148, 137}
+"ffr", 4, {240, 157, 148, 163}
+"filig", 3, {239, 172, 129}
+"FilledSmallSquare", 3, {226, 151, 188}
+"FilledVerySmallSquare", 3, {226, 150, 170}
+"fjlig", 1, {102}
+"flat", 3, {226, 153, 173}
+"fllig", 3, {239, 172, 130}
+"fltns", 3, {226, 150, 177}
+"fnof", 2, {198, 146}
+"Fopf", 4, {240, 157, 148, 189}
+"fopf", 4, {240, 157, 149, 151}
+"forall", 3, {226, 136, 128}
+"ForAll", 3, {226, 136, 128}
+"fork", 3, {226, 139, 148}
+"forkv", 3, {226, 171, 153}
+"Fouriertrf", 3, {226, 132, 177}
+"fpartint", 3, {226, 168, 141}
+"frac12", 2, {194, 189}
+"frac13", 3, {226, 133, 147}
+"frac14", 2, {194, 188}
+"frac15", 3, {226, 133, 149}
+"frac16", 3, {226, 133, 153}
+"frac18", 3, {226, 133, 155}
+"frac23", 3, {226, 133, 148}
+"frac25", 3, {226, 133, 150}
+"frac34", 2, {194, 190}
+"frac35", 3, {226, 133, 151}
+"frac38", 3, {226, 133, 156}
+"frac45", 3, {226, 133, 152}
+"frac56", 3, {226, 133, 154}
+"frac58", 3, {226, 133, 157}
+"frac78", 3, {226, 133, 158}
+"frasl", 3, {226, 129, 132}
+"frown", 3, {226, 140, 162}
+"fscr", 4, {240, 157, 146, 187}
+"Fscr", 3, {226, 132, 177}
+"gacute", 2, {199, 181}
+"Gamma", 2, {206, 147}
+"gamma", 2, {206, 179}
+"Gammad", 2, {207, 156}
+"gammad", 2, {207, 157}
+"gap", 3, {226, 170, 134}
+"Gbreve", 2, {196, 158}
+"gbreve", 2, {196, 159}
+"Gcedil", 2, {196, 162}
+"Gcirc", 2, {196, 156}
+"gcirc", 2, {196, 157}
+"Gcy", 2, {208, 147}
+"gcy", 2, {208, 179}
+"Gdot", 2, {196, 160}
+"gdot", 2, {196, 161}
+"ge", 3, {226, 137, 165}
+"gE", 3, {226, 137, 167}
+"gEl", 3, {226, 170, 140}
+"gel", 3, {226, 139, 155}
+"geq", 3, {226, 137, 165}
+"geqq", 3, {226, 137, 167}
+"geqslant", 3, {226, 169, 190}
+"gescc", 3, {226, 170, 169}
+"ges", 3, {226, 169, 190}
+"gesdot", 3, {226, 170, 128}
+"gesdoto", 3, {226, 170, 130}
+"gesdotol", 3, {226, 170, 132}
+"gesl", 3, {226, 139, 155}
+"gesles", 3, {226, 170, 148}
+"Gfr", 4, {240, 157, 148, 138}
+"gfr", 4, {240, 157, 148, 164}
+"gg", 3, {226, 137, 171}
+"Gg", 3, {226, 139, 153}
+"ggg", 3, {226, 139, 153}
+"gimel", 3, {226, 132, 183}
+"GJcy", 2, {208, 131}
+"gjcy", 2, {209, 147}
+"gla", 3, {226, 170, 165}
+"gl", 3, {226, 137, 183}
+"glE", 3, {226, 170, 146}
+"glj", 3, {226, 170, 164}
+"gnap", 3, {226, 170, 138}
+"gnapprox", 3, {226, 170, 138}
+"gne", 3, {226, 170, 136}
+"gnE", 3, {226, 137, 169}
+"gneq", 3, {226, 170, 136}
+"gneqq", 3, {226, 137, 169}
+"gnsim", 3, {226, 139, 167}
+"Gopf", 4, {240, 157, 148, 190}
+"gopf", 4, {240, 157, 149, 152}
+"grave", 1, {96}
+"GreaterEqual", 3, {226, 137, 165}
+"GreaterEqualLess", 3, {226, 139, 155}
+"GreaterFullEqual", 3, {226, 137, 167}
+"GreaterGreater", 3, {226, 170, 162}
+"GreaterLess", 3, {226, 137, 183}
+"GreaterSlantEqual", 3, {226, 169, 190}
+"GreaterTilde", 3, {226, 137, 179}
+"Gscr", 4, {240, 157, 146, 162}
+"gscr", 3, {226, 132, 138}
+"gsim", 3, {226, 137, 179}
+"gsime", 3, {226, 170, 142}
+"gsiml", 3, {226, 170, 144}
+"gtcc", 3, {226, 170, 167}
+"gtcir", 3, {226, 169, 186}
+"gt", 1, {62}
+"GT", 1, {62}
+"Gt", 3, {226, 137, 171}
+"gtdot", 3, {226, 139, 151}
+"gtlPar", 3, {226, 166, 149}
+"gtquest", 3, {226, 169, 188}
+"gtrapprox", 3, {226, 170, 134}
+"gtrarr", 3, {226, 165, 184}
+"gtrdot", 3, {226, 139, 151}
+"gtreqless", 3, {226, 139, 155}
+"gtreqqless", 3, {226, 170, 140}
+"gtrless", 3, {226, 137, 183}
+"gtrsim", 3, {226, 137, 179}
+"gvertneqq", 3, {226, 137, 169}
+"gvnE", 3, {226, 137, 169}
+"Hacek", 2, {203, 135}
+"hairsp", 3, {226, 128, 138}
+"half", 2, {194, 189}
+"hamilt", 3, {226, 132, 139}
+"HARDcy", 2, {208, 170}
+"hardcy", 2, {209, 138}
+"harrcir", 3, {226, 165, 136}
+"harr", 3, {226, 134, 148}
+"hArr", 3, {226, 135, 148}
+"harrw", 3, {226, 134, 173}
+"Hat", 1, {94}
+"hbar", 3, {226, 132, 143}
+"Hcirc", 2, {196, 164}
+"hcirc", 2, {196, 165}
+"hearts", 3, {226, 153, 165}
+"heartsuit", 3, {226, 153, 165}
+"hellip", 3, {226, 128, 166}
+"hercon", 3, {226, 138, 185}
+"hfr", 4, {240, 157, 148, 165}
+"Hfr", 3, {226, 132, 140}
+"HilbertSpace", 3, {226, 132, 139}
+"hksearow", 3, {226, 164, 165}
+"hkswarow", 3, {226, 164, 166}
+"hoarr", 3, {226, 135, 191}
+"homtht", 3, {226, 136, 187}
+"hookleftarrow", 3, {226, 134, 169}
+"hookrightarrow", 3, {226, 134, 170}
+"hopf", 4, {240, 157, 149, 153}
+"Hopf", 3, {226, 132, 141}
+"horbar", 3, {226, 128, 149}
+"HorizontalLine", 3, {226, 148, 128}
+"hscr", 4, {240, 157, 146, 189}
+"Hscr", 3, {226, 132, 139}
+"hslash", 3, {226, 132, 143}
+"Hstrok", 2, {196, 166}
+"hstrok", 2, {196, 167}
+"HumpDownHump", 3, {226, 137, 142}
+"HumpEqual", 3, {226, 137, 143}
+"hybull", 3, {226, 129, 131}
+"hyphen", 3, {226, 128, 144}
+"Iacute", 2, {195, 141}
+"iacute", 2, {195, 173}
+"ic", 3, {226, 129, 163}
+"Icirc", 2, {195, 142}
+"icirc", 2, {195, 174}
+"Icy", 2, {208, 152}
+"icy", 2, {208, 184}
+"Idot", 2, {196, 176}
+"IEcy", 2, {208, 149}
+"iecy", 2, {208, 181}
+"iexcl", 2, {194, 161}
+"iff", 3, {226, 135, 148}
+"ifr", 4, {240, 157, 148, 166}
+"Ifr", 3, {226, 132, 145}
+"Igrave", 2, {195, 140}
+"igrave", 2, {195, 172}
+"ii", 3, {226, 133, 136}
+"iiiint", 3, {226, 168, 140}
+"iiint", 3, {226, 136, 173}
+"iinfin", 3, {226, 167, 156}
+"iiota", 3, {226, 132, 169}
+"IJlig", 2, {196, 178}
+"ijlig", 2, {196, 179}
+"Imacr", 2, {196, 170}
+"imacr", 2, {196, 171}
+"image", 3, {226, 132, 145}
+"ImaginaryI", 3, {226, 133, 136}
+"imagline", 3, {226, 132, 144}
+"imagpart", 3, {226, 132, 145}
+"imath", 2, {196, 177}
+"Im", 3, {226, 132, 145}
+"imof", 3, {226, 138, 183}
+"imped", 2, {198, 181}
+"Implies", 3, {226, 135, 146}
+"incare", 3, {226, 132, 133}
+"in", 3, {226, 136, 136}
+"infin", 3, {226, 136, 158}
+"infintie", 3, {226, 167, 157}
+"inodot", 2, {196, 177}
+"intcal", 3, {226, 138, 186}
+"int", 3, {226, 136, 171}
+"Int", 3, {226, 136, 172}
+"integers", 3, {226, 132, 164}
+"Integral", 3, {226, 136, 171}
+"intercal", 3, {226, 138, 186}
+"Intersection", 3, {226, 139, 130}
+"intlarhk", 3, {226, 168, 151}
+"intprod", 3, {226, 168, 188}
+"InvisibleComma", 3, {226, 129, 163}
+"InvisibleTimes", 3, {226, 129, 162}
+"IOcy", 2, {208, 129}
+"iocy", 2, {209, 145}
+"Iogon", 2, {196, 174}
+"iogon", 2, {196, 175}
+"Iopf", 4, {240, 157, 149, 128}
+"iopf", 4, {240, 157, 149, 154}
+"Iota", 2, {206, 153}
+"iota", 2, {206, 185}
+"iprod", 3, {226, 168, 188}
+"iquest", 2, {194, 191}
+"iscr", 4, {240, 157, 146, 190}
+"Iscr", 3, {226, 132, 144}
+"isin", 3, {226, 136, 136}
+"isindot", 3, {226, 139, 181}
+"isinE", 3, {226, 139, 185}
+"isins", 3, {226, 139, 180}
+"isinsv", 3, {226, 139, 179}
+"isinv", 3, {226, 136, 136}
+"it", 3, {226, 129, 162}
+"Itilde", 2, {196, 168}
+"itilde", 2, {196, 169}
+"Iukcy", 2, {208, 134}
+"iukcy", 2, {209, 150}
+"Iuml", 2, {195, 143}
+"iuml", 2, {195, 175}
+"Jcirc", 2, {196, 180}
+"jcirc", 2, {196, 181}
+"Jcy", 2, {208, 153}
+"jcy", 2, {208, 185}
+"Jfr", 4, {240, 157, 148, 141}
+"jfr", 4, {240, 157, 148, 167}
+"jmath", 2, {200, 183}
+"Jopf", 4, {240, 157, 149, 129}
+"jopf", 4, {240, 157, 149, 155}
+"Jscr", 4, {240, 157, 146, 165}
+"jscr", 4, {240, 157, 146, 191}
+"Jsercy", 2, {208, 136}
+"jsercy", 2, {209, 152}
+"Jukcy", 2, {208, 132}
+"jukcy", 2, {209, 148}
+"Kappa", 2, {206, 154}
+"kappa", 2, {206, 186}
+"kappav", 2, {207, 176}
+"Kcedil", 2, {196, 182}
+"kcedil", 2, {196, 183}
+"Kcy", 2, {208, 154}
+"kcy", 2, {208, 186}
+"Kfr", 4, {240, 157, 148, 142}
+"kfr", 4, {240, 157, 148, 168}
+"kgreen", 2, {196, 184}
+"KHcy", 2, {208, 165}
+"khcy", 2, {209, 133}
+"KJcy", 2, {208, 140}
+"kjcy", 2, {209, 156}
+"Kopf", 4, {240, 157, 149, 130}
+"kopf", 4, {240, 157, 149, 156}
+"Kscr", 4, {240, 157, 146, 166}
+"kscr", 4, {240, 157, 147, 128}
+"lAarr", 3, {226, 135, 154}
+"Lacute", 2, {196, 185}
+"lacute", 2, {196, 186}
+"laemptyv", 3, {226, 166, 180}
+"lagran", 3, {226, 132, 146}
+"Lambda", 2, {206, 155}
+"lambda", 2, {206, 187}
+"lang", 3, {226, 159, 168}
+"Lang", 3, {226, 159, 170}
+"langd", 3, {226, 166, 145}
+"langle", 3, {226, 159, 168}
+"lap", 3, {226, 170, 133}
+"Laplacetrf", 3, {226, 132, 146}
+"laquo", 2, {194, 171}
+"larrb", 3, {226, 135, 164}
+"larrbfs", 3, {226, 164, 159}
+"larr", 3, {226, 134, 144}
+"Larr", 3, {226, 134, 158}
+"lArr", 3, {226, 135, 144}
+"larrfs", 3, {226, 164, 157}
+"larrhk", 3, {226, 134, 169}
+"larrlp", 3, {226, 134, 171}
+"larrpl", 3, {226, 164, 185}
+"larrsim", 3, {226, 165, 179}
+"larrtl", 3, {226, 134, 162}
+"latail", 3, {226, 164, 153}
+"lAtail", 3, {226, 164, 155}
+"lat", 3, {226, 170, 171}
+"late", 3, {226, 170, 173}
+"lates", 3, {226, 170, 173}
+"lbarr", 3, {226, 164, 140}
+"lBarr", 3, {226, 164, 142}
+"lbbrk", 3, {226, 157, 178}
+"lbrace", 1, {123}
+"lbrack", 1, {91}
+"lbrke", 3, {226, 166, 139}
+"lbrksld", 3, {226, 166, 143}
+"lbrkslu", 3, {226, 166, 141}
+"Lcaron", 2, {196, 189}
+"lcaron", 2, {196, 190}
+"Lcedil", 2, {196, 187}
+"lcedil", 2, {196, 188}
+"lceil", 3, {226, 140, 136}
+"lcub", 1, {123}
+"Lcy", 2, {208, 155}
+"lcy", 2, {208, 187}
+"ldca", 3, {226, 164, 182}
+"ldquo", 3, {226, 128, 156}
+"ldquor", 3, {226, 128, 158}
+"ldrdhar", 3, {226, 165, 167}
+"ldrushar", 3, {226, 165, 139}
+"ldsh", 3, {226, 134, 178}
+"le", 3, {226, 137, 164}
+"lE", 3, {226, 137, 166}
+"LeftAngleBracket", 3, {226, 159, 168}
+"LeftArrowBar", 3, {226, 135, 164}
+"leftarrow", 3, {226, 134, 144}
+"LeftArrow", 3, {226, 134, 144}
+"Leftarrow", 3, {226, 135, 144}
+"LeftArrowRightArrow", 3, {226, 135, 134}
+"leftarrowtail", 3, {226, 134, 162}
+"LeftCeiling", 3, {226, 140, 136}
+"LeftDoubleBracket", 3, {226, 159, 166}
+"LeftDownTeeVector", 3, {226, 165, 161}
+"LeftDownVectorBar", 3, {226, 165, 153}
+"LeftDownVector", 3, {226, 135, 131}
+"LeftFloor", 3, {226, 140, 138}
+"leftharpoondown", 3, {226, 134, 189}
+"leftharpoonup", 3, {226, 134, 188}
+"leftleftarrows", 3, {226, 135, 135}
+"leftrightarrow", 3, {226, 134, 148}
+"LeftRightArrow", 3, {226, 134, 148}
+"Leftrightarrow", 3, {226, 135, 148}
+"leftrightarrows", 3, {226, 135, 134}
+"leftrightharpoons", 3, {226, 135, 139}
+"leftrightsquigarrow", 3, {226, 134, 173}
+"LeftRightVector", 3, {226, 165, 142}
+"LeftTeeArrow", 3, {226, 134, 164}
+"LeftTee", 3, {226, 138, 163}
+"LeftTeeVector", 3, {226, 165, 154}
+"leftthreetimes", 3, {226, 139, 139}
+"LeftTriangleBar", 3, {226, 167, 143}
+"LeftTriangle", 3, {226, 138, 178}
+"LeftTriangleEqual", 3, {226, 138, 180}
+"LeftUpDownVector", 3, {226, 165, 145}
+"LeftUpTeeVector", 3, {226, 165, 160}
+"LeftUpVectorBar", 3, {226, 165, 152}
+"LeftUpVector", 3, {226, 134, 191}
+"LeftVectorBar", 3, {226, 165, 146}
+"LeftVector", 3, {226, 134, 188}
+"lEg", 3, {226, 170, 139}
+"leg", 3, {226, 139, 154}
+"leq", 3, {226, 137, 164}
+"leqq", 3, {226, 137, 166}
+"leqslant", 3, {226, 169, 189}
+"lescc", 3, {226, 170, 168}
+"les", 3, {226, 169, 189}
+"lesdot", 3, {226, 169, 191}
+"lesdoto", 3, {226, 170, 129}
+"lesdotor", 3, {226, 170, 131}
+"lesg", 3, {226, 139, 154}
+"lesges", 3, {226, 170, 147}
+"lessapprox", 3, {226, 170, 133}
+"lessdot", 3, {226, 139, 150}
+"lesseqgtr", 3, {226, 139, 154}
+"lesseqqgtr", 3, {226, 170, 139}
+"LessEqualGreater", 3, {226, 139, 154}
+"LessFullEqual", 3, {226, 137, 166}
+"LessGreater", 3, {226, 137, 182}
+"lessgtr", 3, {226, 137, 182}
+"LessLess", 3, {226, 170, 161}
+"lesssim", 3, {226, 137, 178}
+"LessSlantEqual", 3, {226, 169, 189}
+"LessTilde", 3, {226, 137, 178}
+"lfisht", 3, {226, 165, 188}
+"lfloor", 3, {226, 140, 138}
+"Lfr", 4, {240, 157, 148, 143}
+"lfr", 4, {240, 157, 148, 169}
+"lg", 3, {226, 137, 182}
+"lgE", 3, {226, 170, 145}
+"lHar", 3, {226, 165, 162}
+"lhard", 3, {226, 134, 189}
+"lharu", 3, {226, 134, 188}
+"lharul", 3, {226, 165, 170}
+"lhblk", 3, {226, 150, 132}
+"LJcy", 2, {208, 137}
+"ljcy", 2, {209, 153}
+"llarr", 3, {226, 135, 135}
+"ll", 3, {226, 137, 170}
+"Ll", 3, {226, 139, 152}
+"llcorner", 3, {226, 140, 158}
+"Lleftarrow", 3, {226, 135, 154}
+"llhard", 3, {226, 165, 171}
+"lltri", 3, {226, 151, 186}
+"Lmidot", 2, {196, 191}
+"lmidot", 2, {197, 128}
+"lmoustache", 3, {226, 142, 176}
+"lmoust", 3, {226, 142, 176}
+"lnap", 3, {226, 170, 137}
+"lnapprox", 3, {226, 170, 137}
+"lne", 3, {226, 170, 135}
+"lnE", 3, {226, 137, 168}
+"lneq", 3, {226, 170, 135}
+"lneqq", 3, {226, 137, 168}
+"lnsim", 3, {226, 139, 166}
+"loang", 3, {226, 159, 172}
+"loarr", 3, {226, 135, 189}
+"lobrk", 3, {226, 159, 166}
+"longleftarrow", 3, {226, 159, 181}
+"LongLeftArrow", 3, {226, 159, 181}
+"Longleftarrow", 3, {226, 159, 184}
+"longleftrightarrow", 3, {226, 159, 183}
+"LongLeftRightArrow", 3, {226, 159, 183}
+"Longleftrightarrow", 3, {226, 159, 186}
+"longmapsto", 3, {226, 159, 188}
+"longrightarrow", 3, {226, 159, 182}
+"LongRightArrow", 3, {226, 159, 182}
+"Longrightarrow", 3, {226, 159, 185}
+"looparrowleft", 3, {226, 134, 171}
+"looparrowright", 3, {226, 134, 172}
+"lopar", 3, {226, 166, 133}
+"Lopf", 4, {240, 157, 149, 131}
+"lopf", 4, {240, 157, 149, 157}
+"loplus", 3, {226, 168, 173}
+"lotimes", 3, {226, 168, 180}
+"lowast", 3, {226, 136, 151}
+"lowbar", 1, {95}
+"LowerLeftArrow", 3, {226, 134, 153}
+"LowerRightArrow", 3, {226, 134, 152}
+"loz", 3, {226, 151, 138}
+"lozenge", 3, {226, 151, 138}
+"lozf", 3, {226, 167, 171}
+"lpar", 1, {40}
+"lparlt", 3, {226, 166, 147}
+"lrarr", 3, {226, 135, 134}
+"lrcorner", 3, {226, 140, 159}
+"lrhar", 3, {226, 135, 139}
+"lrhard", 3, {226, 165, 173}
+"lrm", 3, {226, 128, 142}
+"lrtri", 3, {226, 138, 191}
+"lsaquo", 3, {226, 128, 185}
+"lscr", 4, {240, 157, 147, 129}
+"Lscr", 3, {226, 132, 146}
+"lsh", 3, {226, 134, 176}
+"Lsh", 3, {226, 134, 176}
+"lsim", 3, {226, 137, 178}
+"lsime", 3, {226, 170, 141}
+"lsimg", 3, {226, 170, 143}
+"lsqb", 1, {91}
+"lsquo", 3, {226, 128, 152}
+"lsquor", 3, {226, 128, 154}
+"Lstrok", 2, {197, 129}
+"lstrok", 2, {197, 130}
+"ltcc", 3, {226, 170, 166}
+"ltcir", 3, {226, 169, 185}
+"lt", 1, {60}
+"LT", 1, {60}
+"Lt", 3, {226, 137, 170}
+"ltdot", 3, {226, 139, 150}
+"lthree", 3, {226, 139, 139}
+"ltimes", 3, {226, 139, 137}
+"ltlarr", 3, {226, 165, 182}
+"ltquest", 3, {226, 169, 187}
+"ltri", 3, {226, 151, 131}
+"ltrie", 3, {226, 138, 180}
+"ltrif", 3, {226, 151, 130}
+"ltrPar", 3, {226, 166, 150}
+"lurdshar", 3, {226, 165, 138}
+"luruhar", 3, {226, 165, 166}
+"lvertneqq", 3, {226, 137, 168}
+"lvnE", 3, {226, 137, 168}
+"macr", 2, {194, 175}
+"male", 3, {226, 153, 130}
+"malt", 3, {226, 156, 160}
+"maltese", 3, {226, 156, 160}
+"Map", 3, {226, 164, 133}
+"map", 3, {226, 134, 166}
+"mapsto", 3, {226, 134, 166}
+"mapstodown", 3, {226, 134, 167}
+"mapstoleft", 3, {226, 134, 164}
+"mapstoup", 3, {226, 134, 165}
+"marker", 3, {226, 150, 174}
+"mcomma", 3, {226, 168, 169}
+"Mcy", 2, {208, 156}
+"mcy", 2, {208, 188}
+"mdash", 3, {226, 128, 148}
+"mDDot", 3, {226, 136, 186}
+"measuredangle", 3, {226, 136, 161}
+"MediumSpace", 3, {226, 129, 159}
+"Mellintrf", 3, {226, 132, 179}
+"Mfr", 4, {240, 157, 148, 144}
+"mfr", 4, {240, 157, 148, 170}
+"mho", 3, {226, 132, 167}
+"micro", 2, {194, 181}
+"midast", 1, {42}
+"midcir", 3, {226, 171, 176}
+"mid", 3, {226, 136, 163}
+"middot", 2, {194, 183}
+"minusb", 3, {226, 138, 159}
+"minus", 3, {226, 136, 146}
+"minusd", 3, {226, 136, 184}
+"minusdu", 3, {226, 168, 170}
+"MinusPlus", 3, {226, 136, 147}
+"mlcp", 3, {226, 171, 155}
+"mldr", 3, {226, 128, 166}
+"mnplus", 3, {226, 136, 147}
+"models", 3, {226, 138, 167}
+"Mopf", 4, {240, 157, 149, 132}
+"mopf", 4, {240, 157, 149, 158}
+"mp", 3, {226, 136, 147}
+"mscr", 4, {240, 157, 147, 130}
+"Mscr", 3, {226, 132, 179}
+"mstpos", 3, {226, 136, 190}
+"Mu", 2, {206, 156}
+"mu", 2, {206, 188}
+"multimap", 3, {226, 138, 184}
+"mumap", 3, {226, 138, 184}
+"nabla", 3, {226, 136, 135}
+"Nacute", 2, {197, 131}
+"nacute", 2, {197, 132}
+"nang", 3, {226, 136, 160}
+"nap", 3, {226, 137, 137}
+"napE", 3, {226, 169, 176}
+"napid", 3, {226, 137, 139}
+"napos", 2, {197, 137}
+"napprox", 3, {226, 137, 137}
+"natural", 3, {226, 153, 174}
+"naturals", 3, {226, 132, 149}
+"natur", 3, {226, 153, 174}
+"nbsp", 2, {194, 160}
+"nbump", 3, {226, 137, 142}
+"nbumpe", 3, {226, 137, 143}
+"ncap", 3, {226, 169, 131}
+"Ncaron", 2, {197, 135}
+"ncaron", 2, {197, 136}
+"Ncedil", 2, {197, 133}
+"ncedil", 2, {197, 134}
+"ncong", 3, {226, 137, 135}
+"ncongdot", 3, {226, 169, 173}
+"ncup", 3, {226, 169, 130}
+"Ncy", 2, {208, 157}
+"ncy", 2, {208, 189}
+"ndash", 3, {226, 128, 147}
+"nearhk", 3, {226, 164, 164}
+"nearr", 3, {226, 134, 151}
+"neArr", 3, {226, 135, 151}
+"nearrow", 3, {226, 134, 151}
+"ne", 3, {226, 137, 160}
+"nedot", 3, {226, 137, 144}
+"NegativeMediumSpace", 3, {226, 128, 139}
+"NegativeThickSpace", 3, {226, 128, 139}
+"NegativeThinSpace", 3, {226, 128, 139}
+"NegativeVeryThinSpace", 3, {226, 128, 139}
+"nequiv", 3, {226, 137, 162}
+"nesear", 3, {226, 164, 168}
+"nesim", 3, {226, 137, 130}
+"NestedGreaterGreater", 3, {226, 137, 171}
+"NestedLessLess", 3, {226, 137, 170}
+"NewLine", 1, {10}
+"nexist", 3, {226, 136, 132}
+"nexists", 3, {226, 136, 132}
+"Nfr", 4, {240, 157, 148, 145}
+"nfr", 4, {240, 157, 148, 171}
+"ngE", 3, {226, 137, 167}
+"nge", 3, {226, 137, 177}
+"ngeq", 3, {226, 137, 177}
+"ngeqq", 3, {226, 137, 167}
+"ngeqslant", 3, {226, 169, 190}
+"nges", 3, {226, 169, 190}
+"nGg", 3, {226, 139, 153}
+"ngsim", 3, {226, 137, 181}
+"nGt", 3, {226, 137, 171}
+"ngt", 3, {226, 137, 175}
+"ngtr", 3, {226, 137, 175}
+"nGtv", 3, {226, 137, 171}
+"nharr", 3, {226, 134, 174}
+"nhArr", 3, {226, 135, 142}
+"nhpar", 3, {226, 171, 178}
+"ni", 3, {226, 136, 139}
+"nis", 3, {226, 139, 188}
+"nisd", 3, {226, 139, 186}
+"niv", 3, {226, 136, 139}
+"NJcy", 2, {208, 138}
+"njcy", 2, {209, 154}
+"nlarr", 3, {226, 134, 154}
+"nlArr", 3, {226, 135, 141}
+"nldr", 3, {226, 128, 165}
+"nlE", 3, {226, 137, 166}
+"nle", 3, {226, 137, 176}
+"nleftarrow", 3, {226, 134, 154}
+"nLeftarrow", 3, {226, 135, 141}
+"nleftrightarrow", 3, {226, 134, 174}
+"nLeftrightarrow", 3, {226, 135, 142}
+"nleq", 3, {226, 137, 176}
+"nleqq", 3, {226, 137, 166}
+"nleqslant", 3, {226, 169, 189}
+"nles", 3, {226, 169, 189}
+"nless", 3, {226, 137, 174}
+"nLl", 3, {226, 139, 152}
+"nlsim", 3, {226, 137, 180}
+"nLt", 3, {226, 137, 170}
+"nlt", 3, {226, 137, 174}
+"nltri", 3, {226, 139, 170}
+"nltrie", 3, {226, 139, 172}
+"nLtv", 3, {226, 137, 170}
+"nmid", 3, {226, 136, 164}
+"NoBreak", 3, {226, 129, 160}
+"NonBreakingSpace", 2, {194, 160}
+"nopf", 4, {240, 157, 149, 159}
+"Nopf", 3, {226, 132, 149}
+"Not", 3, {226, 171, 172}
+"not", 2, {194, 172}
+"NotCongruent", 3, {226, 137, 162}
+"NotCupCap", 3, {226, 137, 173}
+"NotDoubleVerticalBar", 3, {226, 136, 166}
+"NotElement", 3, {226, 136, 137}
+"NotEqual", 3, {226, 137, 160}
+"NotEqualTilde", 3, {226, 137, 130}
+"NotExists", 3, {226, 136, 132}
+"NotGreater", 3, {226, 137, 175}
+"NotGreaterEqual", 3, {226, 137, 177}
+"NotGreaterFullEqual", 3, {226, 137, 167}
+"NotGreaterGreater", 3, {226, 137, 171}
+"NotGreaterLess", 3, {226, 137, 185}
+"NotGreaterSlantEqual", 3, {226, 169, 190}
+"NotGreaterTilde", 3, {226, 137, 181}
+"NotHumpDownHump", 3, {226, 137, 142}
+"NotHumpEqual", 3, {226, 137, 143}
+"notin", 3, {226, 136, 137}
+"notindot", 3, {226, 139, 181}
+"notinE", 3, {226, 139, 185}
+"notinva", 3, {226, 136, 137}
+"notinvb", 3, {226, 139, 183}
+"notinvc", 3, {226, 139, 182}
+"NotLeftTriangleBar", 3, {226, 167, 143}
+"NotLeftTriangle", 3, {226, 139, 170}
+"NotLeftTriangleEqual", 3, {226, 139, 172}
+"NotLess", 3, {226, 137, 174}
+"NotLessEqual", 3, {226, 137, 176}
+"NotLessGreater", 3, {226, 137, 184}
+"NotLessLess", 3, {226, 137, 170}
+"NotLessSlantEqual", 3, {226, 169, 189}
+"NotLessTilde", 3, {226, 137, 180}
+"NotNestedGreaterGreater", 3, {226, 170, 162}
+"NotNestedLessLess", 3, {226, 170, 161}
+"notni", 3, {226, 136, 140}
+"notniva", 3, {226, 136, 140}
+"notnivb", 3, {226, 139, 190}
+"notnivc", 3, {226, 139, 189}
+"NotPrecedes", 3, {226, 138, 128}
+"NotPrecedesEqual", 3, {226, 170, 175}
+"NotPrecedesSlantEqual", 3, {226, 139, 160}
+"NotReverseElement", 3, {226, 136, 140}
+"NotRightTriangleBar", 3, {226, 167, 144}
+"NotRightTriangle", 3, {226, 139, 171}
+"NotRightTriangleEqual", 3, {226, 139, 173}
+"NotSquareSubset", 3, {226, 138, 143}
+"NotSquareSubsetEqual", 3, {226, 139, 162}
+"NotSquareSuperset", 3, {226, 138, 144}
+"NotSquareSupersetEqual", 3, {226, 139, 163}
+"NotSubset", 3, {226, 138, 130}
+"NotSubsetEqual", 3, {226, 138, 136}
+"NotSucceeds", 3, {226, 138, 129}
+"NotSucceedsEqual", 3, {226, 170, 176}
+"NotSucceedsSlantEqual", 3, {226, 139, 161}
+"NotSucceedsTilde", 3, {226, 137, 191}
+"NotSuperset", 3, {226, 138, 131}
+"NotSupersetEqual", 3, {226, 138, 137}
+"NotTilde", 3, {226, 137, 129}
+"NotTildeEqual", 3, {226, 137, 132}
+"NotTildeFullEqual", 3, {226, 137, 135}
+"NotTildeTilde", 3, {226, 137, 137}
+"NotVerticalBar", 3, {226, 136, 164}
+"nparallel", 3, {226, 136, 166}
+"npar", 3, {226, 136, 166}
+"nparsl", 3, {226, 171, 189}
+"npart", 3, {226, 136, 130}
+"npolint", 3, {226, 168, 148}
+"npr", 3, {226, 138, 128}
+"nprcue", 3, {226, 139, 160}
+"nprec", 3, {226, 138, 128}
+"npreceq", 3, {226, 170, 175}
+"npre", 3, {226, 170, 175}
+"nrarrc", 3, {226, 164, 179}
+"nrarr", 3, {226, 134, 155}
+"nrArr", 3, {226, 135, 143}
+"nrarrw", 3, {226, 134, 157}
+"nrightarrow", 3, {226, 134, 155}
+"nRightarrow", 3, {226, 135, 143}
+"nrtri", 3, {226, 139, 171}
+"nrtrie", 3, {226, 139, 173}
+"nsc", 3, {226, 138, 129}
+"nsccue", 3, {226, 139, 161}
+"nsce", 3, {226, 170, 176}
+"Nscr", 4, {240, 157, 146, 169}
+"nscr", 4, {240, 157, 147, 131}
+"nshortmid", 3, {226, 136, 164}
+"nshortparallel", 3, {226, 136, 166}
+"nsim", 3, {226, 137, 129}
+"nsime", 3, {226, 137, 132}
+"nsimeq", 3, {226, 137, 132}
+"nsmid", 3, {226, 136, 164}
+"nspar", 3, {226, 136, 166}
+"nsqsube", 3, {226, 139, 162}
+"nsqsupe", 3, {226, 139, 163}
+"nsub", 3, {226, 138, 132}
+"nsubE", 3, {226, 171, 133}
+"nsube", 3, {226, 138, 136}
+"nsubset", 3, {226, 138, 130}
+"nsubseteq", 3, {226, 138, 136}
+"nsubseteqq", 3, {226, 171, 133}
+"nsucc", 3, {226, 138, 129}
+"nsucceq", 3, {226, 170, 176}
+"nsup", 3, {226, 138, 133}
+"nsupE", 3, {226, 171, 134}
+"nsupe", 3, {226, 138, 137}
+"nsupset", 3, {226, 138, 131}
+"nsupseteq", 3, {226, 138, 137}
+"nsupseteqq", 3, {226, 171, 134}
+"ntgl", 3, {226, 137, 185}
+"Ntilde", 2, {195, 145}
+"ntilde", 2, {195, 177}
+"ntlg", 3, {226, 137, 184}
+"ntriangleleft", 3, {226, 139, 170}
+"ntrianglelefteq", 3, {226, 139, 172}
+"ntriangleright", 3, {226, 139, 171}
+"ntrianglerighteq", 3, {226, 139, 173}
+"Nu", 2, {206, 157}
+"nu", 2, {206, 189}
+"num", 1, {35}
+"numero", 3, {226, 132, 150}
+"numsp", 3, {226, 128, 135}
+"nvap", 3, {226, 137, 141}
+"nvdash", 3, {226, 138, 172}
+"nvDash", 3, {226, 138, 173}
+"nVdash", 3, {226, 138, 174}
+"nVDash", 3, {226, 138, 175}
+"nvge", 3, {226, 137, 165}
+"nvgt", 1, {62}
+"nvHarr", 3, {226, 164, 132}
+"nvinfin", 3, {226, 167, 158}
+"nvlArr", 3, {226, 164, 130}
+"nvle", 3, {226, 137, 164}
+"nvlt", 1, {60}
+"nvltrie", 3, {226, 138, 180}
+"nvrArr", 3, {226, 164, 131}
+"nvrtrie", 3, {226, 138, 181}
+"nvsim", 3, {226, 136, 188}
+"nwarhk", 3, {226, 164, 163}
+"nwarr", 3, {226, 134, 150}
+"nwArr", 3, {226, 135, 150}
+"nwarrow", 3, {226, 134, 150}
+"nwnear", 3, {226, 164, 167}
+"Oacute", 2, {195, 147}
+"oacute", 2, {195, 179}
+"oast", 3, {226, 138, 155}
+"Ocirc", 2, {195, 148}
+"ocirc", 2, {195, 180}
+"ocir", 3, {226, 138, 154}
+"Ocy", 2, {208, 158}
+"ocy", 2, {208, 190}
+"odash", 3, {226, 138, 157}
+"Odblac", 2, {197, 144}
+"odblac", 2, {197, 145}
+"odiv", 3, {226, 168, 184}
+"odot", 3, {226, 138, 153}
+"odsold", 3, {226, 166, 188}
+"OElig", 2, {197, 146}
+"oelig", 2, {197, 147}
+"ofcir", 3, {226, 166, 191}
+"Ofr", 4, {240, 157, 148, 146}
+"ofr", 4, {240, 157, 148, 172}
+"ogon", 2, {203, 155}
+"Ograve", 2, {195, 146}
+"ograve", 2, {195, 178}
+"ogt", 3, {226, 167, 129}
+"ohbar", 3, {226, 166, 181}
+"ohm", 2, {206, 169}
+"oint", 3, {226, 136, 174}
+"olarr", 3, {226, 134, 186}
+"olcir", 3, {226, 166, 190}
+"olcross", 3, {226, 166, 187}
+"oline", 3, {226, 128, 190}
+"olt", 3, {226, 167, 128}
+"Omacr", 2, {197, 140}
+"omacr", 2, {197, 141}
+"Omega", 2, {206, 169}
+"omega", 2, {207, 137}
+"Omicron", 2, {206, 159}
+"omicron", 2, {206, 191}
+"omid", 3, {226, 166, 182}
+"ominus", 3, {226, 138, 150}
+"Oopf", 4, {240, 157, 149, 134}
+"oopf", 4, {240, 157, 149, 160}
+"opar", 3, {226, 166, 183}
+"OpenCurlyDoubleQuote", 3, {226, 128, 156}
+"OpenCurlyQuote", 3, {226, 128, 152}
+"operp", 3, {226, 166, 185}
+"oplus", 3, {226, 138, 149}
+"orarr", 3, {226, 134, 187}
+"Or", 3, {226, 169, 148}
+"or", 3, {226, 136, 168}
+"ord", 3, {226, 169, 157}
+"order", 3, {226, 132, 180}
+"orderof", 3, {226, 132, 180}
+"ordf", 2, {194, 170}
+"ordm", 2, {194, 186}
+"origof", 3, {226, 138, 182}
+"oror", 3, {226, 169, 150}
+"orslope", 3, {226, 169, 151}
+"orv", 3, {226, 169, 155}
+"oS", 3, {226, 147, 136}
+"Oscr", 4, {240, 157, 146, 170}
+"oscr", 3, {226, 132, 180}
+"Oslash", 2, {195, 152}
+"oslash", 2, {195, 184}
+"osol", 3, {226, 138, 152}
+"Otilde", 2, {195, 149}
+"otilde", 2, {195, 181}
+"otimesas", 3, {226, 168, 182}
+"Otimes", 3, {226, 168, 183}
+"otimes", 3, {226, 138, 151}
+"Ouml", 2, {195, 150}
+"ouml", 2, {195, 182}
+"ovbar", 3, {226, 140, 189}
+"OverBar", 3, {226, 128, 190}
+"OverBrace", 3, {226, 143, 158}
+"OverBracket", 3, {226, 142, 180}
+"OverParenthesis", 3, {226, 143, 156}
+"para", 2, {194, 182}
+"parallel", 3, {226, 136, 165}
+"par", 3, {226, 136, 165}
+"parsim", 3, {226, 171, 179}
+"parsl", 3, {226, 171, 189}
+"part", 3, {226, 136, 130}
+"PartialD", 3, {226, 136, 130}
+"Pcy", 2, {208, 159}
+"pcy", 2, {208, 191}
+"percnt", 1, {37}
+"period", 1, {46}
+"permil", 3, {226, 128, 176}
+"perp", 3, {226, 138, 165}
+"pertenk", 3, {226, 128, 177}
+"Pfr", 4, {240, 157, 148, 147}
+"pfr", 4, {240, 157, 148, 173}
+"Phi", 2, {206, 166}
+"phi", 2, {207, 134}
+"phiv", 2, {207, 149}
+"phmmat", 3, {226, 132, 179}
+"phone", 3, {226, 152, 142}
+"Pi", 2, {206, 160}
+"pi", 2, {207, 128}
+"pitchfork", 3, {226, 139, 148}
+"piv", 2, {207, 150}
+"planck", 3, {226, 132, 143}
+"planckh", 3, {226, 132, 142}
+"plankv", 3, {226, 132, 143}
+"plusacir", 3, {226, 168, 163}
+"plusb", 3, {226, 138, 158}
+"pluscir", 3, {226, 168, 162}
+"plus", 1, {43}
+"plusdo", 3, {226, 136, 148}
+"plusdu", 3, {226, 168, 165}
+"pluse", 3, {226, 169, 178}
+"PlusMinus", 2, {194, 177}
+"plusmn", 2, {194, 177}
+"plussim", 3, {226, 168, 166}
+"plustwo", 3, {226, 168, 167}
+"pm", 2, {194, 177}
+"Poincareplane", 3, {226, 132, 140}
+"pointint", 3, {226, 168, 149}
+"popf", 4, {240, 157, 149, 161}
+"Popf", 3, {226, 132, 153}
+"pound", 2, {194, 163}
+"prap", 3, {226, 170, 183}
+"Pr", 3, {226, 170, 187}
+"pr", 3, {226, 137, 186}
+"prcue", 3, {226, 137, 188}
+"precapprox", 3, {226, 170, 183}
+"prec", 3, {226, 137, 186}
+"preccurlyeq", 3, {226, 137, 188}
+"Precedes", 3, {226, 137, 186}
+"PrecedesEqual", 3, {226, 170, 175}
+"PrecedesSlantEqual", 3, {226, 137, 188}
+"PrecedesTilde", 3, {226, 137, 190}
+"preceq", 3, {226, 170, 175}
+"precnapprox", 3, {226, 170, 185}
+"precneqq", 3, {226, 170, 181}
+"precnsim", 3, {226, 139, 168}
+"pre", 3, {226, 170, 175}
+"prE", 3, {226, 170, 179}
+"precsim", 3, {226, 137, 190}
+"prime", 3, {226, 128, 178}
+"Prime", 3, {226, 128, 179}
+"primes", 3, {226, 132, 153}
+"prnap", 3, {226, 170, 185}
+"prnE", 3, {226, 170, 181}
+"prnsim", 3, {226, 139, 168}
+"prod", 3, {226, 136, 143}
+"Product", 3, {226, 136, 143}
+"profalar", 3, {226, 140, 174}
+"profline", 3, {226, 140, 146}
+"profsurf", 3, {226, 140, 147}
+"prop", 3, {226, 136, 157}
+"Proportional", 3, {226, 136, 157}
+"Proportion", 3, {226, 136, 183}
+"propto", 3, {226, 136, 157}
+"prsim", 3, {226, 137, 190}
+"prurel", 3, {226, 138, 176}
+"Pscr", 4, {240, 157, 146, 171}
+"pscr", 4, {240, 157, 147, 133}
+"Psi", 2, {206, 168}
+"psi", 2, {207, 136}
+"puncsp", 3, {226, 128, 136}
+"Qfr", 4, {240, 157, 148, 148}
+"qfr", 4, {240, 157, 148, 174}
+"qint", 3, {226, 168, 140}
+"qopf", 4, {240, 157, 149, 162}
+"Qopf", 3, {226, 132, 154}
+"qprime", 3, {226, 129, 151}
+"Qscr", 4, {240, 157, 146, 172}
+"qscr", 4, {240, 157, 147, 134}
+"quaternions", 3, {226, 132, 141}
+"quatint", 3, {226, 168, 150}
+"quest", 1, {63}
+"questeq", 3, {226, 137, 159}
+"quot", 1, {34}
+"QUOT", 1, {34}
+"rAarr", 3, {226, 135, 155}
+"race", 3, {226, 136, 189}
+"Racute", 2, {197, 148}
+"racute", 2, {197, 149}
+"radic", 3, {226, 136, 154}
+"raemptyv", 3, {226, 166, 179}
+"rang", 3, {226, 159, 169}
+"Rang", 3, {226, 159, 171}
+"rangd", 3, {226, 166, 146}
+"range", 3, {226, 166, 165}
+"rangle", 3, {226, 159, 169}
+"raquo", 2, {194, 187}
+"rarrap", 3, {226, 165, 181}
+"rarrb", 3, {226, 135, 165}
+"rarrbfs", 3, {226, 164, 160}
+"rarrc", 3, {226, 164, 179}
+"rarr", 3, {226, 134, 146}
+"Rarr", 3, {226, 134, 160}
+"rArr", 3, {226, 135, 146}
+"rarrfs", 3, {226, 164, 158}
+"rarrhk", 3, {226, 134, 170}
+"rarrlp", 3, {226, 134, 172}
+"rarrpl", 3, {226, 165, 133}
+"rarrsim", 3, {226, 165, 180}
+"Rarrtl", 3, {226, 164, 150}
+"rarrtl", 3, {226, 134, 163}
+"rarrw", 3, {226, 134, 157}
+"ratail", 3, {226, 164, 154}
+"rAtail", 3, {226, 164, 156}
+"ratio", 3, {226, 136, 182}
+"rationals", 3, {226, 132, 154}
+"rbarr", 3, {226, 164, 141}
+"rBarr", 3, {226, 164, 143}
+"RBarr", 3, {226, 164, 144}
+"rbbrk", 3, {226, 157, 179}
+"rbrace", 1, {125}
+"rbrack", 1, {93}
+"rbrke", 3, {226, 166, 140}
+"rbrksld", 3, {226, 166, 142}
+"rbrkslu", 3, {226, 166, 144}
+"Rcaron", 2, {197, 152}
+"rcaron", 2, {197, 153}
+"Rcedil", 2, {197, 150}
+"rcedil", 2, {197, 151}
+"rceil", 3, {226, 140, 137}
+"rcub", 1, {125}
+"Rcy", 2, {208, 160}
+"rcy", 2, {209, 128}
+"rdca", 3, {226, 164, 183}
+"rdldhar", 3, {226, 165, 169}
+"rdquo", 3, {226, 128, 157}
+"rdquor", 3, {226, 128, 157}
+"rdsh", 3, {226, 134, 179}
+"real", 3, {226, 132, 156}
+"realine", 3, {226, 132, 155}
+"realpart", 3, {226, 132, 156}
+"reals", 3, {226, 132, 157}
+"Re", 3, {226, 132, 156}
+"rect", 3, {226, 150, 173}
+"reg", 2, {194, 174}
+"REG", 2, {194, 174}
+"ReverseElement", 3, {226, 136, 139}
+"ReverseEquilibrium", 3, {226, 135, 139}
+"ReverseUpEquilibrium", 3, {226, 165, 175}
+"rfisht", 3, {226, 165, 189}
+"rfloor", 3, {226, 140, 139}
+"rfr", 4, {240, 157, 148, 175}
+"Rfr", 3, {226, 132, 156}
+"rHar", 3, {226, 165, 164}
+"rhard", 3, {226, 135, 129}
+"rharu", 3, {226, 135, 128}
+"rharul", 3, {226, 165, 172}
+"Rho", 2, {206, 161}
+"rho", 2, {207, 129}
+"rhov", 2, {207, 177}
+"RightAngleBracket", 3, {226, 159, 169}
+"RightArrowBar", 3, {226, 135, 165}
+"rightarrow", 3, {226, 134, 146}
+"RightArrow", 3, {226, 134, 146}
+"Rightarrow", 3, {226, 135, 146}
+"RightArrowLeftArrow", 3, {226, 135, 132}
+"rightarrowtail", 3, {226, 134, 163}
+"RightCeiling", 3, {226, 140, 137}
+"RightDoubleBracket", 3, {226, 159, 167}
+"RightDownTeeVector", 3, {226, 165, 157}
+"RightDownVectorBar", 3, {226, 165, 149}
+"RightDownVector", 3, {226, 135, 130}
+"RightFloor", 3, {226, 140, 139}
+"rightharpoondown", 3, {226, 135, 129}
+"rightharpoonup", 3, {226, 135, 128}
+"rightleftarrows", 3, {226, 135, 132}
+"rightleftharpoons", 3, {226, 135, 140}
+"rightrightarrows", 3, {226, 135, 137}
+"rightsquigarrow", 3, {226, 134, 157}
+"RightTeeArrow", 3, {226, 134, 166}
+"RightTee", 3, {226, 138, 162}
+"RightTeeVector", 3, {226, 165, 155}
+"rightthreetimes", 3, {226, 139, 140}
+"RightTriangleBar", 3, {226, 167, 144}
+"RightTriangle", 3, {226, 138, 179}
+"RightTriangleEqual", 3, {226, 138, 181}
+"RightUpDownVector", 3, {226, 165, 143}
+"RightUpTeeVector", 3, {226, 165, 156}
+"RightUpVectorBar", 3, {226, 165, 148}
+"RightUpVector", 3, {226, 134, 190}
+"RightVectorBar", 3, {226, 165, 147}
+"RightVector", 3, {226, 135, 128}
+"ring", 2, {203, 154}
+"risingdotseq", 3, {226, 137, 147}
+"rlarr", 3, {226, 135, 132}
+"rlhar", 3, {226, 135, 140}
+"rlm", 3, {226, 128, 143}
+"rmoustache", 3, {226, 142, 177}
+"rmoust", 3, {226, 142, 177}
+"rnmid", 3, {226, 171, 174}
+"roang", 3, {226, 159, 173}
+"roarr", 3, {226, 135, 190}
+"robrk", 3, {226, 159, 167}
+"ropar", 3, {226, 166, 134}
+"ropf", 4, {240, 157, 149, 163}
+"Ropf", 3, {226, 132, 157}
+"roplus", 3, {226, 168, 174}
+"rotimes", 3, {226, 168, 181}
+"RoundImplies", 3, {226, 165, 176}
+"rpar", 1, {41}
+"rpargt", 3, {226, 166, 148}
+"rppolint", 3, {226, 168, 146}
+"rrarr", 3, {226, 135, 137}
+"Rrightarrow", 3, {226, 135, 155}
+"rsaquo", 3, {226, 128, 186}
+"rscr", 4, {240, 157, 147, 135}
+"Rscr", 3, {226, 132, 155}
+"rsh", 3, {226, 134, 177}
+"Rsh", 3, {226, 134, 177}
+"rsqb", 1, {93}
+"rsquo", 3, {226, 128, 153}
+"rsquor", 3, {226, 128, 153}
+"rthree", 3, {226, 139, 140}
+"rtimes", 3, {226, 139, 138}
+"rtri", 3, {226, 150, 185}
+"rtrie", 3, {226, 138, 181}
+"rtrif", 3, {226, 150, 184}
+"rtriltri", 3, {226, 167, 142}
+"RuleDelayed", 3, {226, 167, 180}
+"ruluhar", 3, {226, 165, 168}
+"rx", 3, {226, 132, 158}
+"Sacute", 2, {197, 154}
+"sacute", 2, {197, 155}
+"sbquo", 3, {226, 128, 154}
+"scap", 3, {226, 170, 184}
+"Scaron", 2, {197, 160}
+"scaron", 2, {197, 161}
+"Sc", 3, {226, 170, 188}
+"sc", 3, {226, 137, 187}
+"sccue", 3, {226, 137, 189}
+"sce", 3, {226, 170, 176}
+"scE", 3, {226, 170, 180}
+"Scedil", 2, {197, 158}
+"scedil", 2, {197, 159}
+"Scirc", 2, {197, 156}
+"scirc", 2, {197, 157}
+"scnap", 3, {226, 170, 186}
+"scnE", 3, {226, 170, 182}
+"scnsim", 3, {226, 139, 169}
+"scpolint", 3, {226, 168, 147}
+"scsim", 3, {226, 137, 191}
+"Scy", 2, {208, 161}
+"scy", 2, {209, 129}
+"sdotb", 3, {226, 138, 161}
+"sdot", 3, {226, 139, 133}
+"sdote", 3, {226, 169, 166}
+"searhk", 3, {226, 164, 165}
+"searr", 3, {226, 134, 152}
+"seArr", 3, {226, 135, 152}
+"searrow", 3, {226, 134, 152}
+"sect", 2, {194, 167}
+"semi", 1, {59}
+"seswar", 3, {226, 164, 169}
+"setminus", 3, {226, 136, 150}
+"setmn", 3, {226, 136, 150}
+"sext", 3, {226, 156, 182}
+"Sfr", 4, {240, 157, 148, 150}
+"sfr", 4, {240, 157, 148, 176}
+"sfrown", 3, {226, 140, 162}
+"sharp", 3, {226, 153, 175}
+"SHCHcy", 2, {208, 169}
+"shchcy", 2, {209, 137}
+"SHcy", 2, {208, 168}
+"shcy", 2, {209, 136}
+"ShortDownArrow", 3, {226, 134, 147}
+"ShortLeftArrow", 3, {226, 134, 144}
+"shortmid", 3, {226, 136, 163}
+"shortparallel", 3, {226, 136, 165}
+"ShortRightArrow", 3, {226, 134, 146}
+"ShortUpArrow", 3, {226, 134, 145}
+"shy", 2, {194, 173}
+"Sigma", 2, {206, 163}
+"sigma", 2, {207, 131}
+"sigmaf", 2, {207, 130}
+"sigmav", 2, {207, 130}
+"sim", 3, {226, 136, 188}
+"simdot", 3, {226, 169, 170}
+"sime", 3, {226, 137, 131}
+"simeq", 3, {226, 137, 131}
+"simg", 3, {226, 170, 158}
+"simgE", 3, {226, 170, 160}
+"siml", 3, {226, 170, 157}
+"simlE", 3, {226, 170, 159}
+"simne", 3, {226, 137, 134}
+"simplus", 3, {226, 168, 164}
+"simrarr", 3, {226, 165, 178}
+"slarr", 3, {226, 134, 144}
+"SmallCircle", 3, {226, 136, 152}
+"smallsetminus", 3, {226, 136, 150}
+"smashp", 3, {226, 168, 179}
+"smeparsl", 3, {226, 167, 164}
+"smid", 3, {226, 136, 163}
+"smile", 3, {226, 140, 163}
+"smt", 3, {226, 170, 170}
+"smte", 3, {226, 170, 172}
+"smtes", 3, {226, 170, 172}
+"SOFTcy", 2, {208, 172}
+"softcy", 2, {209, 140}
+"solbar", 3, {226, 140, 191}
+"solb", 3, {226, 167, 132}
+"sol", 1, {47}
+"Sopf", 4, {240, 157, 149, 138}
+"sopf", 4, {240, 157, 149, 164}
+"spades", 3, {226, 153, 160}
+"spadesuit", 3, {226, 153, 160}
+"spar", 3, {226, 136, 165}
+"sqcap", 3, {226, 138, 147}
+"sqcaps", 3, {226, 138, 147}
+"sqcup", 3, {226, 138, 148}
+"sqcups", 3, {226, 138, 148}
+"Sqrt", 3, {226, 136, 154}
+"sqsub", 3, {226, 138, 143}
+"sqsube", 3, {226, 138, 145}
+"sqsubset", 3, {226, 138, 143}
+"sqsubseteq", 3, {226, 138, 145}
+"sqsup", 3, {226, 138, 144}
+"sqsupe", 3, {226, 138, 146}
+"sqsupset", 3, {226, 138, 144}
+"sqsupseteq", 3, {226, 138, 146}
+"square", 3, {226, 150, 161}
+"Square", 3, {226, 150, 161}
+"SquareIntersection", 3, {226, 138, 147}
+"SquareSubset", 3, {226, 138, 143}
+"SquareSubsetEqual", 3, {226, 138, 145}
+"SquareSuperset", 3, {226, 138, 144}
+"SquareSupersetEqual", 3, {226, 138, 146}
+"SquareUnion", 3, {226, 138, 148}
+"squarf", 3, {226, 150, 170}
+"squ", 3, {226, 150, 161}
+"squf", 3, {226, 150, 170}
+"srarr", 3, {226, 134, 146}
+"Sscr", 4, {240, 157, 146, 174}
+"sscr", 4, {240, 157, 147, 136}
+"ssetmn", 3, {226, 136, 150}
+"ssmile", 3, {226, 140, 163}
+"sstarf", 3, {226, 139, 134}
+"Star", 3, {226, 139, 134}
+"star", 3, {226, 152, 134}
+"starf", 3, {226, 152, 133}
+"straightepsilon", 2, {207, 181}
+"straightphi", 2, {207, 149}
+"strns", 2, {194, 175}
+"sub", 3, {226, 138, 130}
+"Sub", 3, {226, 139, 144}
+"subdot", 3, {226, 170, 189}
+"subE", 3, {226, 171, 133}
+"sube", 3, {226, 138, 134}
+"subedot", 3, {226, 171, 131}
+"submult", 3, {226, 171, 129}
+"subnE", 3, {226, 171, 139}
+"subne", 3, {226, 138, 138}
+"subplus", 3, {226, 170, 191}
+"subrarr", 3, {226, 165, 185}
+"subset", 3, {226, 138, 130}
+"Subset", 3, {226, 139, 144}
+"subseteq", 3, {226, 138, 134}
+"subseteqq", 3, {226, 171, 133}
+"SubsetEqual", 3, {226, 138, 134}
+"subsetneq", 3, {226, 138, 138}
+"subsetneqq", 3, {226, 171, 139}
+"subsim", 3, {226, 171, 135}
+"subsub", 3, {226, 171, 149}
+"subsup", 3, {226, 171, 147}
+"succapprox", 3, {226, 170, 184}
+"succ", 3, {226, 137, 187}
+"succcurlyeq", 3, {226, 137, 189}
+"Succeeds", 3, {226, 137, 187}
+"SucceedsEqual", 3, {226, 170, 176}
+"SucceedsSlantEqual", 3, {226, 137, 189}
+"SucceedsTilde", 3, {226, 137, 191}
+"succeq", 3, {226, 170, 176}
+"succnapprox", 3, {226, 170, 186}
+"succneqq", 3, {226, 170, 182}
+"succnsim", 3, {226, 139, 169}
+"succsim", 3, {226, 137, 191}
+"SuchThat", 3, {226, 136, 139}
+"sum", 3, {226, 136, 145}
+"Sum", 3, {226, 136, 145}
+"sung", 3, {226, 153, 170}
+"sup1", 2, {194, 185}
+"sup2", 2, {194, 178}
+"sup3", 2, {194, 179}
+"sup", 3, {226, 138, 131}
+"Sup", 3, {226, 139, 145}
+"supdot", 3, {226, 170, 190}
+"supdsub", 3, {226, 171, 152}
+"supE", 3, {226, 171, 134}
+"supe", 3, {226, 138, 135}
+"supedot", 3, {226, 171, 132}
+"Superset", 3, {226, 138, 131}
+"SupersetEqual", 3, {226, 138, 135}
+"suphsol", 3, {226, 159, 137}
+"suphsub", 3, {226, 171, 151}
+"suplarr", 3, {226, 165, 187}
+"supmult", 3, {226, 171, 130}
+"supnE", 3, {226, 171, 140}
+"supne", 3, {226, 138, 139}
+"supplus", 3, {226, 171, 128}
+"supset", 3, {226, 138, 131}
+"Supset", 3, {226, 139, 145}
+"supseteq", 3, {226, 138, 135}
+"supseteqq", 3, {226, 171, 134}
+"supsetneq", 3, {226, 138, 139}
+"supsetneqq", 3, {226, 171, 140}
+"supsim", 3, {226, 171, 136}
+"supsub", 3, {226, 171, 148}
+"supsup", 3, {226, 171, 150}
+"swarhk", 3, {226, 164, 166}
+"swarr", 3, {226, 134, 153}
+"swArr", 3, {226, 135, 153}
+"swarrow", 3, {226, 134, 153}
+"swnwar", 3, {226, 164, 170}
+"szlig", 2, {195, 159}
+"Tab", 1, {9}
+"target", 3, {226, 140, 150}
+"Tau", 2, {206, 164}
+"tau", 2, {207, 132}
+"tbrk", 3, {226, 142, 180}
+"Tcaron", 2, {197, 164}
+"tcaron", 2, {197, 165}
+"Tcedil", 2, {197, 162}
+"tcedil", 2, {197, 163}
+"Tcy", 2, {208, 162}
+"tcy", 2, {209, 130}
+"tdot", 3, {226, 131, 155}
+"telrec", 3, {226, 140, 149}
+"Tfr", 4, {240, 157, 148, 151}
+"tfr", 4, {240, 157, 148, 177}
+"there4", 3, {226, 136, 180}
+"therefore", 3, {226, 136, 180}
+"Therefore", 3, {226, 136, 180}
+"Theta", 2, {206, 152}
+"theta", 2, {206, 184}
+"thetasym", 2, {207, 145}
+"thetav", 2, {207, 145}
+"thickapprox", 3, {226, 137, 136}
+"thicksim", 3, {226, 136, 188}
+"ThickSpace", 3, {226, 129, 159}
+"ThinSpace", 3, {226, 128, 137}
+"thinsp", 3, {226, 128, 137}
+"thkap", 3, {226, 137, 136}
+"thksim", 3, {226, 136, 188}
+"THORN", 2, {195, 158}
+"thorn", 2, {195, 190}
+"tilde", 2, {203, 156}
+"Tilde", 3, {226, 136, 188}
+"TildeEqual", 3, {226, 137, 131}
+"TildeFullEqual", 3, {226, 137, 133}
+"TildeTilde", 3, {226, 137, 136}
+"timesbar", 3, {226, 168, 177}
+"timesb", 3, {226, 138, 160}
+"times", 2, {195, 151}
+"timesd", 3, {226, 168, 176}
+"tint", 3, {226, 136, 173}
+"toea", 3, {226, 164, 168}
+"topbot", 3, {226, 140, 182}
+"topcir", 3, {226, 171, 177}
+"top", 3, {226, 138, 164}
+"Topf", 4, {240, 157, 149, 139}
+"topf", 4, {240, 157, 149, 165}
+"topfork", 3, {226, 171, 154}
+"tosa", 3, {226, 164, 169}
+"tprime", 3, {226, 128, 180}
+"trade", 3, {226, 132, 162}
+"TRADE", 3, {226, 132, 162}
+"triangle", 3, {226, 150, 181}
+"triangledown", 3, {226, 150, 191}
+"triangleleft", 3, {226, 151, 131}
+"trianglelefteq", 3, {226, 138, 180}
+"triangleq", 3, {226, 137, 156}
+"triangleright", 3, {226, 150, 185}
+"trianglerighteq", 3, {226, 138, 181}
+"tridot", 3, {226, 151, 172}
+"trie", 3, {226, 137, 156}
+"triminus", 3, {226, 168, 186}
+"TripleDot", 3, {226, 131, 155}
+"triplus", 3, {226, 168, 185}
+"trisb", 3, {226, 167, 141}
+"tritime", 3, {226, 168, 187}
+"trpezium", 3, {226, 143, 162}
+"Tscr", 4, {240, 157, 146, 175}
+"tscr", 4, {240, 157, 147, 137}
+"TScy", 2, {208, 166}
+"tscy", 2, {209, 134}
+"TSHcy", 2, {208, 139}
+"tshcy", 2, {209, 155}
+"Tstrok", 2, {197, 166}
+"tstrok", 2, {197, 167}
+"twixt", 3, {226, 137, 172}
+"twoheadleftarrow", 3, {226, 134, 158}
+"twoheadrightarrow", 3, {226, 134, 160}
+"Uacute", 2, {195, 154}
+"uacute", 2, {195, 186}
+"uarr", 3, {226, 134, 145}
+"Uarr", 3, {226, 134, 159}
+"uArr", 3, {226, 135, 145}
+"Uarrocir", 3, {226, 165, 137}
+"Ubrcy", 2, {208, 142}
+"ubrcy", 2, {209, 158}
+"Ubreve", 2, {197, 172}
+"ubreve", 2, {197, 173}
+"Ucirc", 2, {195, 155}
+"ucirc", 2, {195, 187}
+"Ucy", 2, {208, 163}
+"ucy", 2, {209, 131}
+"udarr", 3, {226, 135, 133}
+"Udblac", 2, {197, 176}
+"udblac", 2, {197, 177}
+"udhar", 3, {226, 165, 174}
+"ufisht", 3, {226, 165, 190}
+"Ufr", 4, {240, 157, 148, 152}
+"ufr", 4, {240, 157, 148, 178}
+"Ugrave", 2, {195, 153}
+"ugrave", 2, {195, 185}
+"uHar", 3, {226, 165, 163}
+"uharl", 3, {226, 134, 191}
+"uharr", 3, {226, 134, 190}
+"uhblk", 3, {226, 150, 128}
+"ulcorn", 3, {226, 140, 156}
+"ulcorner", 3, {226, 140, 156}
+"ulcrop", 3, {226, 140, 143}
+"ultri", 3, {226, 151, 184}
+"Umacr", 2, {197, 170}
+"umacr", 2, {197, 171}
+"uml", 2, {194, 168}
+"UnderBar", 1, {95}
+"UnderBrace", 3, {226, 143, 159}
+"UnderBracket", 3, {226, 142, 181}
+"UnderParenthesis", 3, {226, 143, 157}
+"Union", 3, {226, 139, 131}
+"UnionPlus", 3, {226, 138, 142}
+"Uogon", 2, {197, 178}
+"uogon", 2, {197, 179}
+"Uopf", 4, {240, 157, 149, 140}
+"uopf", 4, {240, 157, 149, 166}
+"UpArrowBar", 3, {226, 164, 146}
+"uparrow", 3, {226, 134, 145}
+"UpArrow", 3, {226, 134, 145}
+"Uparrow", 3, {226, 135, 145}
+"UpArrowDownArrow", 3, {226, 135, 133}
+"updownarrow", 3, {226, 134, 149}
+"UpDownArrow", 3, {226, 134, 149}
+"Updownarrow", 3, {226, 135, 149}
+"UpEquilibrium", 3, {226, 165, 174}
+"upharpoonleft", 3, {226, 134, 191}
+"upharpoonright", 3, {226, 134, 190}
+"uplus", 3, {226, 138, 142}
+"UpperLeftArrow", 3, {226, 134, 150}
+"UpperRightArrow", 3, {226, 134, 151}
+"upsi", 2, {207, 133}
+"Upsi", 2, {207, 146}
+"upsih", 2, {207, 146}
+"Upsilon", 2, {206, 165}
+"upsilon", 2, {207, 133}
+"UpTeeArrow", 3, {226, 134, 165}
+"UpTee", 3, {226, 138, 165}
+"upuparrows", 3, {226, 135, 136}
+"urcorn", 3, {226, 140, 157}
+"urcorner", 3, {226, 140, 157}
+"urcrop", 3, {226, 140, 142}
+"Uring", 2, {197, 174}
+"uring", 2, {197, 175}
+"urtri", 3, {226, 151, 185}
+"Uscr", 4, {240, 157, 146, 176}
+"uscr", 4, {240, 157, 147, 138}
+"utdot", 3, {226, 139, 176}
+"Utilde", 2, {197, 168}
+"utilde", 2, {197, 169}
+"utri", 3, {226, 150, 181}
+"utrif", 3, {226, 150, 180}
+"uuarr", 3, {226, 135, 136}
+"Uuml", 2, {195, 156}
+"uuml", 2, {195, 188}
+"uwangle", 3, {226, 166, 167}
+"vangrt", 3, {226, 166, 156}
+"varepsilon", 2, {207, 181}
+"varkappa", 2, {207, 176}
+"varnothing", 3, {226, 136, 133}
+"varphi", 2, {207, 149}
+"varpi", 2, {207, 150}
+"varpropto", 3, {226, 136, 157}
+"varr", 3, {226, 134, 149}
+"vArr", 3, {226, 135, 149}
+"varrho", 2, {207, 177}
+"varsigma", 2, {207, 130}
+"varsubsetneq", 3, {226, 138, 138}
+"varsubsetneqq", 3, {226, 171, 139}
+"varsupsetneq", 3, {226, 138, 139}
+"varsupsetneqq", 3, {226, 171, 140}
+"vartheta", 2, {207, 145}
+"vartriangleleft", 3, {226, 138, 178}
+"vartriangleright", 3, {226, 138, 179}
+"vBar", 3, {226, 171, 168}
+"Vbar", 3, {226, 171, 171}
+"vBarv", 3, {226, 171, 169}
+"Vcy", 2, {208, 146}
+"vcy", 2, {208, 178}
+"vdash", 3, {226, 138, 162}
+"vDash", 3, {226, 138, 168}
+"Vdash", 3, {226, 138, 169}
+"VDash", 3, {226, 138, 171}
+"Vdashl", 3, {226, 171, 166}
+"veebar", 3, {226, 138, 187}
+"vee", 3, {226, 136, 168}
+"Vee", 3, {226, 139, 129}
+"veeeq", 3, {226, 137, 154}
+"vellip", 3, {226, 139, 174}
+"verbar", 1, {124}
+"Verbar", 3, {226, 128, 150}
+"vert", 1, {124}
+"Vert", 3, {226, 128, 150}
+"VerticalBar", 3, {226, 136, 163}
+"VerticalLine", 1, {124}
+"VerticalSeparator", 3, {226, 157, 152}
+"VerticalTilde", 3, {226, 137, 128}
+"VeryThinSpace", 3, {226, 128, 138}
+"Vfr", 4, {240, 157, 148, 153}
+"vfr", 4, {240, 157, 148, 179}
+"vltri", 3, {226, 138, 178}
+"vnsub", 3, {226, 138, 130}
+"vnsup", 3, {226, 138, 131}
+"Vopf", 4, {240, 157, 149, 141}
+"vopf", 4, {240, 157, 149, 167}
+"vprop", 3, {226, 136, 157}
+"vrtri", 3, {226, 138, 179}
+"Vscr", 4, {240, 157, 146, 177}
+"vscr", 4, {240, 157, 147, 139}
+"vsubnE", 3, {226, 171, 139}
+"vsubne", 3, {226, 138, 138}
+"vsupnE", 3, {226, 171, 140}
+"vsupne", 3, {226, 138, 139}
+"Vvdash", 3, {226, 138, 170}
+"vzigzag", 3, {226, 166, 154}
+"Wcirc", 2, {197, 180}
+"wcirc", 2, {197, 181}
+"wedbar", 3, {226, 169, 159}
+"wedge", 3, {226, 136, 167}
+"Wedge", 3, {226, 139, 128}
+"wedgeq", 3, {226, 137, 153}
+"weierp", 3, {226, 132, 152}
+"Wfr", 4, {240, 157, 148, 154}
+"wfr", 4, {240, 157, 148, 180}
+"Wopf", 4, {240, 157, 149, 142}
+"wopf", 4, {240, 157, 149, 168}
+"wp", 3, {226, 132, 152}
+"wr", 3, {226, 137, 128}
+"wreath", 3, {226, 137, 128}
+"Wscr", 4, {240, 157, 146, 178}
+"wscr", 4, {240, 157, 147, 140}
+"xcap", 3, {226, 139, 130}
+"xcirc", 3, {226, 151, 175}
+"xcup", 3, {226, 139, 131}
+"xdtri", 3, {226, 150, 189}
+"Xfr", 4, {240, 157, 148, 155}
+"xfr", 4, {240, 157, 148, 181}
+"xharr", 3, {226, 159, 183}
+"xhArr", 3, {226, 159, 186}
+"Xi", 2, {206, 158}
+"xi", 2, {206, 190}
+"xlarr", 3, {226, 159, 181}
+"xlArr", 3, {226, 159, 184}
+"xmap", 3, {226, 159, 188}
+"xnis", 3, {226, 139, 187}
+"xodot", 3, {226, 168, 128}
+"Xopf", 4, {240, 157, 149, 143}
+"xopf", 4, {240, 157, 149, 169}
+"xoplus", 3, {226, 168, 129}
+"xotime", 3, {226, 168, 130}
+"xrarr", 3, {226, 159, 182}
+"xrArr", 3, {226, 159, 185}
+"Xscr", 4, {240, 157, 146, 179}
+"xscr", 4, {240, 157, 147, 141}
+"xsqcup", 3, {226, 168, 134}
+"xuplus", 3, {226, 168, 132}
+"xutri", 3, {226, 150, 179}
+"xvee", 3, {226, 139, 129}
+"xwedge", 3, {226, 139, 128}
+"Yacute", 2, {195, 157}
+"yacute", 2, {195, 189}
+"YAcy", 2, {208, 175}
+"yacy", 2, {209, 143}
+"Ycirc", 2, {197, 182}
+"ycirc", 2, {197, 183}
+"Ycy", 2, {208, 171}
+"ycy", 2, {209, 139}
+"yen", 2, {194, 165}
+"Yfr", 4, {240, 157, 148, 156}
+"yfr", 4, {240, 157, 148, 182}
+"YIcy", 2, {208, 135}
+"yicy", 2, {209, 151}
+"Yopf", 4, {240, 157, 149, 144}
+"yopf", 4, {240, 157, 149, 170}
+"Yscr", 4, {240, 157, 146, 180}
+"yscr", 4, {240, 157, 147, 142}
+"YUcy", 2, {208, 174}
+"yucy", 2, {209, 142}
+"yuml", 2, {195, 191}
+"Yuml", 2, {197, 184}
+"Zacute", 2, {197, 185}
+"zacute", 2, {197, 186}
+"Zcaron", 2, {197, 189}
+"zcaron", 2, {197, 190}
+"Zcy", 2, {208, 151}
+"zcy", 2, {208, 183}
+"Zdot", 2, {197, 187}
+"zdot", 2, {197, 188}
+"zeetrf", 3, {226, 132, 168}
+"ZeroWidthSpace", 3, {226, 128, 139}
+"Zeta", 2, {206, 150}
+"zeta", 2, {206, 182}
+"zfr", 4, {240, 157, 148, 183}
+"Zfr", 3, {226, 132, 168}
+"ZHcy", 2, {208, 150}
+"zhcy", 2, {208, 182}
+"zigrarr", 3, {226, 135, 157}
+"zopf", 4, {240, 157, 149, 171}
+"Zopf", 3, {226, 132, 164}
+"Zscr", 4, {240, 157, 146, 181}
+"zscr", 4, {240, 157, 147, 143}
+"zwj", 3, {226, 128, 141}
+"zwnj", 3, {226, 128, 140}
diff --git a/src/html/html_unescape.h b/src/html/html_unescape.h
new file mode 100644
index 0000000..5d12662
--- /dev/null
+++ b/src/html/html_unescape.h
@@ -0,0 +1,9746 @@
+/* C code produced by gperf version 3.0.4 */
+/* Command-line: gperf -I -t -N find_entity -H hash_entity -K entity -C -l --null-strings -m5 src/html/html_unescape.gperf */
+/* Computed positions: -k'1-7,10,12,$' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+error "gperf generated tables don't work with this execution character set. Please report a bug to ."
+#endif
+
+#line 1 "src/html/html_unescape.gperf"
+struct html_ent {
+ const char *entity;
+ unsigned int utf8_len;
+ unsigned char utf8[4];
+};
+#include
+
+#define TOTAL_KEYWORDS 2125
+#define MIN_WORD_LENGTH 2
+#define MAX_WORD_LENGTH 31
+#define MIN_HASH_VALUE 39
+#define MAX_HASH_VALUE 16000
+/* maximum key range = 15962, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+hash_entity (str, len)
+ register const char *str;
+ register unsigned int len;
+{
+ static const unsigned short asso_values[] =
+ {
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 2,
+ 3, 7, 2, 4, 8, 16001, 10, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 1890, 1538, 220, 165, 1045,
+ 535, 1971, 1187, 1262, 35, 126, 201, 133, 350, 1487,
+ 1965, 3, 478, 134, 8, 147, 73, 41, 23, 212,
+ 9, 16001, 2, 16001, 2, 16001, 16001, 4154, 29, 3168,
+ 429, 10, 146, 1925, 2307, 280, 1313, 1924, 4, 651,
+ 27, 1031, 65, 176, 2, 6, 17, 15, 107, 482,
+ 3207, 3865, 757, 131, 178, 4, 4, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001,
+ 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001, 16001
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[11]];
+ /*FALLTHROUGH*/
+ case 11:
+ case 10:
+ hval += asso_values[(unsigned char)str[9]];
+ /*FALLTHROUGH*/
+ case 9:
+ case 8:
+ case 7:
+ hval += asso_values[(unsigned char)str[6]];
+ /*FALLTHROUGH*/
+ case 6:
+ hval += asso_values[(unsigned char)str[5]];
+ /*FALLTHROUGH*/
+ case 5:
+ hval += asso_values[(unsigned char)str[4]+1];
+ /*FALLTHROUGH*/
+ case 4:
+ hval += asso_values[(unsigned char)str[3]+3];
+ /*FALLTHROUGH*/
+ case 3:
+ hval += asso_values[(unsigned char)str[2]+1];
+ /*FALLTHROUGH*/
+ case 2:
+ hval += asso_values[(unsigned char)str[1]+4];
+ /*FALLTHROUGH*/
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+#ifdef __GNUC__
+__inline
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const struct html_ent *
+find_entity (str, len)
+ register const char *str;
+ register unsigned int len;
+{
+ static const unsigned char lengthtable[] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 6, 0, 6, 5, 0, 5, 3, 4,
+ 3, 4, 0, 4, 0, 2, 5, 4, 0, 0, 0, 2, 0, 7,
+ 0, 7, 3, 0, 5, 0, 0, 0, 0, 0, 4, 0, 0, 6,
+ 0, 0, 0, 3, 6, 0, 4, 0, 0, 0, 0, 6, 4, 5,
+ 0, 0, 0, 5, 0, 5, 0, 6, 0, 0, 0, 4, 5, 5,
+ 5, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,
+ 0, 0, 0, 3, 4, 0, 3, 0, 0, 5, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 0,
+ 5, 0, 5, 6, 0, 6, 5, 0, 2, 5, 0, 5, 0, 0,
+ 0, 0, 4, 0, 0, 0, 3, 0, 3, 5, 0, 0, 5, 0,
+ 0, 0, 6, 0, 10, 0, 4, 0, 0, 5, 3, 5, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 3, 0, 0, 0, 0, 6, 6,
+ 0, 6, 0, 0, 0, 0, 6, 0, 6, 0, 2, 0, 0, 0,
+ 4, 7, 0, 7, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 4, 0, 4, 6, 0, 3, 0, 0, 0, 0, 0, 0, 4,
+ 4, 3, 0, 4, 0, 0, 2, 0, 0, 0, 4, 0, 4, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 2, 0, 0, 0, 5, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 3, 2, 4, 0, 6, 0, 0, 3, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 0, 0, 0,
+ 0, 4, 6, 0, 0, 0, 5, 5, 5, 0, 13, 0, 0, 4,
+ 0, 0, 5, 0, 4, 4, 5, 17, 18, 0, 0, 0, 0, 0,
+ 5, 0, 0, 17, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0,
+ 5, 5, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 6, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 6, 0, 0,
+ 0, 4, 0, 0, 5, 0, 6, 6, 6, 6, 6, 6, 6, 0,
+ 0, 6, 0, 6, 0, 6, 6, 6, 6, 6, 6, 0, 0, 0,
+ 6, 0, 6, 3, 4, 0, 0, 4, 3, 5, 0, 0, 3, 0,
+ 0, 0, 11, 5, 0, 0, 0, 4, 0, 0, 6, 0, 0, 0,
+ 5, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 5, 3, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 0, 4,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 5, 0, 0, 0, 0,
+ 3, 6, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 4, 6,
+ 0, 0, 8, 0, 8, 0, 2, 0, 0, 0, 0, 4, 0, 0,
+ 0, 4, 0, 6, 0, 0, 0, 0, 6, 0, 4, 0, 0, 0,
+ 0, 6, 0, 5, 6, 2, 5, 8, 5, 0, 0, 4, 0, 4,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 9, 0, 4, 4,
+ 4, 0, 4, 6, 4, 4, 4, 0, 0, 0, 5, 4, 5, 4,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 4, 5, 4,
+ 5, 0, 0, 4, 0, 5, 0, 0, 0, 4, 0, 0, 0, 0,
+ 4, 4, 0, 5, 0, 0, 11, 0, 0, 6, 0, 0, 3, 0,
+ 0, 0, 0, 6, 0, 4, 0, 0, 4, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 7, 4, 4, 0, 7, 0, 0, 0, 0, 0,
+ 5, 0, 0, 0, 3, 8, 4, 0, 0, 0, 5, 0, 6, 0,
+ 0, 0, 0, 6, 0, 4, 0, 0, 0, 5, 0, 6, 0, 0,
+ 0, 5, 5, 0, 0, 3, 6, 2, 0, 0, 4, 0, 0, 7,
+ 0, 4, 0, 4, 4, 4, 3, 5, 0, 0, 0, 0, 0, 0,
+ 6, 0, 4, 4, 0, 0, 0, 12, 13, 0, 0, 6, 8, 0,
+ 2, 0, 0, 17, 0, 0, 0, 4, 0, 5, 0, 7, 0, 5,
+ 0, 0, 0, 5, 4, 5, 0, 0, 3, 0, 0, 0, 5, 0,
+ 5, 12, 13, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 0, 0, 7, 0, 0, 6, 6, 6, 0, 4, 0,
+ 0, 0, 0, 17, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 3, 6, 9, 0, 0,
+ 0, 9, 0, 0, 0, 0, 0, 6, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 19, 0, 5, 0, 0, 17, 0, 0,
+ 14, 0, 0, 0, 0, 12, 4, 0, 0, 0, 4, 0, 2, 0,
+ 4, 0, 6, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0,
+ 4, 0, 4, 4, 4, 0, 0, 0, 0, 4, 0, 4, 0, 4,
+ 9, 0, 0, 4, 2, 0, 0, 4, 2, 4, 4, 0, 0, 0,
+ 0, 4, 6, 0, 0, 6, 9, 4, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, 6, 0, 0,
+ 0, 0, 6, 4, 6, 4, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 9, 0, 0, 4, 0, 0, 0, 0, 0,
+ 7, 4, 4, 7, 0, 7, 5, 0, 0, 6, 4, 4, 4, 0,
+ 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 0,
+ 0, 0, 4, 0, 0, 4, 4, 6, 0, 0, 0, 3, 5, 3,
+ 5, 11, 4, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 0,
+ 7, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 3, 5, 4,
+ 0, 0, 0, 5, 0, 6, 9, 7, 2, 0, 4, 0, 0, 4,
+ 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 9, 10, 0,
+ 0, 0, 5, 0, 0, 0, 0, 11, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 4, 8, 6, 0, 0, 0, 0, 0, 8, 0, 0,
+ 0, 0, 0, 0, 0, 5, 6, 0, 0, 0, 13, 5, 5, 6,
+ 0, 0, 0, 0, 2, 0, 0, 0, 4, 2, 4, 0, 0, 6,
+ 4, 0, 4, 0, 0, 0, 4, 0, 21, 0, 0, 0, 6, 0,
+ 3, 0, 0, 0, 6, 6, 0, 3, 13, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 4, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 7, 3, 0, 0,
+ 0, 0, 0, 0, 0, 7, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0,
+ 3, 15, 3, 3, 3, 0, 0, 0, 3, 3, 6, 3, 6, 0,
+ 0, 0, 0, 3, 0, 0, 4, 3, 0, 3, 0, 12, 0, 0,
+ 0, 3, 0, 4, 0, 0, 0, 3, 0, 12, 0, 4, 5, 0,
+ 9, 0, 0, 7, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
+ 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5,
+ 0, 3, 3, 0, 0, 6, 0, 0, 0, 0, 0, 4, 0, 0,
+ 3, 3, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 3, 7, 0, 0, 8, 0, 0, 0, 0,
+ 0, 0, 3, 4, 0, 6, 0, 0, 0, 15, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 0, 9, 3,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 3, 24, 0, 0,
+ 0, 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 7, 4, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 3,
+ 0, 4, 0, 7, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 5, 2, 0, 0, 0, 6, 0, 3, 8, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 0, 9, 5, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7, 15, 7, 8, 4, 0, 5, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 4, 4, 5, 0, 0, 0, 0, 6, 14, 3,
+ 15, 0, 6, 0, 0, 0, 3, 0, 3, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 0, 0, 0,
+ 0, 0, 0, 5, 0, 0, 5, 16, 0, 5, 10, 0, 0, 0,
+ 5, 7, 0, 5, 0, 0, 6, 0, 3, 0, 0, 11, 5, 0,
+ 0, 4, 5, 0, 0, 5, 0, 0, 3, 0, 0, 0, 0, 8,
+ 0, 0, 0, 5, 0, 0, 0, 6, 3, 0, 0, 0, 0, 0,
+ 5, 0, 0, 3, 3, 3, 0, 0, 0, 6, 0, 0, 5, 6,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 11, 0, 6, 0, 6, 0, 0, 13, 0, 0, 7,
+ 0, 0, 0, 0, 7, 0, 6, 4, 5, 0, 3, 0, 0, 5,
+ 3, 0, 0, 0, 0, 0, 6, 0, 0, 4, 0, 0, 0, 0,
+ 3, 6, 5, 0, 0, 0, 0, 11, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 11, 0, 5, 5, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 8, 0, 7, 4, 0, 0, 0, 0, 5, 4, 9,
+ 0, 0, 5, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
+ 0, 6, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 4, 0, 0, 14, 5, 0, 0, 8,
+ 0, 0, 0, 20, 7, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 3, 0, 0, 4, 6, 0, 0, 0, 0, 6, 0, 0, 0, 7,
+ 0, 3, 6, 4, 6, 0, 0, 0, 0, 0, 0, 6, 3, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ 0, 11, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4,
+ 0, 0, 0, 0, 0, 0, 0, 13, 18, 5, 0, 3, 0, 7,
+ 0, 4, 0, 0, 0, 4, 0, 0, 10, 11, 0, 0, 0, 6,
+ 0, 6, 0, 0, 5, 0, 5, 12, 12, 0, 0, 0, 4, 0,
+ 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 14, 0, 0, 0, 2, 4, 8, 4, 0, 3, 0, 0, 7, 0,
+ 3, 0, 0, 0, 3, 2, 0, 0, 0, 0, 6, 0, 6, 4,
+ 6, 7, 6, 6, 6, 0, 10, 0, 0, 0, 3, 6, 0, 4,
+ 0, 0, 0, 0, 0, 4, 0, 6, 6, 0, 4, 0, 0, 0,
+ 7, 0, 0, 7, 0, 0, 4, 0, 4, 0, 5, 6, 0, 6,
+ 0, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 8, 14, 0, 3, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 7, 5, 0, 0, 0, 4, 0, 0, 0,
+ 17, 7, 0, 0, 4, 0, 0, 7, 0, 5, 0, 0, 7, 5,
+ 0, 0, 4, 0, 7, 2, 20, 0, 0, 0, 0, 13, 0, 0,
+ 0, 0, 6, 0, 7, 3, 5, 4, 0, 0, 0, 0, 5, 5,
+ 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0,
+ 5, 0, 5, 0, 0, 6, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 4, 9, 0, 5, 12, 0, 0, 0, 0, 5, 0, 5,
+ 4, 0, 0, 0, 9, 0, 0, 0, 10, 10, 0, 0, 4, 6,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 6, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 0,
+ 7, 0, 0, 0, 0, 7, 4, 0, 0, 0, 0, 0, 4, 0,
+ 9, 0, 0, 3, 0, 0, 0, 7, 0, 4, 0, 0, 5, 6,
+ 0, 0, 6, 3, 5, 4, 0, 0, 0, 0, 0, 6, 0, 5,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+ 6, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 0, 6, 0, 6, 0, 0, 6,
+ 0, 0, 18, 0, 6, 0, 20, 15, 0, 0, 4, 4, 0, 0,
+ 0, 6, 0, 0, 0, 3, 0, 0, 0, 0, 0, 5, 4, 4,
+ 0, 7, 0, 6, 0, 4, 0, 5, 0, 0, 0, 0, 5, 0,
+ 0, 0, 4, 4, 0, 0, 0, 0, 4, 0, 4, 0, 11, 0,
+ 20, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 4, 0, 0, 3, 0, 0, 6,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 13, 0, 0, 9, 0, 0, 0, 5,
+ 0, 0, 0, 5, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 0, 17, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 9, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 7, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 14, 0,
+ 0, 11, 0, 6, 0, 6, 0, 7, 5, 0, 0, 0, 6, 12,
+ 12, 0, 0, 0, 0, 16, 0, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 7,
+ 0, 0, 5, 0, 0, 0, 0, 0, 0, 6, 0, 14, 0, 0,
+ 0, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0,
+ 5, 0, 5, 0, 0, 0, 0, 0, 11, 6, 6, 3, 0, 0,
+ 0, 0, 7, 0, 6, 0, 6, 6, 4, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0,
+ 4, 4, 0, 0, 0, 0, 3, 3, 6, 0, 0, 0, 0, 0,
+ 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 6, 0,
+ 4, 4, 0, 0, 0, 0, 13, 0, 4, 0, 0, 0, 0, 4,
+ 2, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 10, 0, 9, 0, 0, 4, 6, 0, 5, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 8, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 0, 18, 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 7, 0, 0, 0, 0, 5, 0, 5,
+ 0, 0, 0, 6, 0, 0, 5, 0, 0, 6, 0, 6, 0, 0,
+ 13, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 6, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0,
+ 14, 0, 6, 15, 0, 0, 7, 0, 3, 0, 3, 0, 0, 0,
+ 9, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 15,
+ 0, 0, 0, 6, 0, 0, 6, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 4, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 2, 15, 0, 0,
+ 0, 5, 0, 5, 0, 4, 0, 0, 0, 0, 0, 0, 16, 0,
+ 3, 3, 10, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 4,
+ 5, 4, 0, 0, 6, 0, 5, 4, 0, 5, 5, 3, 5, 0,
+ 4, 0, 6, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 3, 0, 0, 6, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 8, 6, 0, 0, 0, 0, 0, 0, 0, 5, 16, 0,
+ 5, 7, 0, 6, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 5, 0, 0,
+ 0, 0, 6, 0, 5, 4, 5, 0, 5, 5, 0, 0, 0, 0,
+ 5, 2, 6, 4, 0, 5, 0, 0, 5, 0, 4, 0, 0, 0,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 3, 5, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 5, 0, 0, 4,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 4, 2, 6, 0, 6, 3, 3, 0, 0,
+ 3, 0, 4, 0, 6, 0, 3, 0, 0, 6, 0, 5, 31, 0,
+ 0, 0, 0, 0, 0, 0, 3, 6, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 6,
+ 0, 8, 0, 5, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 5, 0,
+ 0, 0, 19, 0, 0, 0, 0, 24, 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 5,
+ 0, 0, 0, 6, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0,
+ 0, 16, 5, 0, 0, 3, 4, 4, 0, 5, 4, 5, 0, 0,
+ 0, 13, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 6, 0, 3,
+ 0, 7, 0, 10, 0, 0, 0, 0, 6, 0, 6, 0, 0, 13,
+ 0, 0, 0, 5, 0, 8, 0, 6, 0, 6, 8, 6, 0, 0,
+ 6, 6, 0, 10, 0, 8, 6, 6, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 11, 0, 0, 0, 6, 0, 0, 0,
+ 0, 7, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 0, 0, 0, 17, 6, 0, 0, 0, 0, 0, 16, 0, 0,
+ 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 7, 0,
+ 14, 7, 6, 0, 6, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 10, 4, 14, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 4, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 6, 3, 8, 4, 6, 6, 0,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 6, 0, 4, 0, 2, 0, 20, 21, 0, 0, 2, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0, 14, 4, 6, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 5, 0, 0,
+ 4, 6, 0, 2, 7, 0, 6, 5, 0, 8, 0, 0, 5, 0,
+ 4, 0, 0, 0, 5, 0, 4, 15, 5, 0, 4, 6, 0, 0,
+ 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 17, 5, 0,
+ 0, 0, 9, 6, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 7, 5, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 0, 12, 0, 0, 0, 6, 0, 0, 0, 0, 10, 3, 0, 0,
+ 0, 4, 0, 5, 0, 0, 0, 0, 0, 4, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 9, 0, 6, 0, 6, 0, 0, 0, 0, 19,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 5, 0, 6, 3, 6,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 2, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 6, 0, 6, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 17, 0,
+ 0, 7, 0, 0, 2, 6, 2, 0, 0, 0, 2, 0, 0, 0,
+ 0, 3, 8, 0, 0, 3, 0, 5, 0, 5, 6, 0, 0, 0,
+ 0, 18, 0, 0, 0, 0, 5, 0, 7, 0, 0, 9, 0, 0,
+ 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 0, 4, 0, 0, 4, 0, 9, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 0, 4, 0,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 5, 0, 5, 6,
+ 0, 0, 0, 3, 3, 5, 0, 0, 0, 0, 6, 0, 0, 0,
+ 6, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4,
+ 6, 13, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
+ 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ 8, 6, 8, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 12, 0, 6, 0, 0, 0, 6, 0, 0,
+ 0, 6, 4, 0, 0, 7, 6, 5, 0, 0, 6, 0, 5, 5,
+ 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 5, 0, 6, 8,
+ 0, 0, 6, 0, 5, 8, 0, 0, 0, 6, 0, 4, 0, 9,
+ 0, 0, 0, 0, 4, 6, 4, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4,
+ 11, 0, 0, 8, 9, 0, 0, 0, 0, 3, 5, 3, 0, 0,
+ 0, 0, 6, 4, 0, 0, 0, 9, 4, 3, 0, 2, 0, 0,
+ 0, 0, 0, 7, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 14, 3, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 10, 7,
+ 5, 0, 6, 0, 6, 0, 3, 17, 0, 0, 0, 0, 0, 0,
+ 20, 0, 14, 4, 0, 0, 0, 0, 0, 0, 19, 6, 6, 0,
+ 10, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 6, 0,
+ 0, 3, 0, 0, 0, 4, 5, 0, 0, 4, 0, 5, 0, 0,
+ 0, 0, 0, 0, 7, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 7, 0, 3, 0, 4, 0, 3, 0, 4, 0, 0, 13,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
+ 6, 0, 0, 0, 0, 0, 7, 0, 13, 0, 0, 15, 0, 0,
+ 5, 9, 0, 0, 0, 6, 0, 6, 0, 0, 4, 6, 0, 0,
+ 6, 4, 4, 0, 16, 0, 4, 0, 3, 0, 0, 11, 5, 15,
+ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 0, 0, 5, 0, 5, 4, 0, 0, 4, 0,
+ 20, 4, 0, 0, 0, 0, 0, 5, 15, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 22, 0, 0, 7,
+ 8, 0, 4, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 6, 7, 0, 0, 0, 0, 6, 0, 6, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 4, 0, 5, 0, 12, 15, 6, 0,
+ 13, 0, 4, 0, 5, 4, 6, 0, 0, 0, 0, 4, 0, 0,
+ 4, 3, 5, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0,
+ 0, 0, 0, 0, 4, 0, 0, 9, 0, 0, 20, 0, 4, 10,
+ 0, 0, 0, 0, 4, 0, 5, 0, 0, 8, 6, 0, 5, 4,
+ 0, 0, 3, 0, 4, 0, 0, 6, 6, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 9,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 17,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 14, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 14, 0, 0, 0, 0, 0, 0, 5, 6, 0, 5, 0, 0,
+ 0, 0, 0, 0, 5, 0, 8, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 16, 15, 4, 0, 0, 11, 0, 0, 0, 8, 0, 0,
+ 0, 0, 0, 0, 0, 2, 0, 5, 0, 10, 0, 0, 5, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0,
+ 5, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8, 6, 5, 4, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 6, 0,
+ 0, 0, 0, 2, 4, 5, 0, 0, 0, 8, 0, 0, 3, 0,
+ 8, 0, 0, 4, 18, 0, 0, 0, 0, 4, 5, 0, 0, 0,
+ 16, 0, 0, 0, 0, 7, 0, 2, 3, 5, 0, 0, 5, 0,
+ 4, 4, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 14, 0, 0, 0, 0, 5, 0, 0, 6, 0, 6, 0,
+ 5, 0, 5, 0, 5, 15, 0, 0, 8, 17, 12, 0, 0, 0,
+ 0, 0, 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0, 5, 0, 0, 20, 0, 0, 0, 0, 0,
+ 11, 0, 5, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 13,
+ 0, 0, 0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 5,
+ 8, 0, 0, 0, 0, 0, 6, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0,
+ 0, 13, 0, 0, 0, 0, 0, 8, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 16, 0, 14, 0, 18, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0,
+ 0, 14, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 8, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0,
+ 0, 0, 0, 0, 0, 0, 9, 0, 15, 0, 5, 0, 5, 0,
+ 0, 0, 0, 0, 0, 6, 5, 0, 0, 0, 0, 6, 4, 0,
+ 0, 9, 0, 0, 0, 0, 0, 6, 0, 6, 0, 0, 8, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 6, 2, 0, 0, 6, 0, 12, 6, 0, 0, 0, 16, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+ 0, 0, 14, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10, 8, 0, 5, 0, 0, 6,
+ 0, 0, 0, 6, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 5, 0, 0, 5, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 0, 0, 0, 14, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 9, 0,
+ 0, 0, 5, 0, 0, 0, 0, 4, 6, 0, 0, 0, 0, 0,
+ 0, 8, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 21, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 6, 0, 0, 0, 0, 0, 3, 5, 0,
+ 0, 5, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 2, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 14, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 5, 6, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 13, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 12, 0, 0, 0, 18, 10, 0, 0, 18, 0, 7, 0, 0,
+ 0, 6, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+ 0, 5, 0, 0, 0, 0, 6, 0, 0, 5, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 4, 0,
+ 0, 0, 5, 0, 12, 4, 12, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 4, 0, 0, 0, 0,
+ 7, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+ 5, 0, 0, 0, 5, 6, 7, 7, 0, 0, 0, 0, 0, 0,
+ 0, 6, 0, 8, 0, 0, 0, 0, 5, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 16, 0, 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 4, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0,
+ 0, 17, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 0, 17, 0, 5, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 8, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 0,
+ 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0,
+ 0, 0, 0, 0, 0, 8, 4, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 0, 4, 6, 8, 0, 5, 0,
+ 0, 4, 4, 0, 5, 4, 5, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 5, 0, 0, 18, 0, 5, 0, 0, 0, 19, 0, 0,
+ 8, 0, 14, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 11, 0, 5, 13, 0, 0, 0, 7,
+ 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0,
+ 4, 0, 6, 13, 0, 8, 0, 5, 0, 0, 0, 5, 0, 0,
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0,
+ 3, 0, 3, 0, 3, 0, 3, 3, 3, 4, 0, 4, 0, 3,
+ 5, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3,
+ 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 5,
+ 0, 18, 0, 0, 15, 7, 0, 3, 0, 0, 6, 5, 0, 5,
+ 0, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 12, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 7, 10, 0, 0, 0, 0, 0, 4, 0, 0, 9, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 11, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 12, 0, 0, 0, 5, 6, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 5, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 0, 0, 0, 0, 6, 5, 0, 0, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 15, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6, 0, 9, 6, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 7, 0, 0, 20, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 0, 0,
+ 0, 3, 0, 0, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 14, 0, 0, 0, 0, 5, 6, 0, 0, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 8, 0, 0, 5, 0, 0, 0, 0, 0, 0,
+ 5, 0, 0, 0, 0, 0, 6, 8, 0, 0, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 13, 0, 0, 0, 0, 7, 0, 0, 3, 14, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 7, 5, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 6, 11, 19, 0,
+ 0, 5, 17, 0, 0, 0, 0, 0, 16, 5, 0, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
+ 7, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 0, 7, 8, 0, 0, 0, 0, 0, 13, 0, 16, 5, 4,
+ 0, 0, 0, 6, 0, 0, 5, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 9, 6, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8,
+ 9, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 7, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 6, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 4, 10, 0, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 10, 0, 10, 0,
+ 0, 0, 21, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 11, 0, 20, 0, 3, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 3, 0, 0, 0, 0, 5, 14, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 5, 0,
+ 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0,
+ 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 8, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 5, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 7, 0,
+ 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 0, 0, 0, 0, 0, 16, 5, 0, 15, 0,
+ 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 0, 0, 6, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 11, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 0, 0, 0, 4, 7, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 8, 0, 0,
+ 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 4,
+ 0, 0, 11, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 18, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 14, 0, 0, 18, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0,
+ 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 12, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 13, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 11, 0,
+ 0, 5, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 9, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 21, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0,
+ 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15
+ };
+ static const struct html_ent wordlist[] =
+ {
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1502 "src/html/html_unescape.gperf"
+ {"rarr", 3, {226, 134, 146}},
+ {(char*)0},
+#line 834 "src/html/html_unescape.gperf"
+ {"larr", 3, {226, 134, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 845 "src/html/html_unescape.gperf"
+ {"lat", 3, {226, 170, 171}},
+ {(char*)0}, {(char*)0},
+#line 1904 "src/html/html_unescape.gperf"
+ {"uarr", 3, {226, 134, 145}},
+ {(char*)0}, {(char*)0},
+#line 1236 "src/html/html_unescape.gperf"
+ {"npr", 3, {226, 138, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1511 "src/html/html_unescape.gperf"
+ {"rarrtl", 3, {226, 134, 163}},
+ {(char*)0},
+#line 842 "src/html/html_unescape.gperf"
+ {"larrtl", 3, {226, 134, 162}},
+#line 1602 "src/html/html_unescape.gperf"
+ {"roarr", 3, {226, 135, 190}},
+ {(char*)0},
+#line 964 "src/html/html_unescape.gperf"
+ {"loarr", 3, {226, 135, 189}},
+#line 1169 "src/html/html_unescape.gperf"
+ {"not", 2, {194, 172}},
+#line 1610 "src/html/html_unescape.gperf"
+ {"rpar", 1, {41}},
+#line 147 "src/html/html_unescape.gperf"
+ {"bot", 3, {226, 138, 165}},
+#line 990 "src/html/html_unescape.gperf"
+ {"lpar", 1, {40}},
+ {(char*)0},
+#line 1716 "src/html/html_unescape.gperf"
+ {"spar", 3, {226, 136, 165}},
+ {(char*)0},
+#line 946 "src/html/html_unescape.gperf"
+ {"ll", 3, {226, 137, 170}},
+#line 1927 "src/html/html_unescape.gperf"
+ {"uharr", 3, {226, 134, 190}},
+#line 506 "src/html/html_unescape.gperf"
+ {"epar", 3, {226, 139, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 483 "src/html/html_unescape.gperf"
+ {"el", 3, {226, 170, 153}},
+ {(char*)0},
+#line 1608 "src/html/html_unescape.gperf"
+ {"rotimes", 3, {226, 168, 181}},
+ {(char*)0},
+#line 982 "src/html/html_unescape.gperf"
+ {"lotimes", 3, {226, 168, 180}},
+#line 1389 "src/html/html_unescape.gperf"
+ {"par", 3, {226, 136, 165}},
+ {(char*)0},
+#line 1133 "src/html/html_unescape.gperf"
+ {"nharr", 3, {226, 134, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1232 "src/html/html_unescape.gperf"
+ {"npar", 3, {226, 136, 166}},
+ {(char*)0}, {(char*)0},
+#line 1873 "src/html/html_unescape.gperf"
+ {"tprime", 3, {226, 128, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 487 "src/html/html_unescape.gperf"
+ {"els", 3, {226, 170, 149}},
+#line 507 "src/html/html_unescape.gperf"
+ {"eparsl", 3, {226, 167, 163}},
+ {(char*)0},
+#line 501 "src/html/html_unescape.gperf"
+ {"ensp", 3, {226, 128, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 194 "src/html/html_unescape.gperf"
+ {"bprime", 3, {226, 128, 181}},
+#line 956 "src/html/html_unescape.gperf"
+ {"lnap", 3, {226, 170, 137}},
+#line 138 "src/html/html_unescape.gperf"
+ {"blk14", 3, {226, 150, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 137 "src/html/html_unescape.gperf"
+ {"blk12", 3, {226, 150, 146}},
+ {(char*)0},
+#line 139 "src/html/html_unescape.gperf"
+ {"blk34", 3, {226, 150, 147}},
+ {(char*)0},
+#line 1233 "src/html/html_unescape.gperf"
+ {"nparsl", 3, {226, 171, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1144 "src/html/html_unescape.gperf"
+ {"nldr", 3, {226, 128, 165}},
+#line 1595 "src/html/html_unescape.gperf"
+ {"rlarr", 3, {226, 135, 132}},
+#line 1234 "src/html/html_unescape.gperf"
+ {"npart", 3, {226, 136, 130}},
+#line 945 "src/html/html_unescape.gperf"
+ {"llarr", 3, {226, 135, 135}},
+#line 1159 "src/html/html_unescape.gperf"
+ {"nlt", 3, {226, 137, 174}},
+#line 1697 "src/html/html_unescape.gperf"
+ {"slarr", 3, {226, 134, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1231 "src/html/html_unescape.gperf"
+ {"nparallel", 3, {226, 136, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1826 "src/html/html_unescape.gperf"
+ {"Tau", 2, {206, 164}},
+#line 1992 "src/html/html_unescape.gperf"
+ {"varr", 3, {226, 134, 149}},
+ {(char*)0},
+#line 1739 "src/html/html_unescape.gperf"
+ {"squ", 3, {226, 150, 161}},
+ {(char*)0}, {(char*)0},
+#line 1142 "src/html/html_unescape.gperf"
+ {"nlarr", 3, {226, 134, 154}},
+ {(char*)0}, {(char*)0},
+#line 1827 "src/html/html_unescape.gperf"
+ {"tau", 2, {207, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 958 "src/html/html_unescape.gperf"
+ {"lne", 3, {226, 170, 135}},
+#line 1613 "src/html/html_unescape.gperf"
+ {"rrarr", 3, {226, 135, 137}},
+ {(char*)0},
+#line 992 "src/html/html_unescape.gperf"
+ {"lrarr", 3, {226, 135, 134}},
+ {(char*)0},
+#line 1741 "src/html/html_unescape.gperf"
+ {"srarr", 3, {226, 134, 146}},
+#line 1557 "src/html/html_unescape.gperf"
+ {"rharul", 3, {226, 165, 172}},
+ {(char*)0},
+#line 941 "src/html/html_unescape.gperf"
+ {"lharul", 3, {226, 165, 170}},
+#line 526 "src/html/html_unescape.gperf"
+ {"erarr", 3, {226, 165, 177}},
+ {(char*)0},
+#line 1434 "src/html/html_unescape.gperf"
+ {"pr", 3, {226, 137, 186}},
+#line 1556 "src/html/html_unescape.gperf"
+ {"rharu", 3, {226, 135, 128}},
+ {(char*)0},
+#line 940 "src/html/html_unescape.gperf"
+ {"lharu", 3, {226, 134, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1905 "src/html/html_unescape.gperf"
+ {"Uarr", 3, {226, 134, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1129 "src/html/html_unescape.gperf"
+ {"nGt", 3, {226, 137, 171}},
+ {(char*)0},
+#line 141 "src/html/html_unescape.gperf"
+ {"bne", 1, {61}},
+#line 1242 "src/html/html_unescape.gperf"
+ {"nrarr", 3, {226, 134, 155}},
+ {(char*)0}, {(char*)0},
+#line 1819 "src/html/html_unescape.gperf"
+ {"swarr", 3, {226, 134, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1498 "src/html/html_unescape.gperf"
+ {"rarrap", 3, {226, 165, 181}},
+ {(char*)0},
+#line 1967 "src/html/html_unescape.gperf"
+ {"upuparrows", 3, {226, 135, 136}},
+ {(char*)0},
+#line 345 "src/html/html_unescape.gperf"
+ {"Darr", 3, {226, 134, 161}},
+ {(char*)0}, {(char*)0},
+#line 1517 "src/html/html_unescape.gperf"
+ {"rbarr", 3, {226, 164, 141}},
+#line 398 "src/html/html_unescape.gperf"
+ {"Dot", 2, {194, 168}},
+#line 848 "src/html/html_unescape.gperf"
+ {"lbarr", 3, {226, 164, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1307 "src/html/html_unescape.gperf"
+ {"nwarr", 3, {226, 134, 150}},
+ {(char*)0},
+#line 1704 "src/html/html_unescape.gperf"
+ {"smt", 3, {226, 170, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 497 "src/html/html_unescape.gperf"
+ {"emsp14", 3, {226, 128, 133}},
+#line 1508 "src/html/html_unescape.gperf"
+ {"rarrpl", 3, {226, 165, 133}},
+ {(char*)0},
+#line 840 "src/html/html_unescape.gperf"
+ {"larrpl", 3, {226, 164, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1406 "src/html/html_unescape.gperf"
+ {"phmmat", 3, {226, 132, 179}},
+ {(char*)0},
+#line 496 "src/html/html_unescape.gperf"
+ {"emsp13", 3, {226, 128, 132}},
+ {(char*)0},
+#line 1014 "src/html/html_unescape.gperf"
+ {"LT", 1, {60}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 835 "src/html/html_unescape.gperf"
+ {"Larr", 3, {226, 134, 158}},
+#line 1525 "src/html/html_unescape.gperf"
+ {"rbrkslu", 3, {226, 166, 144}},
+ {(char*)0},
+#line 855 "src/html/html_unescape.gperf"
+ {"lbrkslu", 3, {226, 166, 141}},
+ {(char*)0},
+#line 1082 "src/html/html_unescape.gperf"
+ {"napos", 2, {197, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1146 "src/html/html_unescape.gperf"
+ {"nle", 3, {226, 137, 176}},
+ {(char*)0},
+#line 1554 "src/html/html_unescape.gperf"
+ {"rHar", 3, {226, 165, 164}},
+ {(char*)0},
+#line 938 "src/html/html_unescape.gperf"
+ {"lHar", 3, {226, 165, 162}},
+#line 1477 "src/html/html_unescape.gperf"
+ {"qprime", 3, {226, 129, 151}},
+ {(char*)0},
+#line 829 "src/html/html_unescape.gperf"
+ {"lap", 3, {226, 170, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1087 "src/html/html_unescape.gperf"
+ {"nbsp", 2, {194, 160}},
+#line 1925 "src/html/html_unescape.gperf"
+ {"uHar", 3, {226, 165, 163}},
+#line 1868 "src/html/html_unescape.gperf"
+ {"top", 3, {226, 138, 164}},
+ {(char*)0},
+#line 2004 "src/html/html_unescape.gperf"
+ {"Vbar", 3, {226, 171, 171}},
+ {(char*)0}, {(char*)0},
+#line 947 "src/html/html_unescape.gperf"
+ {"Ll", 3, {226, 139, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1432 "src/html/html_unescape.gperf"
+ {"prap", 3, {226, 170, 183}},
+ {(char*)0},
+#line 498 "src/html/html_unescape.gperf"
+ {"emsp", 3, {226, 128, 131}},
+ {(char*)0}, {(char*)0},
+#line 1079 "src/html/html_unescape.gperf"
+ {"nap", 3, {226, 137, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 976 "src/html/html_unescape.gperf"
+ {"looparrowleft", 3, {226, 134, 171}},
+ {(char*)0},
+#line 870 "src/html/html_unescape.gperf"
+ {"le", 3, {226, 137, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1670 "src/html/html_unescape.gperf"
+ {"sharp", 3, {226, 153, 175}},
+ {(char*)0},
+#line 474 "src/html/html_unescape.gperf"
+ {"ee", 3, {226, 133, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 914 "src/html/html_unescape.gperf"
+ {"les", 3, {226, 169, 189}},
+#line 745 "src/html/html_unescape.gperf"
+ {"in", 3, {226, 136, 136}},
+#line 1461 "src/html/html_unescape.gperf"
+ {"prop", 3, {226, 136, 157}},
+ {(char*)0},
+#line 1866 "src/html/html_unescape.gperf"
+ {"topbot", 3, {226, 140, 182}},
+ {(char*)0}, {(char*)0},
+#line 750 "src/html/html_unescape.gperf"
+ {"int", 3, {226, 136, 171}},
+ {(char*)0},
+#line 1105 "src/html/html_unescape.gperf"
+ {"ne", 3, {226, 137, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1237 "src/html/html_unescape.gperf"
+ {"nprcue", 3, {226, 139, 160}},
+ {(char*)0},
+#line 1447 "src/html/html_unescape.gperf"
+ {"pre", 3, {226, 170, 175}},
+#line 509 "src/html/html_unescape.gperf"
+ {"epsi", 2, {206, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1960 "src/html/html_unescape.gperf"
+ {"upsi", 2, {207, 133}},
+#line 1839 "src/html/html_unescape.gperf"
+ {"there4", 3, {226, 136, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1523 "src/html/html_unescape.gperf"
+ {"rbrke", 3, {226, 166, 140}},
+#line 1658 "src/html/html_unescape.gperf"
+ {"searr", 3, {226, 134, 152}},
+#line 853 "src/html/html_unescape.gperf"
+ {"lbrke", 3, {226, 166, 139}},
+ {(char*)0},
+#line 132 "src/html/html_unescape.gperf"
+ {"blacktriangle", 3, {226, 150, 180}},
+ {(char*)0}, {(char*)0},
+#line 960 "src/html/html_unescape.gperf"
+ {"lneq", 3, {226, 170, 135}},
+ {(char*)0}, {(char*)0},
+#line 961 "src/html/html_unescape.gperf"
+ {"lneqq", 3, {226, 137, 168}},
+ {(char*)0},
+#line 1418 "src/html/html_unescape.gperf"
+ {"plus", 1, {43}},
+#line 1154 "src/html/html_unescape.gperf"
+ {"nles", 3, {226, 169, 189}},
+#line 1106 "src/html/html_unescape.gperf"
+ {"nedot", 3, {226, 137, 144}},
+#line 134 "src/html/html_unescape.gperf"
+ {"blacktriangleleft", 3, {226, 151, 130}},
+#line 135 "src/html/html_unescape.gperf"
+ {"blacktriangleright", 3, {226, 150, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1102 "src/html/html_unescape.gperf"
+ {"nearr", 3, {226, 134, 151}},
+ {(char*)0}, {(char*)0},
+#line 133 "src/html/html_unescape.gperf"
+ {"blacktriangledown", 3, {226, 150, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1155 "src/html/html_unescape.gperf"
+ {"nless", 3, {226, 137, 174}},
+#line 490 "src/html/html_unescape.gperf"
+ {"emacr", 2, {196, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2034 "src/html/html_unescape.gperf"
+ {"vprop", 3, {226, 136, 157}},
+#line 1934 "src/html/html_unescape.gperf"
+ {"umacr", 2, {197, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1701 "src/html/html_unescape.gperf"
+ {"smeparsl", 3, {226, 167, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1033 "src/html/html_unescape.gperf"
+ {"Map", 3, {226, 164, 133}},
+ {(char*)0}, {(char*)0},
+#line 1420 "src/html/html_unescape.gperf"
+ {"plusdu", 3, {226, 168, 165}},
+#line 1168 "src/html/html_unescape.gperf"
+ {"Not", 3, {226, 171, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2019 "src/html/html_unescape.gperf"
+ {"Verbar", 3, {226, 128, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1399 "src/html/html_unescape.gperf"
+ {"perp", 3, {226, 138, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 561 "src/html/html_unescape.gperf"
+ {"fltns", 3, {226, 150, 177}},
+#line 1423 "src/html/html_unescape.gperf"
+ {"plusmn", 2, {194, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1151 "src/html/html_unescape.gperf"
+ {"nleq", 3, {226, 137, 176}},
+ {(char*)0}, {(char*)0},
+#line 1152 "src/html/html_unescape.gperf"
+ {"nleqq", 3, {226, 137, 166}},
+ {(char*)0},
+#line 579 "src/html/html_unescape.gperf"
+ {"frac34", 2, {194, 190}},
+#line 573 "src/html/html_unescape.gperf"
+ {"frac14", 2, {194, 188}},
+#line 2018 "src/html/html_unescape.gperf"
+ {"verbar", 1, {124}},
+#line 571 "src/html/html_unescape.gperf"
+ {"frac12", 2, {194, 189}},
+#line 580 "src/html/html_unescape.gperf"
+ {"frac35", 3, {226, 133, 151}},
+#line 574 "src/html/html_unescape.gperf"
+ {"frac15", 3, {226, 133, 149}},
+#line 582 "src/html/html_unescape.gperf"
+ {"frac45", 3, {226, 133, 152}},
+ {(char*)0}, {(char*)0},
+#line 578 "src/html/html_unescape.gperf"
+ {"frac25", 3, {226, 133, 150}},
+ {(char*)0},
+#line 572 "src/html/html_unescape.gperf"
+ {"frac13", 3, {226, 133, 147}},
+ {(char*)0},
+#line 575 "src/html/html_unescape.gperf"
+ {"frac16", 3, {226, 133, 153}},
+#line 1466 "src/html/html_unescape.gperf"
+ {"prurel", 3, {226, 138, 176}},
+#line 577 "src/html/html_unescape.gperf"
+ {"frac23", 3, {226, 133, 148}},
+#line 581 "src/html/html_unescape.gperf"
+ {"frac38", 3, {226, 133, 156}},
+#line 576 "src/html/html_unescape.gperf"
+ {"frac18", 3, {226, 133, 155}},
+#line 583 "src/html/html_unescape.gperf"
+ {"frac56", 3, {226, 133, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 584 "src/html/html_unescape.gperf"
+ {"frac58", 3, {226, 133, 157}},
+ {(char*)0},
+#line 585 "src/html/html_unescape.gperf"
+ {"frac78", 3, {226, 133, 158}},
+#line 910 "src/html/html_unescape.gperf"
+ {"leq", 3, {226, 137, 164}},
+#line 344 "src/html/html_unescape.gperf"
+ {"darr", 3, {226, 134, 147}},
+ {(char*)0}, {(char*)0},
+#line 1961 "src/html/html_unescape.gperf"
+ {"Upsi", 2, {207, 146}},
+#line 399 "src/html/html_unescape.gperf"
+ {"dot", 2, {203, 153}},
+#line 1407 "src/html/html_unescape.gperf"
+ {"phone", 3, {226, 152, 142}},
+ {(char*)0}, {(char*)0},
+#line 219 "src/html/html_unescape.gperf"
+ {"Cap", 3, {226, 139, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 131 "src/html/html_unescape.gperf"
+ {"blacksquare", 3, {226, 150, 170}},
+#line 1600 "src/html/html_unescape.gperf"
+ {"rnmid", 3, {226, 171, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 911 "src/html/html_unescape.gperf"
+ {"leqq", 3, {226, 137, 166}},
+ {(char*)0}, {(char*)0},
+#line 749 "src/html/html_unescape.gperf"
+ {"intcal", 3, {226, 138, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 372 "src/html/html_unescape.gperf"
+ {"dharr", 3, {226, 135, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1555 "src/html/html_unescape.gperf"
+ {"rhard", 3, {226, 135, 129}},
+ {(char*)0},
+#line 939 "src/html/html_unescape.gperf"
+ {"lhard", 3, {226, 134, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1421 "src/html/html_unescape.gperf"
+ {"pluse", 3, {226, 169, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1933 "src/html/html_unescape.gperf"
+ {"Umacr", 2, {197, 170}},
+#line 2015 "src/html/html_unescape.gperf"
+ {"Vee", 3, {226, 139, 129}},
+ {(char*)0}, {(char*)0},
+#line 1503 "src/html/html_unescape.gperf"
+ {"Rarr", 3, {226, 134, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 304 "src/html/html_unescape.gperf"
+ {"Cross", 3, {226, 168, 175}},
+ {(char*)0},
+#line 1620 "src/html/html_unescape.gperf"
+ {"rsqb", 1, {93}},
+ {(char*)0},
+#line 1006 "src/html/html_unescape.gperf"
+ {"lsqb", 1, {91}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1510 "src/html/html_unescape.gperf"
+ {"Rarrtl", 3, {226, 164, 150}},
+ {(char*)0}, {(char*)0},
+#line 530 "src/html/html_unescape.gperf"
+ {"esdot", 3, {226, 137, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2014 "src/html/html_unescape.gperf"
+ {"vee", 3, {226, 136, 168}},
+#line 1089 "src/html/html_unescape.gperf"
+ {"nbumpe", 3, {226, 137, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 948 "src/html/html_unescape.gperf"
+ {"llcorner", 3, {226, 140, 158}},
+#line 570 "src/html/html_unescape.gperf"
+ {"fpartint", 3, {226, 168, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1740 "src/html/html_unescape.gperf"
+ {"squf", 3, {226, 150, 170}},
+#line 1414 "src/html/html_unescape.gperf"
+ {"plankv", 3, {226, 132, 143}},
+ {(char*)0}, {(char*)0},
+#line 525 "src/html/html_unescape.gperf"
+ {"eqvparsl", 3, {226, 167, 165}},
+ {(char*)0},
+#line 1930 "src/html/html_unescape.gperf"
+ {"ulcorner", 3, {226, 140, 156}},
+ {(char*)0},
+#line 2055 "src/html/html_unescape.gperf"
+ {"wp", 3, {226, 132, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 989 "src/html/html_unescape.gperf"
+ {"lozf", 3, {226, 167, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 299 "src/html/html_unescape.gperf"
+ {"COPY", 2, {194, 169}},
+ {(char*)0},
+#line 1929 "src/html/html_unescape.gperf"
+ {"ulcorn", 3, {226, 140, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2013 "src/html/html_unescape.gperf"
+ {"veebar", 3, {226, 138, 187}},
+ {(char*)0},
+#line 1392 "src/html/html_unescape.gperf"
+ {"part", 3, {226, 136, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1730 "src/html/html_unescape.gperf"
+ {"square", 3, {226, 150, 161}},
+ {(char*)0},
+#line 1088 "src/html/html_unescape.gperf"
+ {"nbump", 3, {226, 137, 142}},
+#line 108 "src/html/html_unescape.gperf"
+ {"bernou", 3, {226, 132, 172}},
+#line 2056 "src/html/html_unescape.gperf"
+ {"wr", 3, {226, 137, 128}},
+#line 1518 "src/html/html_unescape.gperf"
+ {"rBarr", 3, {226, 164, 143}},
+#line 993 "src/html/html_unescape.gperf"
+ {"lrcorner", 3, {226, 140, 159}},
+#line 849 "src/html/html_unescape.gperf"
+ {"lBarr", 3, {226, 164, 142}},
+ {(char*)0}, {(char*)0},
+#line 144 "src/html/html_unescape.gperf"
+ {"bnot", 3, {226, 140, 144}},
+ {(char*)0},
+#line 1662 "src/html/html_unescape.gperf"
+ {"semi", 1, {59}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1969 "src/html/html_unescape.gperf"
+ {"urcorner", 3, {226, 140, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1218 "src/html/html_unescape.gperf"
+ {"NotSubset", 3, {226, 138, 130}},
+ {(char*)0},
+#line 1605 "src/html/html_unescape.gperf"
+ {"ropf", 4, {240, 157, 149, 163}},
+#line 1476 "src/html/html_unescape.gperf"
+ {"Qopf", 3, {226, 132, 154}},
+#line 980 "src/html/html_unescape.gperf"
+ {"lopf", 4, {240, 157, 149, 157}},
+ {(char*)0},
+#line 1713 "src/html/html_unescape.gperf"
+ {"sopf", 4, {240, 157, 149, 164}},
+#line 1968 "src/html/html_unescape.gperf"
+ {"urcorn", 3, {226, 140, 157}},
+#line 1869 "src/html/html_unescape.gperf"
+ {"Topf", 4, {240, 157, 149, 139}},
+#line 2127 "src/html/html_unescape.gperf"
+ {"Zopf", 3, {226, 132, 164}},
+#line 505 "src/html/html_unescape.gperf"
+ {"eopf", 4, {240, 157, 149, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1604 "src/html/html_unescape.gperf"
+ {"ropar", 3, {226, 166, 134}},
+#line 1945 "src/html/html_unescape.gperf"
+ {"uopf", 4, {240, 157, 149, 166}},
+#line 978 "src/html/html_unescape.gperf"
+ {"lopar", 3, {226, 166, 133}},
+#line 1870 "src/html/html_unescape.gperf"
+ {"topf", 4, {240, 157, 149, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2075 "src/html/html_unescape.gperf"
+ {"Xopf", 4, {240, 157, 149, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1166 "src/html/html_unescape.gperf"
+ {"nopf", 4, {240, 157, 149, 159}},
+ {(char*)0},
+#line 146 "src/html/html_unescape.gperf"
+ {"bopf", 4, {240, 157, 149, 147}},
+#line 512 "src/html/html_unescape.gperf"
+ {"epsiv", 2, {207, 181}},
+#line 562 "src/html/html_unescape.gperf"
+ {"fnof", 2, {198, 146}},
+#line 734 "src/html/html_unescape.gperf"
+ {"imacr", 2, {196, 171}},
+ {(char*)0}, {(char*)0},
+#line 792 "src/html/html_unescape.gperf"
+ {"Jopf", 4, {240, 157, 149, 129}},
+ {(char*)0},
+#line 1135 "src/html/html_unescape.gperf"
+ {"nhpar", 3, {226, 171, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2053 "src/html/html_unescape.gperf"
+ {"Wopf", 4, {240, 157, 149, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1721 "src/html/html_unescape.gperf"
+ {"Sqrt", 3, {226, 136, 154}},
+#line 1263 "src/html/html_unescape.gperf"
+ {"nsub", 3, {226, 138, 132}},
+ {(char*)0},
+#line 1081 "src/html/html_unescape.gperf"
+ {"napid", 3, {226, 137, 139}},
+ {(char*)0}, {(char*)0},
+#line 1224 "src/html/html_unescape.gperf"
+ {"NotSuperset", 3, {226, 138, 131}},
+ {(char*)0}, {(char*)0},
+#line 197 "src/html/html_unescape.gperf"
+ {"brvbar", 2, {194, 166}},
+ {(char*)0}, {(char*)0},
+#line 1711 "src/html/html_unescape.gperf"
+ {"sol", 1, {47}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 461 "src/html/html_unescape.gperf"
+ {"easter", 3, {226, 169, 174}},
+ {(char*)0},
+#line 1429 "src/html/html_unescape.gperf"
+ {"popf", 4, {240, 157, 149, 161}},
+ {(char*)0}, {(char*)0},
+#line 370 "src/html/html_unescape.gperf"
+ {"dHar", 3, {226, 165, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2032 "src/html/html_unescape.gperf"
+ {"Vopf", 4, {240, 157, 149, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1274 "src/html/html_unescape.gperf"
+ {"nsupset", 3, {226, 138, 131}},
+#line 1271 "src/html/html_unescape.gperf"
+ {"nsup", 3, {226, 138, 133}},
+#line 2003 "src/html/html_unescape.gperf"
+ {"vBar", 3, {226, 171, 168}},
+ {(char*)0},
+#line 1266 "src/html/html_unescape.gperf"
+ {"nsubset", 3, {226, 138, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1851 "src/html/html_unescape.gperf"
+ {"thkap", 3, {226, 137, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1137 "src/html/html_unescape.gperf"
+ {"nis", 3, {226, 139, 188}},
+#line 1460 "src/html/html_unescape.gperf"
+ {"profsurf", 3, {226, 140, 147}},
+#line 1710 "src/html/html_unescape.gperf"
+ {"solb", 3, {226, 167, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 962 "src/html/html_unescape.gperf"
+ {"lnsim", 3, {226, 139, 166}},
+ {(char*)0},
+#line 1709 "src/html/html_unescape.gperf"
+ {"solbar", 3, {226, 140, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1731 "src/html/html_unescape.gperf"
+ {"Square", 3, {226, 150, 161}},
+ {(char*)0},
+#line 2033 "src/html/html_unescape.gperf"
+ {"vopf", 4, {240, 157, 149, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1926 "src/html/html_unescape.gperf"
+ {"uharl", 3, {226, 134, 191}},
+ {(char*)0},
+#line 1931 "src/html/html_unescape.gperf"
+ {"ulcrop", 3, {226, 140, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 515 "src/html/html_unescape.gperf"
+ {"eqsim", 3, {226, 137, 130}},
+#line 523 "src/html/html_unescape.gperf"
+ {"equiv", 3, {226, 137, 161}},
+ {(char*)0}, {(char*)0},
+#line 486 "src/html/html_unescape.gperf"
+ {"ell", 3, {226, 132, 147}},
+#line 1700 "src/html/html_unescape.gperf"
+ {"smashp", 3, {226, 168, 179}},
+#line 1067 "src/html/html_unescape.gperf"
+ {"mp", 3, {226, 136, 147}},
+ {(char*)0}, {(char*)0},
+#line 814 "src/html/html_unescape.gperf"
+ {"Kopf", 4, {240, 157, 149, 130}},
+ {(char*)0}, {(char*)0},
+#line 1696 "src/html/html_unescape.gperf"
+ {"simrarr", 3, {226, 165, 178}},
+ {(char*)0},
+#line 559 "src/html/html_unescape.gperf"
+ {"flat", 3, {226, 153, 173}},
+ {(char*)0},
+#line 1065 "src/html/html_unescape.gperf"
+ {"Mopf", 4, {240, 157, 149, 132}},
+#line 1712 "src/html/html_unescape.gperf"
+ {"Sopf", 4, {240, 157, 149, 138}},
+#line 1062 "src/html/html_unescape.gperf"
+ {"mldr", 3, {226, 128, 166}},
+#line 1597 "src/html/html_unescape.gperf"
+ {"rlm", 3, {226, 128, 143}},
+#line 768 "src/html/html_unescape.gperf"
+ {"iprod", 3, {226, 168, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 991 "src/html/html_unescape.gperf"
+ {"lparlt", 3, {226, 166, 147}},
+ {(char*)0},
+#line 564 "src/html/html_unescape.gperf"
+ {"fopf", 4, {240, 157, 149, 151}},
+#line 1944 "src/html/html_unescape.gperf"
+ {"Uopf", 4, {240, 157, 149, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1996 "src/html/html_unescape.gperf"
+ {"varsubsetneq", 3, {226, 138, 138}},
+#line 1997 "src/html/html_unescape.gperf"
+ {"varsubsetneqq", 3, {226, 171, 139}},
+ {(char*)0}, {(char*)0},
+#line 1970 "src/html/html_unescape.gperf"
+ {"urcrop", 3, {226, 140, 142}},
+#line 928 "src/html/html_unescape.gperf"
+ {"LessLess", 3, {226, 170, 161}},
+ {(char*)0},
+#line 1543 "src/html/html_unescape.gperf"
+ {"Re", 3, {226, 132, 156}},
+ {(char*)0}, {(char*)0},
+#line 1202 "src/html/html_unescape.gperf"
+ {"NotNestedLessLess", 3, {226, 170, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 396 "src/html/html_unescape.gperf"
+ {"Dopf", 4, {240, 157, 148, 187}},
+ {(char*)0},
+#line 568 "src/html/html_unescape.gperf"
+ {"forkv", 3, {226, 171, 153}},
+ {(char*)0},
+#line 1261 "src/html/html_unescape.gperf"
+ {"nsqsube", 3, {226, 139, 162}},
+ {(char*)0},
+#line 1273 "src/html/html_unescape.gperf"
+ {"nsupe", 3, {226, 138, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1265 "src/html/html_unescape.gperf"
+ {"nsube", 3, {226, 138, 136}},
+#line 1475 "src/html/html_unescape.gperf"
+ {"qopf", 4, {240, 157, 149, 162}},
+#line 1596 "src/html/html_unescape.gperf"
+ {"rlhar", 3, {226, 135, 140}},
+ {(char*)0}, {(char*)0},
+#line 996 "src/html/html_unescape.gperf"
+ {"lrm", 3, {226, 128, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1157 "src/html/html_unescape.gperf"
+ {"nlsim", 3, {226, 137, 180}},
+ {(char*)0},
+#line 1431 "src/html/html_unescape.gperf"
+ {"pound", 2, {194, 163}},
+#line 1998 "src/html/html_unescape.gperf"
+ {"varsupsetneq", 3, {226, 138, 139}},
+#line 1999 "src/html/html_unescape.gperf"
+ {"varsupsetneqq", 3, {226, 171, 140}},
+ {(char*)0},
+#line 142 "src/html/html_unescape.gperf"
+ {"bnequiv", 3, {226, 137, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 979 "src/html/html_unescape.gperf"
+ {"Lopf", 4, {240, 157, 149, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1262 "src/html/html_unescape.gperf"
+ {"nsqsupe", 3, {226, 139, 163}},
+ {(char*)0}, {(char*)0},
+#line 1507 "src/html/html_unescape.gperf"
+ {"rarrlp", 3, {226, 134, 172}},
+#line 2046 "src/html/html_unescape.gperf"
+ {"wedbar", 3, {226, 169, 159}},
+#line 839 "src/html/html_unescape.gperf"
+ {"larrlp", 3, {226, 134, 171}},
+ {(char*)0},
+#line 2101 "src/html/html_unescape.gperf"
+ {"Yopf", 4, {240, 157, 149, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1210 "src/html/html_unescape.gperf"
+ {"NotReverseElement", 3, {226, 136, 140}},
+ {(char*)0}, {(char*)0},
+#line 295 "src/html/html_unescape.gperf"
+ {"Copf", 3, {226, 132, 130}},
+#line 994 "src/html/html_unescape.gperf"
+ {"lrhar", 3, {226, 135, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1391 "src/html/html_unescape.gperf"
+ {"parsl", 3, {226, 171, 189}},
+#line 1935 "src/html/html_unescape.gperf"
+ {"uml", 2, {194, 168}},
+#line 1039 "src/html/html_unescape.gperf"
+ {"marker", 3, {226, 150, 174}},
+#line 1275 "src/html/html_unescape.gperf"
+ {"nsupseteq", 3, {226, 138, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1267 "src/html/html_unescape.gperf"
+ {"nsubseteq", 3, {226, 138, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1738 "src/html/html_unescape.gperf"
+ {"squarf", 3, {226, 150, 170}},
+#line 2021 "src/html/html_unescape.gperf"
+ {"Vert", 3, {226, 128, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1736 "src/html/html_unescape.gperf"
+ {"SquareSupersetEqual", 3, {226, 138, 146}},
+ {(char*)0},
+#line 1465 "src/html/html_unescape.gperf"
+ {"prsim", 3, {226, 137, 190}},
+ {(char*)0}, {(char*)0},
+#line 1734 "src/html/html_unescape.gperf"
+ {"SquareSubsetEqual", 3, {226, 138, 145}},
+ {(char*)0}, {(char*)0},
+#line 1735 "src/html/html_unescape.gperf"
+ {"SquareSuperset", 3, {226, 138, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1733 "src/html/html_unescape.gperf"
+ {"SquareSubset", 3, {226, 138, 143}},
+#line 1290 "src/html/html_unescape.gperf"
+ {"nvap", 3, {226, 137, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 765 "src/html/html_unescape.gperf"
+ {"iopf", 4, {240, 157, 149, 154}},
+ {(char*)0},
+#line 1426 "src/html/html_unescape.gperf"
+ {"pm", 2, {194, 177}},
+ {(char*)0},
+#line 2020 "src/html/html_unescape.gperf"
+ {"vert", 1, {124}},
+ {(char*)0},
+#line 1845 "src/html/html_unescape.gperf"
+ {"thetav", 2, {207, 145}},
+ {(char*)0}, {(char*)0},
+#line 987 "src/html/html_unescape.gperf"
+ {"loz", 3, {226, 151, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1034 "src/html/html_unescape.gperf"
+ {"map", 3, {226, 134, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 923 "src/html/html_unescape.gperf"
+ {"lesseqqgtr", 3, {226, 170, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1616 "src/html/html_unescape.gperf"
+ {"rscr", 4, {240, 157, 147, 135}},
+#line 1478 "src/html/html_unescape.gperf"
+ {"Qscr", 4, {240, 157, 146, 172}},
+#line 999 "src/html/html_unescape.gperf"
+ {"lscr", 4, {240, 157, 147, 129}},
+ {(char*)0},
+#line 1743 "src/html/html_unescape.gperf"
+ {"sscr", 4, {240, 157, 147, 136}},
+ {(char*)0},
+#line 1891 "src/html/html_unescape.gperf"
+ {"Tscr", 4, {240, 157, 146, 175}},
+#line 2128 "src/html/html_unescape.gperf"
+ {"Zscr", 4, {240, 157, 146, 181}},
+#line 528 "src/html/html_unescape.gperf"
+ {"escr", 3, {226, 132, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1975 "src/html/html_unescape.gperf"
+ {"uscr", 4, {240, 157, 147, 138}},
+ {(char*)0},
+#line 1892 "src/html/html_unescape.gperf"
+ {"tscr", 4, {240, 157, 147, 137}},
+ {(char*)0},
+#line 741 "src/html/html_unescape.gperf"
+ {"imof", 3, {226, 138, 183}},
+#line 297 "src/html/html_unescape.gperf"
+ {"Coproduct", 3, {226, 136, 144}},
+ {(char*)0}, {(char*)0},
+#line 2081 "src/html/html_unescape.gperf"
+ {"Xscr", 4, {240, 157, 146, 179}},
+#line 2068 "src/html/html_unescape.gperf"
+ {"Xi", 2, {206, 158}},
+ {(char*)0}, {(char*)0},
+#line 1253 "src/html/html_unescape.gperf"
+ {"nscr", 4, {240, 157, 147, 131}},
+#line 1136 "src/html/html_unescape.gperf"
+ {"ni", 3, {226, 136, 139}},
+#line 198 "src/html/html_unescape.gperf"
+ {"bscr", 4, {240, 157, 146, 183}},
+#line 1167 "src/html/html_unescape.gperf"
+ {"Nopf", 3, {226, 132, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 794 "src/html/html_unescape.gperf"
+ {"Jscr", 4, {240, 157, 146, 165}},
+#line 1443 "src/html/html_unescape.gperf"
+ {"preceq", 3, {226, 170, 175}},
+ {(char*)0}, {(char*)0},
+#line 1303 "src/html/html_unescape.gperf"
+ {"nvrArr", 3, {226, 164, 131}},
+#line 88 "src/html/html_unescape.gperf"
+ {"backprime", 3, {226, 128, 181}},
+#line 2058 "src/html/html_unescape.gperf"
+ {"Wscr", 4, {240, 157, 146, 178}},
+ {(char*)0},
+#line 1989 "src/html/html_unescape.gperf"
+ {"varphi", 2, {207, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1259 "src/html/html_unescape.gperf"
+ {"nsmid", 3, {226, 136, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 393 "src/html/html_unescape.gperf"
+ {"dlcorn", 3, {226, 140, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1468 "src/html/html_unescape.gperf"
+ {"pscr", 4, {240, 157, 147, 133}},
+#line 1409 "src/html/html_unescape.gperf"
+ {"pi", 2, {207, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2036 "src/html/html_unescape.gperf"
+ {"Vscr", 4, {240, 157, 146, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1113 "src/html/html_unescape.gperf"
+ {"nesim", 3, {226, 137, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1694 "src/html/html_unescape.gperf"
+ {"simne", 3, {226, 137, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1276 "src/html/html_unescape.gperf"
+ {"nsupseteqq", 3, {226, 171, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1268 "src/html/html_unescape.gperf"
+ {"nsubseteqq", 3, {226, 171, 133}},
+#line 441 "src/html/html_unescape.gperf"
+ {"drcorn", 3, {226, 140, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1521 "src/html/html_unescape.gperf"
+ {"rbrace", 1, {125}},
+#line 2037 "src/html/html_unescape.gperf"
+ {"vscr", 4, {240, 157, 147, 139}},
+#line 851 "src/html/html_unescape.gperf"
+ {"lbrace", 1, {123}},
+#line 397 "src/html/html_unescape.gperf"
+ {"dopf", 4, {240, 157, 149, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 586 "src/html/html_unescape.gperf"
+ {"frasl", 3, {226, 129, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 931 "src/html/html_unescape.gperf"
+ {"LessTilde", 3, {226, 137, 178}},
+ {(char*)0}, {(char*)0},
+#line 816 "src/html/html_unescape.gperf"
+ {"Kscr", 4, {240, 157, 146, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1417 "src/html/html_unescape.gperf"
+ {"pluscir", 3, {226, 168, 162}},
+#line 1069 "src/html/html_unescape.gperf"
+ {"Mscr", 3, {226, 132, 179}},
+#line 1742 "src/html/html_unescape.gperf"
+ {"Sscr", 4, {240, 157, 146, 174}},
+#line 1524 "src/html/html_unescape.gperf"
+ {"rbrksld", 3, {226, 166, 142}},
+ {(char*)0},
+#line 854 "src/html/html_unescape.gperf"
+ {"lbrksld", 3, {226, 166, 143}},
+#line 1519 "src/html/html_unescape.gperf"
+ {"RBarr", 3, {226, 164, 144}},
+ {(char*)0}, {(char*)0},
+#line 1718 "src/html/html_unescape.gperf"
+ {"sqcaps", 3, {226, 138, 147}},
+#line 1504 "src/html/html_unescape.gperf"
+ {"rArr", 3, {226, 135, 146}},
+#line 143 "src/html/html_unescape.gperf"
+ {"bNot", 3, {226, 171, 173}},
+#line 836 "src/html/html_unescape.gperf"
+ {"lArr", 3, {226, 135, 144}},
+ {(char*)0},
+#line 588 "src/html/html_unescape.gperf"
+ {"fscr", 4, {240, 157, 146, 187}},
+#line 1974 "src/html/html_unescape.gperf"
+ {"Uscr", 4, {240, 157, 146, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1906 "src/html/html_unescape.gperf"
+ {"uArr", 3, {226, 135, 145}},
+ {(char*)0}, {(char*)0},
+#line 1606 "src/html/html_unescape.gperf"
+ {"Ropf", 3, {226, 132, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2054 "src/html/html_unescape.gperf"
+ {"wopf", 4, {240, 157, 149, 168}},
+ {(char*)0}, {(char*)0},
+#line 443 "src/html/html_unescape.gperf"
+ {"Dscr", 4, {240, 157, 146, 159}},
+#line 1352 "src/html/html_unescape.gperf"
+ {"opar", 3, {226, 166, 183}},
+#line 1663 "src/html/html_unescape.gperf"
+ {"seswar", 3, {226, 164, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 363 "src/html/html_unescape.gperf"
+ {"Del", 3, {226, 136, 135}},
+#line 1486 "src/html/html_unescape.gperf"
+ {"rAarr", 3, {226, 135, 155}},
+#line 1559 "src/html/html_unescape.gperf"
+ {"rho", 2, {207, 129}},
+#line 818 "src/html/html_unescape.gperf"
+ {"lAarr", 3, {226, 135, 154}},
+#line 1438 "src/html/html_unescape.gperf"
+ {"preccurlyeq", 3, {226, 137, 188}},
+#line 1479 "src/html/html_unescape.gperf"
+ {"qscr", 4, {240, 157, 147, 134}},
+ {(char*)0}, {(char*)0},
+#line 1029 "src/html/html_unescape.gperf"
+ {"macr", 2, {194, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1186 "src/html/html_unescape.gperf"
+ {"notin", 3, {226, 136, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 524 "src/html/html_unescape.gperf"
+ {"equivDD", 3, {226, 169, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1717 "src/html/html_unescape.gperf"
+ {"sqcap", 3, {226, 138, 147}},
+ {(char*)0},
+#line 1260 "src/html/html_unescape.gperf"
+ {"nspar", 3, {226, 136, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1341 "src/html/html_unescape.gperf"
+ {"olt", 3, {226, 167, 128}},
+#line 1515 "src/html/html_unescape.gperf"
+ {"ratio", 3, {226, 136, 182}},
+#line 1000 "src/html/html_unescape.gperf"
+ {"Lscr", 3, {226, 132, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 371 "src/html/html_unescape.gperf"
+ {"dharl", 3, {226, 135, 131}},
+ {(char*)0},
+#line 394 "src/html/html_unescape.gperf"
+ {"dlcrop", 3, {226, 140, 141}},
+#line 409 "src/html/html_unescape.gperf"
+ {"DoubleDot", 2, {194, 168}},
+#line 405 "src/html/html_unescape.gperf"
+ {"dotplus", 3, {226, 136, 148}},
+#line 1359 "src/html/html_unescape.gperf"
+ {"or", 3, {226, 136, 168}},
+ {(char*)0},
+#line 2103 "src/html/html_unescape.gperf"
+ {"Yscr", 4, {240, 157, 146, 180}},
+ {(char*)0}, {(char*)0},
+#line 563 "src/html/html_unescape.gperf"
+ {"Fopf", 4, {240, 157, 148, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 305 "src/html/html_unescape.gperf"
+ {"Cscr", 4, {240, 157, 146, 158}},
+#line 1337 "src/html/html_unescape.gperf"
+ {"olarr", 3, {226, 134, 186}},
+#line 1244 "src/html/html_unescape.gperf"
+ {"nrarrw", 3, {226, 134, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1027 "src/html/html_unescape.gperf"
+ {"lvertneqq", 3, {226, 137, 168}},
+#line 516 "src/html/html_unescape.gperf"
+ {"eqslantgtr", 3, {226, 170, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1854 "src/html/html_unescape.gperf"
+ {"thorn", 2, {195, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 517 "src/html/html_unescape.gperf"
+ {"eqslantless", 3, {226, 170, 149}},
+ {(char*)0}, {(char*)0},
+#line 744 "src/html/html_unescape.gperf"
+ {"incare", 3, {226, 132, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1993 "src/html/html_unescape.gperf"
+ {"vArr", 3, {226, 135, 149}},
+#line 1612 "src/html/html_unescape.gperf"
+ {"rppolint", 3, {226, 168, 146}},
+#line 442 "src/html/html_unescape.gperf"
+ {"drcrop", 3, {226, 140, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1388 "src/html/html_unescape.gperf"
+ {"parallel", 3, {226, 136, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1357 "src/html/html_unescape.gperf"
+ {"orarr", 3, {226, 134, 187}},
+#line 1745 "src/html/html_unescape.gperf"
+ {"ssmile", 3, {226, 140, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 413 "src/html/html_unescape.gperf"
+ {"DoubleLeftTee", 3, {226, 171, 164}},
+#line 527 "src/html/html_unescape.gperf"
+ {"erDot", 3, {226, 137, 147}},
+#line 382 "src/html/html_unescape.gperf"
+ {"diams", 3, {226, 153, 166}},
+#line 1744 "src/html/html_unescape.gperf"
+ {"ssetmn", 3, {226, 136, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1369 "src/html/html_unescape.gperf"
+ {"oS", 3, {226, 147, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 770 "src/html/html_unescape.gperf"
+ {"iscr", 4, {240, 157, 146, 190}},
+#line 726 "src/html/html_unescape.gperf"
+ {"ii", 3, {226, 133, 136}},
+#line 1544 "src/html/html_unescape.gperf"
+ {"rect", 3, {226, 150, 173}},
+ {(char*)0}, {(char*)0},
+#line 1250 "src/html/html_unescape.gperf"
+ {"nsccue", 3, {226, 139, 161}},
+#line 1661 "src/html/html_unescape.gperf"
+ {"sect", 2, {194, 167}},
+ {(char*)0},
+#line 1061 "src/html/html_unescape.gperf"
+ {"mlcp", 3, {226, 171, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1366 "src/html/html_unescape.gperf"
+ {"oror", 3, {226, 169, 150}},
+ {(char*)0},
+#line 408 "src/html/html_unescape.gperf"
+ {"DoubleContourIntegral", 3, {226, 136, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 519 "src/html/html_unescape.gperf"
+ {"equals", 1, {61}},
+ {(char*)0},
+#line 680 "src/html/html_unescape.gperf"
+ {"Hat", 1, {94}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1746 "src/html/html_unescape.gperf"
+ {"sstarf", 3, {226, 139, 134}},
+#line 1070 "src/html/html_unescape.gperf"
+ {"mstpos", 3, {226, 136, 190}},
+ {(char*)0},
+#line 383 "src/html/html_unescape.gperf"
+ {"die", 2, {194, 168}},
+#line 1045 "src/html/html_unescape.gperf"
+ {"measuredangle", 3, {226, 136, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 565 "src/html/html_unescape.gperf"
+ {"forall", 3, {226, 136, 128}},
+ {(char*)0}, {(char*)0},
+#line 1190 "src/html/html_unescape.gperf"
+ {"notinvb", 3, {226, 139, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1066 "src/html/html_unescape.gperf"
+ {"mopf", 4, {240, 157, 149, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1139 "src/html/html_unescape.gperf"
+ {"niv", 3, {226, 136, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2005 "src/html/html_unescape.gperf"
+ {"vBarv", 3, {226, 171, 169}},
+ {(char*)0},
+#line 1252 "src/html/html_unescape.gperf"
+ {"Nscr", 4, {240, 157, 146, 169}},
+ {(char*)0},
+#line 1397 "src/html/html_unescape.gperf"
+ {"period", 1, {46}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 103 "src/html/html_unescape.gperf"
+ {"becaus", 3, {226, 136, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 113 "src/html/html_unescape.gperf"
+ {"between", 3, {226, 137, 172}},
+#line 751 "src/html/html_unescape.gperf"
+ {"Int", 3, {226, 136, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 104 "src/html/html_unescape.gperf"
+ {"because", 3, {226, 136, 181}},
+#line 1411 "src/html/html_unescape.gperf"
+ {"piv", 2, {207, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1552 "src/html/html_unescape.gperf"
+ {"rfr", 4, {240, 157, 148, 175}},
+#line 1472 "src/html/html_unescape.gperf"
+ {"Qfr", 4, {240, 157, 148, 148}},
+#line 935 "src/html/html_unescape.gperf"
+ {"lfr", 4, {240, 157, 148, 169}},
+ {(char*)0},
+#line 1668 "src/html/html_unescape.gperf"
+ {"sfr", 4, {240, 157, 148, 176}},
+#line 1149 "src/html/html_unescape.gperf"
+ {"nleftrightarrow", 3, {226, 134, 174}},
+#line 1837 "src/html/html_unescape.gperf"
+ {"Tfr", 4, {240, 157, 148, 151}},
+#line 2122 "src/html/html_unescape.gperf"
+ {"Zfr", 3, {226, 132, 168}},
+#line 477 "src/html/html_unescape.gperf"
+ {"efr", 4, {240, 157, 148, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1686 "src/html/html_unescape.gperf"
+ {"sim", 3, {226, 136, 188}},
+#line 1922 "src/html/html_unescape.gperf"
+ {"ufr", 4, {240, 157, 148, 178}},
+#line 1607 "src/html/html_unescape.gperf"
+ {"roplus", 3, {226, 168, 174}},
+#line 1838 "src/html/html_unescape.gperf"
+ {"tfr", 4, {240, 157, 148, 177}},
+#line 981 "src/html/html_unescape.gperf"
+ {"loplus", 3, {226, 168, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2064 "src/html/html_unescape.gperf"
+ {"Xfr", 4, {240, 157, 148, 155}},
+ {(char*)0}, {(char*)0},
+#line 1539 "src/html/html_unescape.gperf"
+ {"real", 3, {226, 132, 156}},
+#line 1120 "src/html/html_unescape.gperf"
+ {"nfr", 4, {240, 157, 148, 171}},
+ {(char*)0},
+#line 115 "src/html/html_unescape.gperf"
+ {"bfr", 4, {240, 157, 148, 159}},
+ {(char*)0},
+#line 1185 "src/html/html_unescape.gperf"
+ {"NotHumpEqual", 3, {226, 137, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 789 "src/html/html_unescape.gperf"
+ {"Jfr", 4, {240, 157, 148, 141}},
+ {(char*)0},
+#line 444 "src/html/html_unescape.gperf"
+ {"dscr", 4, {240, 157, 146, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2051 "src/html/html_unescape.gperf"
+ {"Wfr", 4, {240, 157, 148, 154}},
+ {(char*)0},
+#line 130 "src/html/html_unescape.gperf"
+ {"blacklozenge", 3, {226, 167, 171}},
+ {(char*)0},
+#line 2126 "src/html/html_unescape.gperf"
+ {"zopf", 4, {240, 157, 149, 171}},
+#line 1542 "src/html/html_unescape.gperf"
+ {"reals", 3, {226, 132, 157}},
+ {(char*)0},
+#line 1171 "src/html/html_unescape.gperf"
+ {"NotCupCap", 3, {226, 137, 173}},
+ {(char*)0}, {(char*)0},
+#line 1695 "src/html/html_unescape.gperf"
+ {"simplus", 3, {226, 168, 164}},
+ {(char*)0},
+#line 566 "src/html/html_unescape.gperf"
+ {"ForAll", 3, {226, 136, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1402 "src/html/html_unescape.gperf"
+ {"pfr", 4, {240, 157, 148, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1343 "src/html/html_unescape.gperf"
+ {"omacr", 2, {197, 141}},
+ {(char*)0},
+#line 2027 "src/html/html_unescape.gperf"
+ {"Vfr", 4, {240, 157, 148, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 489 "src/html/html_unescape.gperf"
+ {"Emacr", 2, {196, 146}},
+#line 1617 "src/html/html_unescape.gperf"
+ {"Rscr", 3, {226, 132, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2059 "src/html/html_unescape.gperf"
+ {"wscr", 4, {240, 157, 147, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1680 "src/html/html_unescape.gperf"
+ {"ShortUpArrow", 3, {226, 134, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1665 "src/html/html_unescape.gperf"
+ {"setmn", 3, {226, 136, 150}},
+ {(char*)0},
+#line 2028 "src/html/html_unescape.gperf"
+ {"vfr", 4, {240, 157, 148, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 807 "src/html/html_unescape.gperf"
+ {"Kfr", 4, {240, 157, 148, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1355 "src/html/html_unescape.gperf"
+ {"operp", 3, {226, 166, 185}},
+ {(char*)0},
+#line 1048 "src/html/html_unescape.gperf"
+ {"Mfr", 4, {240, 157, 148, 144}},
+#line 1667 "src/html/html_unescape.gperf"
+ {"Sfr", 4, {240, 157, 148, 150}},
+ {(char*)0}, {(char*)0},
+#line 1161 "src/html/html_unescape.gperf"
+ {"nltrie", 3, {226, 139, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 589 "src/html/html_unescape.gperf"
+ {"Fscr", 3, {226, 132, 177}},
+ {(char*)0}, {(char*)0},
+#line 554 "src/html/html_unescape.gperf"
+ {"ffr", 4, {240, 157, 148, 163}},
+#line 1921 "src/html/html_unescape.gperf"
+ {"Ufr", 4, {240, 157, 148, 152}},
+ {(char*)0},
+#line 1677 "src/html/html_unescape.gperf"
+ {"shortmid", 3, {226, 136, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1305 "src/html/html_unescape.gperf"
+ {"nvsim", 3, {226, 136, 188}},
+#line 368 "src/html/html_unescape.gperf"
+ {"Dfr", 4, {240, 157, 148, 135}},
+#line 921 "src/html/html_unescape.gperf"
+ {"lessdot", 3, {226, 139, 150}},
+ {(char*)0}, {(char*)0},
+#line 1459 "src/html/html_unescape.gperf"
+ {"profline", 3, {226, 140, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1473 "src/html/html_unescape.gperf"
+ {"qfr", 4, {240, 157, 148, 174}},
+#line 346 "src/html/html_unescape.gperf"
+ {"dArr", 3, {226, 135, 147}},
+ {(char*)0},
+#line 1248 "src/html/html_unescape.gperf"
+ {"nrtrie", 3, {226, 139, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1679 "src/html/html_unescape.gperf"
+ {"ShortRightArrow", 3, {226, 134, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1841 "src/html/html_unescape.gperf"
+ {"Therefore", 3, {226, 136, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 358 "src/html/html_unescape.gperf"
+ {"DD", 3, {226, 133, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1840 "src/html/html_unescape.gperf"
+ {"therefore", 3, {226, 136, 180}},
+#line 934 "src/html/html_unescape.gperf"
+ {"Lfr", 4, {240, 157, 148, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1825 "src/html/html_unescape.gperf"
+ {"target", 3, {226, 140, 150}},
+ {(char*)0}, {(char*)0},
+#line 484 "src/html/html_unescape.gperf"
+ {"Element", 3, {226, 136, 136}},
+#line 2097 "src/html/html_unescape.gperf"
+ {"Yfr", 4, {240, 157, 148, 156}},
+#line 272 "src/html/html_unescape.gperf"
+ {"ClockwiseContourIntegral", 3, {226, 136, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1338 "src/html/html_unescape.gperf"
+ {"olcir", 3, {226, 166, 190}},
+ {(char*)0},
+#line 246 "src/html/html_unescape.gperf"
+ {"Cfr", 3, {226, 132, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 549 "src/html/html_unescape.gperf"
+ {"female", 3, {226, 153, 128}},
+#line 1270 "src/html/html_unescape.gperf"
+ {"nsucceq", 3, {226, 170, 176}},
+#line 1313 "src/html/html_unescape.gperf"
+ {"oast", 3, {226, 138, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1396 "src/html/html_unescape.gperf"
+ {"percnt", 1, {37}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1363 "src/html/html_unescape.gperf"
+ {"ordf", 2, {194, 170}},
+ {(char*)0},
+#line 1360 "src/html/html_unescape.gperf"
+ {"ord", 3, {226, 169, 157}},
+#line 1558 "src/html/html_unescape.gperf"
+ {"Rho", 2, {206, 161}},
+ {(char*)0},
+#line 1068 "src/html/html_unescape.gperf"
+ {"mscr", 4, {240, 157, 147, 130}},
+ {(char*)0},
+#line 1304 "src/html/html_unescape.gperf"
+ {"nvrtrie", 3, {226, 138, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 959 "src/html/html_unescape.gperf"
+ {"lnE", 3, {226, 137, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1134 "src/html/html_unescape.gperf"
+ {"nhArr", 3, {226, 135, 142}},
+#line 1358 "src/html/html_unescape.gperf"
+ {"Or", 3, {226, 169, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 388 "src/html/html_unescape.gperf"
+ {"divide", 2, {195, 183}},
+ {(char*)0},
+#line 722 "src/html/html_unescape.gperf"
+ {"ifr", 4, {240, 157, 148, 166}},
+#line 485 "src/html/html_unescape.gperf"
+ {"elinters", 3, {226, 143, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 204 "src/html/html_unescape.gperf"
+ {"bsol", 1, {92}},
+#line 1299 "src/html/html_unescape.gperf"
+ {"nvlArr", 3, {226, 164, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 733 "src/html/html_unescape.gperf"
+ {"Imacr", 2, {196, 170}},
+ {(char*)0},
+#line 90 "src/html/html_unescape.gperf"
+ {"backsimeq", 3, {226, 139, 141}},
+#line 1899 "src/html/html_unescape.gperf"
+ {"twixt", 3, {226, 137, 172}},
+#line 1339 "src/html/html_unescape.gperf"
+ {"olcross", 3, {226, 166, 187}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1509 "src/html/html_unescape.gperf"
+ {"rarrsim", 3, {226, 165, 180}},
+#line 410 "src/html/html_unescape.gperf"
+ {"DoubleDownArrow", 3, {226, 135, 147}},
+#line 841 "src/html/html_unescape.gperf"
+ {"larrsim", 3, {226, 165, 179}},
+#line 492 "src/html/html_unescape.gperf"
+ {"emptyset", 3, {226, 136, 133}},
+#line 1351 "src/html/html_unescape.gperf"
+ {"oopf", 4, {240, 157, 149, 160}},
+ {(char*)0},
+#line 541 "src/html/html_unescape.gperf"
+ {"exist", 3, {226, 136, 131}},
+ {(char*)0}, {(char*)0},
+#line 950 "src/html/html_unescape.gperf"
+ {"llhard", 3, {226, 165, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 540 "src/html/html_unescape.gperf"
+ {"excl", 1, {33}},
+#line 504 "src/html/html_unescape.gperf"
+ {"Eopf", 4, {240, 157, 148, 188}},
+#line 1143 "src/html/html_unescape.gperf"
+ {"nlArr", 3, {226, 135, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1850 "src/html/html_unescape.gperf"
+ {"thinsp", 3, {226, 128, 137}},
+#line 1219 "src/html/html_unescape.gperf"
+ {"NotSubsetEqual", 3, {226, 138, 136}},
+#line 1404 "src/html/html_unescape.gperf"
+ {"phi", 2, {207, 134}},
+#line 411 "src/html/html_unescape.gperf"
+ {"DoubleLeftArrow", 3, {226, 135, 144}},
+ {(char*)0},
+#line 1867 "src/html/html_unescape.gperf"
+ {"topcir", 3, {226, 171, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 387 "src/html/html_unescape.gperf"
+ {"div", 2, {195, 183}},
+ {(char*)0},
+#line 1119 "src/html/html_unescape.gperf"
+ {"Nfr", 4, {240, 157, 148, 145}},
+#line 1145 "src/html/html_unescape.gperf"
+ {"nlE", 3, {226, 137, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2129 "src/html/html_unescape.gperf"
+ {"zscr", 4, {240, 157, 147, 143}},
+#line 995 "src/html/html_unescape.gperf"
+ {"lrhard", 3, {226, 165, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 951 "src/html/html_unescape.gperf"
+ {"lltri", 3, {226, 151, 186}},
+ {(char*)0}, {(char*)0},
+#line 1243 "src/html/html_unescape.gperf"
+ {"nrArr", 3, {226, 135, 143}},
+#line 1225 "src/html/html_unescape.gperf"
+ {"NotSupersetEqual", 3, {226, 138, 137}},
+ {(char*)0},
+#line 1820 "src/html/html_unescape.gperf"
+ {"swArr", 3, {226, 135, 153}},
+#line 1848 "src/html/html_unescape.gperf"
+ {"ThickSpace", 3, {226, 129, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1932 "src/html/html_unescape.gperf"
+ {"ultri", 3, {226, 151, 184}},
+#line 1205 "src/html/html_unescape.gperf"
+ {"notnivb", 3, {226, 139, 190}},
+ {(char*)0},
+#line 1450 "src/html/html_unescape.gperf"
+ {"prime", 3, {226, 128, 178}},
+ {(char*)0}, {(char*)0},
+#line 1452 "src/html/html_unescape.gperf"
+ {"primes", 3, {226, 132, 153}},
+ {(char*)0},
+#line 1335 "src/html/html_unescape.gperf"
+ {"ohm", 2, {206, 169}},
+ {(char*)0}, {(char*)0},
+#line 265 "src/html/html_unescape.gperf"
+ {"CircleTimes", 3, {226, 138, 151}},
+#line 1160 "src/html/html_unescape.gperf"
+ {"nltri", 3, {226, 139, 170}},
+ {(char*)0}, {(char*)0},
+#line 1692 "src/html/html_unescape.gperf"
+ {"siml", 3, {226, 170, 157}},
+#line 1308 "src/html/html_unescape.gperf"
+ {"nwArr", 3, {226, 135, 150}},
+ {(char*)0}, {(char*)0},
+#line 1990 "src/html/html_unescape.gperf"
+ {"varpi", 2, {207, 150}},
+ {(char*)0}, {(char*)0},
+#line 1368 "src/html/html_unescape.gperf"
+ {"orv", 3, {226, 169, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1664 "src/html/html_unescape.gperf"
+ {"setminus", 3, {226, 136, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 997 "src/html/html_unescape.gperf"
+ {"lrtri", 3, {226, 138, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1398 "src/html/html_unescape.gperf"
+ {"permil", 3, {226, 128, 176}},
+#line 1054 "src/html/html_unescape.gperf"
+ {"mid", 3, {226, 136, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1973 "src/html/html_unescape.gperf"
+ {"urtri", 3, {226, 151, 185}},
+ {(char*)0}, {(char*)0},
+#line 369 "src/html/html_unescape.gperf"
+ {"dfr", 4, {240, 157, 148, 161}},
+#line 1050 "src/html/html_unescape.gperf"
+ {"mho", 3, {226, 132, 167}},
+#line 1448 "src/html/html_unescape.gperf"
+ {"prE", 3, {226, 170, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2041 "src/html/html_unescape.gperf"
+ {"vsupne", 3, {226, 138, 139}},
+ {(char*)0}, {(char*)0},
+#line 1247 "src/html/html_unescape.gperf"
+ {"nrtri", 3, {226, 139, 171}},
+#line 2039 "src/html/html_unescape.gperf"
+ {"vsubne", 3, {226, 138, 138}},
+ {(char*)0},
+#line 473 "src/html/html_unescape.gperf"
+ {"eDot", 3, {226, 137, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 919 "src/html/html_unescape.gperf"
+ {"lesges", 3, {226, 170, 147}},
+ {(char*)0}, {(char*)0},
+#line 87 "src/html/html_unescape.gperf"
+ {"backepsilon", 2, {207, 182}},
+ {(char*)0},
+#line 1513 "src/html/html_unescape.gperf"
+ {"ratail", 3, {226, 164, 154}},
+ {(char*)0},
+#line 843 "src/html/html_unescape.gperf"
+ {"latail", 3, {226, 164, 153}},
+ {(char*)0}, {(char*)0},
+#line 1954 "src/html/html_unescape.gperf"
+ {"UpEquilibrium", 3, {226, 165, 174}},
+ {(char*)0}, {(char*)0},
+#line 511 "src/html/html_unescape.gperf"
+ {"epsilon", 2, {206, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1964 "src/html/html_unescape.gperf"
+ {"upsilon", 2, {207, 133}},
+ {(char*)0},
+#line 1052 "src/html/html_unescape.gperf"
+ {"midast", 1, {42}},
+#line 698 "src/html/html_unescape.gperf"
+ {"Hopf", 3, {226, 132, 141}},
+#line 2029 "src/html/html_unescape.gperf"
+ {"vltri", 3, {226, 138, 178}},
+ {(char*)0},
+#line 1553 "src/html/html_unescape.gperf"
+ {"Rfr", 3, {226, 132, 156}},
+ {(char*)0}, {(char*)0},
+#line 2048 "src/html/html_unescape.gperf"
+ {"Wedge", 3, {226, 139, 128}},
+#line 2052 "src/html/html_unescape.gperf"
+ {"wfr", 4, {240, 157, 148, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 94 "src/html/html_unescape.gperf"
+ {"barwed", 3, {226, 140, 133}},
+ {(char*)0}, {(char*)0},
+#line 1031 "src/html/html_unescape.gperf"
+ {"malt", 3, {226, 156, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 251 "src/html/html_unescape.gperf"
+ {"Chi", 2, {206, 167}},
+#line 494 "src/html/html_unescape.gperf"
+ {"emptyv", 3, {226, 136, 133}},
+#line 1203 "src/html/html_unescape.gperf"
+ {"notni", 3, {226, 136, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 926 "src/html/html_unescape.gperf"
+ {"LessGreater", 3, {226, 137, 182}},
+ {(char*)0},
+#line 378 "src/html/html_unescape.gperf"
+ {"diam", 3, {226, 139, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2035 "src/html/html_unescape.gperf"
+ {"vrtri", 3, {226, 138, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 263 "src/html/html_unescape.gperf"
+ {"CircleMinus", 3, {226, 138, 150}},
+ {(char*)0},
+#line 1342 "src/html/html_unescape.gperf"
+ {"Omacr", 2, {197, 140}},
+#line 1659 "src/html/html_unescape.gperf"
+ {"seArr", 3, {226, 135, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 553 "src/html/html_unescape.gperf"
+ {"Ffr", 4, {240, 157, 148, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1445 "src/html/html_unescape.gperf"
+ {"precneqq", 3, {226, 170, 181}},
+ {(char*)0},
+#line 380 "src/html/html_unescape.gperf"
+ {"Diamond", 3, {226, 139, 132}},
+#line 1364 "src/html/html_unescape.gperf"
+ {"ordm", 2, {194, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1103 "src/html/html_unescape.gperf"
+ {"neArr", 3, {226, 135, 151}},
+#line 764 "src/html/html_unescape.gperf"
+ {"Iopf", 4, {240, 157, 149, 128}},
+#line 260 "src/html/html_unescape.gperf"
+ {"CircleDot", 3, {226, 138, 153}},
+ {(char*)0}, {(char*)0},
+#line 1453 "src/html/html_unescape.gperf"
+ {"prnap", 3, {226, 170, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 404 "src/html/html_unescape.gperf"
+ {"dotminus", 3, {226, 136, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1254 "src/html/html_unescape.gperf"
+ {"nshortmid", 3, {226, 136, 164}},
+ {(char*)0},
+#line 148 "src/html/html_unescape.gperf"
+ {"bottom", 3, {226, 138, 165}},
+ {(char*)0},
+#line 1428 "src/html/html_unescape.gperf"
+ {"pointint", 3, {226, 168, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1737 "src/html/html_unescape.gperf"
+ {"SquareUnion", 3, {226, 138, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 793 "src/html/html_unescape.gperf"
+ {"jopf", 4, {240, 157, 149, 155}},
+ {(char*)0}, {(char*)0},
+#line 1963 "src/html/html_unescape.gperf"
+ {"Upsilon", 2, {206, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 279 "src/html/html_unescape.gperf"
+ {"Colone", 3, {226, 169, 180}},
+ {(char*)0},
+#line 1301 "src/html/html_unescape.gperf"
+ {"nvlt", 1, {60}},
+ {(char*)0}, {(char*)0},
+#line 1115 "src/html/html_unescape.gperf"
+ {"NestedLessLess", 3, {226, 137, 170}},
+#line 278 "src/html/html_unescape.gperf"
+ {"Colon", 3, {226, 136, 183}},
+ {(char*)0}, {(char*)0},
+#line 205 "src/html/html_unescape.gperf"
+ {"bsolhsub", 3, {226, 159, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 412 "src/html/html_unescape.gperf"
+ {"DoubleLeftRightArrow", 3, {226, 135, 148}},
+#line 1424 "src/html/html_unescape.gperf"
+ {"plussim", 3, {226, 168, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 735 "src/html/html_unescape.gperf"
+ {"image", 3, {226, 132, 145}},
+#line 481 "src/html/html_unescape.gperf"
+ {"egs", 3, {226, 170, 150}},
+ {(char*)0}, {(char*)0},
+#line 1371 "src/html/html_unescape.gperf"
+ {"oscr", 3, {226, 132, 180}},
+#line 1822 "src/html/html_unescape.gperf"
+ {"swnwar", 3, {226, 164, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2117 "src/html/html_unescape.gperf"
+ {"zeetrf", 3, {226, 132, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1032 "src/html/html_unescape.gperf"
+ {"maltese", 3, {226, 156, 160}},
+ {(char*)0},
+#line 1049 "src/html/html_unescape.gperf"
+ {"mfr", 4, {240, 157, 148, 170}},
+#line 1505 "src/html/html_unescape.gperf"
+ {"rarrfs", 3, {226, 164, 158}},
+#line 529 "src/html/html_unescape.gperf"
+ {"Escr", 3, {226, 132, 176}},
+#line 837 "src/html/html_unescape.gperf"
+ {"larrfs", 3, {226, 164, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1063 "src/html/html_unescape.gperf"
+ {"mnplus", 3, {226, 136, 147}},
+#line 1130 "src/html/html_unescape.gperf"
+ {"ngt", 3, {226, 137, 175}},
+#line 1131 "src/html/html_unescape.gperf"
+ {"ngtr", 3, {226, 137, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 628 "src/html/html_unescape.gperf"
+ {"gl", 3, {226, 137, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 381 "src/html/html_unescape.gperf"
+ {"diamondsuit", 3, {226, 153, 166}},
+#line 656 "src/html/html_unescape.gperf"
+ {"GT", 1, {62}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 929 "src/html/html_unescape.gperf"
+ {"lesssim", 3, {226, 137, 178}},
+#line 447 "src/html/html_unescape.gperf"
+ {"dsol", 3, {226, 167, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1955 "src/html/html_unescape.gperf"
+ {"upharpoonleft", 3, {226, 134, 191}},
+#line 1732 "src/html/html_unescape.gperf"
+ {"SquareIntersection", 3, {226, 138, 147}},
+#line 1004 "src/html/html_unescape.gperf"
+ {"lsime", 3, {226, 170, 141}},
+ {(char*)0},
+#line 1158 "src/html/html_unescape.gperf"
+ {"nLt", 3, {226, 137, 170}},
+ {(char*)0},
+#line 1195 "src/html/html_unescape.gperf"
+ {"NotLess", 3, {226, 137, 174}},
+ {(char*)0},
+#line 631 "src/html/html_unescape.gperf"
+ {"gnap", 3, {226, 170, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1635 "src/html/html_unescape.gperf"
+ {"scap", 3, {226, 170, 184}},
+ {(char*)0}, {(char*)0},
+#line 1037 "src/html/html_unescape.gperf"
+ {"mapstoleft", 3, {226, 134, 164}},
+#line 1198 "src/html/html_unescape.gperf"
+ {"NotLessLess", 3, {226, 137, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1551 "src/html/html_unescape.gperf"
+ {"rfloor", 3, {226, 140, 139}},
+ {(char*)0},
+#line 933 "src/html/html_unescape.gperf"
+ {"lfloor", 3, {226, 140, 138}},
+ {(char*)0}, {(char*)0},
+#line 1257 "src/html/html_unescape.gperf"
+ {"nsime", 3, {226, 137, 132}},
+ {(char*)0},
+#line 202 "src/html/html_unescape.gperf"
+ {"bsime", 3, {226, 139, 141}},
+#line 1196 "src/html/html_unescape.gperf"
+ {"NotLessEqual", 3, {226, 137, 176}},
+#line 1200 "src/html/html_unescape.gperf"
+ {"NotLessTilde", 3, {226, 137, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1090 "src/html/html_unescape.gperf"
+ {"ncap", 3, {226, 169, 131}},
+ {(char*)0}, {(char*)0},
+#line 1197 "src/html/html_unescape.gperf"
+ {"NotLessGreater", 3, {226, 137, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1449 "src/html/html_unescape.gperf"
+ {"precsim", 3, {226, 137, 190}},
+ {(char*)0},
+#line 977 "src/html/html_unescape.gperf"
+ {"looparrowright", 3, {226, 134, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1433 "src/html/html_unescape.gperf"
+ {"Pr", 3, {226, 170, 187}},
+#line 1531 "src/html/html_unescape.gperf"
+ {"rcub", 1, {125}},
+#line 1038 "src/html/html_unescape.gperf"
+ {"mapstoup", 3, {226, 134, 165}},
+#line 861 "src/html/html_unescape.gperf"
+ {"lcub", 1, {123}},
+ {(char*)0},
+#line 2121 "src/html/html_unescape.gperf"
+ {"zfr", 4, {240, 157, 148, 183}},
+ {(char*)0}, {(char*)0},
+#line 1947 "src/html/html_unescape.gperf"
+ {"uparrow", 3, {226, 134, 145}},
+ {(char*)0},
+#line 633 "src/html/html_unescape.gperf"
+ {"gne", 3, {226, 170, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1641 "src/html/html_unescape.gperf"
+ {"sce", 3, {226, 170, 176}},
+#line 740 "src/html/html_unescape.gperf"
+ {"Im", 3, {226, 132, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1527 "src/html/html_unescape.gperf"
+ {"rcaron", 2, {197, 153}},
+ {(char*)0},
+#line 857 "src/html/html_unescape.gperf"
+ {"lcaron", 2, {196, 190}},
+#line 1350 "src/html/html_unescape.gperf"
+ {"Oopf", 4, {240, 157, 149, 134}},
+#line 1637 "src/html/html_unescape.gperf"
+ {"scaron", 2, {197, 161}},
+#line 89 "src/html/html_unescape.gperf"
+ {"backsim", 3, {226, 136, 189}},
+#line 1829 "src/html/html_unescape.gperf"
+ {"Tcaron", 2, {197, 164}},
+#line 2111 "src/html/html_unescape.gperf"
+ {"Zcaron", 2, {197, 189}},
+#line 463 "src/html/html_unescape.gperf"
+ {"ecaron", 2, {196, 155}},
+ {(char*)0},
+#line 109 "src/html/html_unescape.gperf"
+ {"Bernoullis", 3, {226, 132, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1122 "src/html/html_unescape.gperf"
+ {"nge", 3, {226, 137, 177}},
+#line 1830 "src/html/html_unescape.gperf"
+ {"tcaron", 2, {197, 165}},
+ {(char*)0},
+#line 567 "src/html/html_unescape.gperf"
+ {"fork", 3, {226, 139, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 702 "src/html/html_unescape.gperf"
+ {"Hscr", 3, {226, 132, 139}},
+ {(char*)0},
+#line 1092 "src/html/html_unescape.gperf"
+ {"ncaron", 2, {197, 136}},
+#line 488 "src/html/html_unescape.gperf"
+ {"elsdot", 3, {226, 170, 151}},
+ {(char*)0},
+#line 1828 "src/html/html_unescape.gperf"
+ {"tbrk", 3, {226, 142, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1887 "src/html/html_unescape.gperf"
+ {"triplus", 3, {226, 168, 185}},
+ {(char*)0}, {(char*)0},
+#line 379 "src/html/html_unescape.gperf"
+ {"diamond", 3, {226, 139, 132}},
+ {(char*)0}, {(char*)0},
+#line 1097 "src/html/html_unescape.gperf"
+ {"ncup", 3, {226, 169, 130}},
+ {(char*)0},
+#line 97 "src/html/html_unescape.gperf"
+ {"bbrk", 3, {226, 142, 181}},
+ {(char*)0},
+#line 587 "src/html/html_unescape.gperf"
+ {"frown", 3, {226, 140, 162}},
+#line 129 "src/html/html_unescape.gperf"
+ {"bkarow", 3, {226, 164, 141}},
+ {(char*)0},
+#line 1714 "src/html/html_unescape.gperf"
+ {"spades", 3, {226, 153, 160}},
+ {(char*)0},
+#line 1470 "src/html/html_unescape.gperf"
+ {"psi", 2, {207, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 145 "src/html/html_unescape.gperf"
+ {"Bopf", 4, {240, 157, 148, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 395 "src/html/html_unescape.gperf"
+ {"dollar", 1, {36}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 386 "src/html/html_unescape.gperf"
+ {"disin", 3, {226, 139, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1715 "src/html/html_unescape.gperf"
+ {"spadesuit", 3, {226, 153, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1226 "src/html/html_unescape.gperf"
+ {"NotTilde", 3, {226, 137, 129}},
+#line 407 "src/html/html_unescape.gperf"
+ {"doublebarwedge", 3, {226, 140, 134}},
+ {(char*)0},
+#line 595 "src/html/html_unescape.gperf"
+ {"gap", 3, {226, 170, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 98 "src/html/html_unescape.gperf"
+ {"bbrktbrk", 3, {226, 142, 182}},
+ {(char*)0}, {(char*)0},
+#line 1821 "src/html/html_unescape.gperf"
+ {"swarrow", 3, {226, 134, 153}},
+#line 107 "src/html/html_unescape.gperf"
+ {"bepsi", 2, {207, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 771 "src/html/html_unescape.gperf"
+ {"Iscr", 3, {226, 132, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1228 "src/html/html_unescape.gperf"
+ {"NotTildeFullEqual", 3, {226, 137, 135}},
+#line 514 "src/html/html_unescape.gperf"
+ {"eqcolon", 3, {226, 137, 149}},
+ {(char*)0}, {(char*)0},
+#line 1864 "src/html/html_unescape.gperf"
+ {"tint", 3, {226, 136, 173}},
+ {(char*)0}, {(char*)0},
+#line 757 "src/html/html_unescape.gperf"
+ {"intprod", 3, {226, 168, 188}},
+ {(char*)0},
+#line 1272 "src/html/html_unescape.gperf"
+ {"nsupE", 3, {226, 171, 134}},
+ {(char*)0}, {(char*)0},
+#line 1309 "src/html/html_unescape.gperf"
+ {"nwarrow", 3, {226, 134, 150}},
+#line 1264 "src/html/html_unescape.gperf"
+ {"nsubE", 3, {226, 171, 133}},
+ {(char*)0}, {(char*)0},
+#line 1126 "src/html/html_unescape.gperf"
+ {"nges", 3, {226, 169, 190}},
+ {(char*)0},
+#line 1949 "src/html/html_unescape.gperf"
+ {"Uparrow", 3, {226, 135, 145}},
+#line 605 "src/html/html_unescape.gperf"
+ {"ge", 3, {226, 137, 165}},
+#line 1353 "src/html/html_unescape.gperf"
+ {"OpenCurlyDoubleQuote", 3, {226, 128, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1699 "src/html/html_unescape.gperf"
+ {"smallsetminus", 3, {226, 136, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1636 "src/html/html_unescape.gperf"
+ {"Scaron", 2, {197, 160}},
+ {(char*)0},
+#line 1302 "src/html/html_unescape.gperf"
+ {"nvltrie", 3, {226, 138, 180}},
+#line 613 "src/html/html_unescape.gperf"
+ {"ges", 3, {226, 169, 190}},
+#line 136 "src/html/html_unescape.gperf"
+ {"blank", 3, {226, 144, 163}},
+#line 1485 "src/html/html_unescape.gperf"
+ {"QUOT", 1, {34}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 140 "src/html/html_unescape.gperf"
+ {"block", 3, {226, 150, 136}},
+#line 1874 "src/html/html_unescape.gperf"
+ {"trade", 3, {226, 132, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 795 "src/html/html_unescape.gperf"
+ {"jscr", 4, {240, 157, 146, 191}},
+#line 2047 "src/html/html_unescape.gperf"
+ {"wedge", 3, {226, 136, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 30 "src/html/html_unescape.gperf"
+ {"Amacr", 2, {196, 128}},
+ {(char*)0},
+#line 518 "src/html/html_unescape.gperf"
+ {"Equal", 3, {226, 169, 181}},
+ {(char*)0}, {(char*)0},
+#line 352 "src/html/html_unescape.gperf"
+ {"Dcaron", 2, {196, 142}},
+ {(char*)0}, {(char*)0},
+#line 400 "src/html/html_unescape.gperf"
+ {"DotDot", 3, {226, 131, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 635 "src/html/html_unescape.gperf"
+ {"gneq", 3, {226, 170, 136}},
+#line 1991 "src/html/html_unescape.gperf"
+ {"varpropto", 3, {226, 136, 157}},
+ {(char*)0},
+#line 636 "src/html/html_unescape.gperf"
+ {"gneqq", 3, {226, 137, 169}},
+#line 1462 "src/html/html_unescape.gperf"
+ {"Proportional", 3, {226, 136, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 775 "src/html/html_unescape.gperf"
+ {"isins", 3, {226, 139, 180}},
+ {(char*)0},
+#line 470 "src/html/html_unescape.gperf"
+ {"eDDot", 3, {226, 169, 183}},
+#line 772 "src/html/html_unescape.gperf"
+ {"isin", 3, {226, 136, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1886 "src/html/html_unescape.gperf"
+ {"TripleDot", 3, {226, 131, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 569 "src/html/html_unescape.gperf"
+ {"Fouriertrf", 3, {226, 132, 177}},
+#line 1463 "src/html/html_unescape.gperf"
+ {"Proportion", 3, {226, 136, 183}},
+ {(char*)0}, {(char*)0},
+#line 1123 "src/html/html_unescape.gperf"
+ {"ngeq", 3, {226, 137, 177}},
+#line 856 "src/html/html_unescape.gperf"
+ {"Lcaron", 2, {196, 189}},
+ {(char*)0},
+#line 1124 "src/html/html_unescape.gperf"
+ {"ngeqq", 3, {226, 137, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 871 "src/html/html_unescape.gperf"
+ {"lE", 3, {226, 137, 166}},
+#line 228 "src/html/html_unescape.gperf"
+ {"Ccaron", 2, {196, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 200 "src/html/html_unescape.gperf"
+ {"bsemi", 3, {226, 129, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1464 "src/html/html_unescape.gperf"
+ {"propto", 3, {226, 136, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 915 "src/html/html_unescape.gperf"
+ {"lesdot", 3, {226, 169, 191}},
+#line 292 "src/html/html_unescape.gperf"
+ {"Conint", 3, {226, 136, 175}},
+ {(char*)0},
+#line 36 "src/html/html_unescape.gperf"
+ {"And", 3, {226, 169, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1660 "src/html/html_unescape.gperf"
+ {"searrow", 3, {226, 134, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1367 "src/html/html_unescape.gperf"
+ {"orslope", 3, {226, 169, 151}},
+#line 677 "src/html/html_unescape.gperf"
+ {"harr", 3, {226, 134, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 846 "src/html/html_unescape.gperf"
+ {"late", 3, {226, 170, 173}},
+ {(char*)0},
+#line 244 "src/html/html_unescape.gperf"
+ {"CenterDot", 2, {194, 183}},
+ {(char*)0}, {(char*)0},
+#line 1329 "src/html/html_unescape.gperf"
+ {"ofr", 4, {240, 157, 148, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1104 "src/html/html_unescape.gperf"
+ {"nearrow", 3, {226, 134, 151}},
+ {(char*)0},
+#line 1474 "src/html/html_unescape.gperf"
+ {"qint", 3, {226, 168, 140}},
+ {(char*)0}, {(char*)0},
+#line 847 "src/html/html_unescape.gperf"
+ {"lates", 3, {226, 170, 173}},
+#line 802 "src/html/html_unescape.gperf"
+ {"kappav", 2, {207, 176}},
+ {(char*)0}, {(char*)0},
+#line 699 "src/html/html_unescape.gperf"
+ {"horbar", 3, {226, 128, 149}},
+#line 476 "src/html/html_unescape.gperf"
+ {"Efr", 4, {240, 157, 148, 136}},
+#line 693 "src/html/html_unescape.gperf"
+ {"hoarr", 3, {226, 135, 191}},
+#line 1240 "src/html/html_unescape.gperf"
+ {"npre", 3, {226, 170, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 748 "src/html/html_unescape.gperf"
+ {"inodot", 2, {196, 177}},
+ {(char*)0},
+#line 1916 "src/html/html_unescape.gperf"
+ {"udarr", 3, {226, 135, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 609 "src/html/html_unescape.gperf"
+ {"geq", 3, {226, 137, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1258 "src/html/html_unescape.gperf"
+ {"nsimeq", 3, {226, 137, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 610 "src/html/html_unescape.gperf"
+ {"geqq", 3, {226, 137, 167}},
+ {(char*)0}, {(char*)0},
+#line 475 "src/html/html_unescape.gperf"
+ {"efDot", 3, {226, 137, 146}},
+ {(char*)0}, {(char*)0},
+#line 1611 "src/html/html_unescape.gperf"
+ {"rpargt", 3, {226, 166, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1370 "src/html/html_unescape.gperf"
+ {"Oscr", 4, {240, 157, 146, 170}},
+ {(char*)0}, {(char*)0},
+#line 1419 "src/html/html_unescape.gperf"
+ {"plusdo", 3, {226, 136, 148}},
+ {(char*)0}, {(char*)0},
+#line 822 "src/html/html_unescape.gperf"
+ {"lagran", 3, {226, 132, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1847 "src/html/html_unescape.gperf"
+ {"thicksim", 3, {226, 136, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1446 "src/html/html_unescape.gperf"
+ {"precnsim", 3, {226, 139, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1091 "src/html/html_unescape.gperf"
+ {"Ncaron", 2, {197, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1080 "src/html/html_unescape.gperf"
+ {"napE", 3, {226, 169, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 728 "src/html/html_unescape.gperf"
+ {"iiint", 3, {226, 136, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 199 "src/html/html_unescape.gperf"
+ {"Bscr", 3, {226, 132, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1036 "src/html/html_unescape.gperf"
+ {"mapstodown", 3, {226, 134, 167}},
+ {(char*)0}, {(char*)0},
+#line 1994 "src/html/html_unescape.gperf"
+ {"varrho", 2, {207, 177}},
+ {(char*)0},
+#line 776 "src/html/html_unescape.gperf"
+ {"isinsv", 3, {226, 139, 179}},
+ {(char*)0}, {(char*)0},
+#line 1297 "src/html/html_unescape.gperf"
+ {"nvHarr", 3, {226, 164, 132}},
+ {(char*)0}, {(char*)0},
+#line 1192 "src/html/html_unescape.gperf"
+ {"NotLeftTriangleBar", 3, {226, 167, 143}},
+ {(char*)0},
+#line 521 "src/html/html_unescape.gperf"
+ {"equest", 3, {226, 137, 159}},
+ {(char*)0},
+#line 1194 "src/html/html_unescape.gperf"
+ {"NotLeftTriangleEqual", 3, {226, 139, 172}},
+#line 1193 "src/html/html_unescape.gperf"
+ {"NotLeftTriangle", 3, {226, 139, 170}},
+ {(char*)0}, {(char*)0},
+#line 61 "src/html/html_unescape.gperf"
+ {"Aopf", 4, {240, 157, 148, 184}},
+#line 681 "src/html/html_unescape.gperf"
+ {"hbar", 3, {226, 132, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1985 "src/html/html_unescape.gperf"
+ {"vangrt", 3, {226, 166, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 689 "src/html/html_unescape.gperf"
+ {"Hfr", 3, {226, 132, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1495 "src/html/html_unescape.gperf"
+ {"range", 3, {226, 166, 165}},
+#line 1705 "src/html/html_unescape.gperf"
+ {"smte", 3, {226, 170, 172}},
+#line 1003 "src/html/html_unescape.gperf"
+ {"lsim", 3, {226, 137, 178}},
+ {(char*)0},
+#line 1235 "src/html/html_unescape.gperf"
+ {"npolint", 3, {226, 168, 148}},
+ {(char*)0},
+#line 353 "src/html/html_unescape.gperf"
+ {"dcaron", 2, {196, 143}},
+ {(char*)0},
+#line 532 "src/html/html_unescape.gperf"
+ {"esim", 3, {226, 137, 130}},
+ {(char*)0},
+#line 1940 "src/html/html_unescape.gperf"
+ {"Union", 3, {226, 139, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1706 "src/html/html_unescape.gperf"
+ {"smtes", 3, {226, 170, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 815 "src/html/html_unescape.gperf"
+ {"kopf", 4, {240, 157, 149, 156}},
+#line 639 "src/html/html_unescape.gperf"
+ {"gopf", 4, {240, 157, 149, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1256 "src/html/html_unescape.gperf"
+ {"nsim", 3, {226, 137, 129}},
+ {(char*)0},
+#line 201 "src/html/html_unescape.gperf"
+ {"bsim", 3, {226, 136, 189}},
+ {(char*)0},
+#line 1698 "src/html/html_unescape.gperf"
+ {"SmallCircle", 3, {226, 136, 152}},
+ {(char*)0},
+#line 1172 "src/html/html_unescape.gperf"
+ {"NotDoubleVerticalBar", 3, {226, 136, 166}},
+#line 1201 "src/html/html_unescape.gperf"
+ {"NotNestedGreaterGreater", 3, {226, 170, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 520 "src/html/html_unescape.gperf"
+ {"EqualTilde", 3, {226, 137, 130}},
+ {(char*)0}, {(char*)0},
+#line 1187 "src/html/html_unescape.gperf"
+ {"notindot", 3, {226, 139, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1526 "src/html/html_unescape.gperf"
+ {"Rcaron", 2, {197, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1430 "src/html/html_unescape.gperf"
+ {"Popf", 3, {226, 132, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 638 "src/html/html_unescape.gperf"
+ {"Gopf", 4, {240, 157, 148, 190}},
+ {(char*)0}, {(char*)0},
+#line 723 "src/html/html_unescape.gperf"
+ {"Ifr", 3, {226, 132, 145}},
+ {(char*)0}, {(char*)0},
+#line 2049 "src/html/html_unescape.gperf"
+ {"wedgeq", 3, {226, 137, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1456 "src/html/html_unescape.gperf"
+ {"prod", 3, {226, 136, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1374 "src/html/html_unescape.gperf"
+ {"osol", 3, {226, 138, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 419 "src/html/html_unescape.gperf"
+ {"DoubleUpArrow", 3, {226, 135, 145}},
+ {(char*)0}, {(char*)0},
+#line 290 "src/html/html_unescape.gperf"
+ {"Congruent", 3, {226, 137, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 637 "src/html/html_unescape.gperf"
+ {"gnsim", 3, {226, 139, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1651 "src/html/html_unescape.gperf"
+ {"scsim", 3, {226, 137, 191}},
+ {(char*)0},
+#line 790 "src/html/html_unescape.gperf"
+ {"jfr", 4, {240, 157, 148, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1962 "src/html/html_unescape.gperf"
+ {"upsih", 2, {207, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1156 "src/html/html_unescape.gperf"
+ {"nLl", 3, {226, 139, 152}},
+ {(char*)0}, {(char*)0},
+#line 420 "src/html/html_unescape.gperf"
+ {"DoubleUpDownArrow", 3, {226, 135, 149}},
+ {(char*)0},
+#line 1128 "src/html/html_unescape.gperf"
+ {"ngsim", 3, {226, 137, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 684 "src/html/html_unescape.gperf"
+ {"hearts", 3, {226, 153, 165}},
+ {(char*)0},
+#line 922 "src/html/html_unescape.gperf"
+ {"lesseqgtr", 3, {226, 139, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1112 "src/html/html_unescape.gperf"
+ {"nesear", 3, {226, 164, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 542 "src/html/html_unescape.gperf"
+ {"Exists", 3, {226, 136, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1703 "src/html/html_unescape.gperf"
+ {"smile", 3, {226, 140, 163}},
+ {(char*)0},
+#line 1984 "src/html/html_unescape.gperf"
+ {"uwangle", 3, {226, 166, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 685 "src/html/html_unescape.gperf"
+ {"heartsuit", 3, {226, 153, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 700 "src/html/html_unescape.gperf"
+ {"HorizontalLine", 3, {226, 148, 128}},
+ {(char*)0}, {(char*)0},
+#line 645 "src/html/html_unescape.gperf"
+ {"GreaterLess", 3, {226, 137, 183}},
+ {(char*)0},
+#line 1615 "src/html/html_unescape.gperf"
+ {"rsaquo", 3, {226, 128, 186}},
+ {(char*)0},
+#line 998 "src/html/html_unescape.gperf"
+ {"lsaquo", 3, {226, 128, 185}},
+ {(char*)0},
+#line 1540 "src/html/html_unescape.gperf"
+ {"realine", 3, {226, 132, 155}},
+#line 348 "src/html/html_unescape.gperf"
+ {"Dashv", 3, {226, 171, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1687 "src/html/html_unescape.gperf"
+ {"simdot", 3, {226, 169, 170}},
+#line 641 "src/html/html_unescape.gperf"
+ {"GreaterEqual", 3, {226, 137, 165}},
+#line 647 "src/html/html_unescape.gperf"
+ {"GreaterTilde", 3, {226, 137, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 642 "src/html/html_unescape.gperf"
+ {"GreaterEqualLess", 3, {226, 139, 155}},
+ {(char*)0},
+#line 644 "src/html/html_unescape.gperf"
+ {"GreaterGreater", 3, {226, 170, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1530 "src/html/html_unescape.gperf"
+ {"rceil", 3, {226, 140, 137}},
+ {(char*)0},
+#line 860 "src/html/html_unescape.gperf"
+ {"lceil", 3, {226, 140, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 927 "src/html/html_unescape.gperf"
+ {"lessgtr", 3, {226, 137, 182}},
+ {(char*)0}, {(char*)0},
+#line 1340 "src/html/html_unescape.gperf"
+ {"oline", 3, {226, 128, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1852 "src/html/html_unescape.gperf"
+ {"thksim", 3, {226, 136, 188}},
+ {(char*)0},
+#line 759 "src/html/html_unescape.gperf"
+ {"InvisibleTimes", 3, {226, 129, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1487 "src/html/html_unescape.gperf"
+ {"race", 3, {226, 136, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 769 "src/html/html_unescape.gperf"
+ {"iquest", 2, {194, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 737 "src/html/html_unescape.gperf"
+ {"imagline", 3, {226, 132, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1966 "src/html/html_unescape.gperf"
+ {"UpTee", 3, {226, 138, 165}},
+ {(char*)0},
+#line 1053 "src/html/html_unescape.gperf"
+ {"midcir", 3, {226, 171, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1327 "src/html/html_unescape.gperf"
+ {"ofcir", 3, {226, 166, 191}},
+ {(char*)0}, {(char*)0},
+#line 357 "src/html/html_unescape.gperf"
+ {"ddarr", 3, {226, 135, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1494 "src/html/html_unescape.gperf"
+ {"rangd", 3, {226, 166, 146}},
+ {(char*)0},
+#line 827 "src/html/html_unescape.gperf"
+ {"langd", 3, {226, 166, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 522 "src/html/html_unescape.gperf"
+ {"Equilibrium", 3, {226, 135, 140}},
+#line 1390 "src/html/html_unescape.gperf"
+ {"parsim", 3, {226, 171, 179}},
+#line 2012 "src/html/html_unescape.gperf"
+ {"Vdashl", 3, {226, 171, 166}},
+#line 1328 "src/html/html_unescape.gperf"
+ {"Ofr", 4, {240, 157, 148, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 105 "src/html/html_unescape.gperf"
+ {"Because", 3, {226, 136, 181}},
+ {(char*)0},
+#line 1514 "src/html/html_unescape.gperf"
+ {"rAtail", 3, {226, 164, 156}},
+ {(char*)0},
+#line 844 "src/html/html_unescape.gperf"
+ {"lAtail", 3, {226, 164, 155}},
+#line 1349 "src/html/html_unescape.gperf"
+ {"ominus", 3, {226, 138, 150}},
+#line 74 "src/html/html_unescape.gperf"
+ {"Ascr", 4, {240, 157, 146, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 510 "src/html/html_unescape.gperf"
+ {"Epsilon", 2, {206, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1676 "src/html/html_unescape.gperf"
+ {"ShortLeftArrow", 3, {226, 134, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 777 "src/html/html_unescape.gperf"
+ {"isinv", 3, {226, 136, 136}},
+ {(char*)0},
+#line 1051 "src/html/html_unescape.gperf"
+ {"micro", 2, {194, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2112 "src/html/html_unescape.gperf"
+ {"zcaron", 2, {197, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 817 "src/html/html_unescape.gperf"
+ {"kscr", 4, {240, 157, 147, 128}},
+#line 649 "src/html/html_unescape.gperf"
+ {"gscr", 3, {226, 132, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 114 "src/html/html_unescape.gperf"
+ {"Bfr", 4, {240, 157, 148, 133}},
+#line 608 "src/html/html_unescape.gperf"
+ {"gel", 3, {226, 139, 155}},
+#line 687 "src/html/html_unescape.gperf"
+ {"hercon", 3, {226, 138, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1885 "src/html/html_unescape.gperf"
+ {"triminus", 3, {226, 168, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 480 "src/html/html_unescape.gperf"
+ {"egrave", 2, {195, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1655 "src/html/html_unescape.gperf"
+ {"sdot", 3, {226, 139, 133}},
+#line 1924 "src/html/html_unescape.gperf"
+ {"ugrave", 2, {195, 185}},
+ {(char*)0},
+#line 2115 "src/html/html_unescape.gperf"
+ {"Zdot", 2, {197, 187}},
+#line 472 "src/html/html_unescape.gperf"
+ {"edot", 2, {196, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1229 "src/html/html_unescape.gperf"
+ {"NotTildeTilde", 3, {226, 137, 137}},
+ {(char*)0},
+#line 1835 "src/html/html_unescape.gperf"
+ {"tdot", 3, {226, 131, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1467 "src/html/html_unescape.gperf"
+ {"Pscr", 4, {240, 157, 146, 171}},
+#line 1408 "src/html/html_unescape.gperf"
+ {"Pi", 2, {206, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 648 "src/html/html_unescape.gperf"
+ {"Gscr", 4, {240, 157, 146, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1425 "src/html/html_unescape.gperf"
+ {"plustwo", 3, {226, 168, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1173 "src/html/html_unescape.gperf"
+ {"NotElement", 3, {226, 136, 137}},
+ {(char*)0},
+#line 1422 "src/html/html_unescape.gperf"
+ {"PlusMinus", 2, {194, 177}},
+ {(char*)0}, {(char*)0},
+#line 697 "src/html/html_unescape.gperf"
+ {"hopf", 4, {240, 157, 149, 153}},
+#line 594 "src/html/html_unescape.gperf"
+ {"gammad", 2, {207, 157}},
+ {(char*)0},
+#line 1044 "src/html/html_unescape.gperf"
+ {"mDDot", 3, {226, 136, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 389 "src/html/html_unescape.gperf"
+ {"divideontimes", 3, {226, 139, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 401 "src/html/html_unescape.gperf"
+ {"doteq", 3, {226, 137, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1986 "src/html/html_unescape.gperf"
+ {"varepsilon", 2, {207, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1439 "src/html/html_unescape.gperf"
+ {"Precedes", 3, {226, 137, 186}},
+ {(char*)0}, {(char*)0},
+#line 593 "src/html/html_unescape.gperf"
+ {"Gammad", 2, {207, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 349 "src/html/html_unescape.gperf"
+ {"dashv", 3, {226, 138, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1170 "src/html/html_unescape.gperf"
+ {"NotCongruent", 3, {226, 137, 162}},
+ {(char*)0}, {(char*)0},
+#line 1911 "src/html/html_unescape.gperf"
+ {"ubreve", 2, {197, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1333 "src/html/html_unescape.gperf"
+ {"ogt", 3, {226, 167, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1609 "src/html/html_unescape.gperf"
+ {"RoundImplies", 3, {226, 165, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1441 "src/html/html_unescape.gperf"
+ {"PrecedesSlantEqual", 3, {226, 137, 188}},
+ {(char*)0}, {(char*)0},
+#line 1688 "src/html/html_unescape.gperf"
+ {"sime", 3, {226, 137, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1923 "src/html/html_unescape.gperf"
+ {"Ugrave", 2, {195, 153}},
+ {(char*)0},
+#line 350 "src/html/html_unescape.gperf"
+ {"dbkarow", 3, {226, 164, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1656 "src/html/html_unescape.gperf"
+ {"sdote", 3, {226, 169, 166}},
+ {(char*)0},
+#line 2016 "src/html/html_unescape.gperf"
+ {"veeeq", 3, {226, 137, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1035 "src/html/html_unescape.gperf"
+ {"mapsto", 3, {226, 134, 166}},
+ {(char*)0}, {(char*)0},
+#line 1862 "src/html/html_unescape.gperf"
+ {"times", 2, {195, 151}},
+ {(char*)0}, {(char*)0},
+#line 1496 "src/html/html_unescape.gperf"
+ {"rangle", 3, {226, 159, 169}},
+ {(char*)0},
+#line 828 "src/html/html_unescape.gperf"
+ {"langle", 3, {226, 159, 168}},
+ {(char*)0}, {(char*)0},
+#line 878 "src/html/html_unescape.gperf"
+ {"leftarrowtail", 3, {226, 134, 162}},
+#line 673 "src/html/html_unescape.gperf"
+ {"hamilt", 3, {226, 132, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1919 "src/html/html_unescape.gperf"
+ {"udhar", 3, {226, 165, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1138 "src/html/html_unescape.gperf"
+ {"nisd", 3, {226, 139, 186}},
+ {(char*)0},
+#line 1550 "src/html/html_unescape.gperf"
+ {"rfisht", 3, {226, 165, 189}},
+ {(char*)0},
+#line 932 "src/html/html_unescape.gperf"
+ {"lfisht", 3, {226, 165, 188}},
+#line 676 "src/html/html_unescape.gperf"
+ {"harrcir", 3, {226, 165, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1354 "src/html/html_unescape.gperf"
+ {"OpenCurlyQuote", 3, {226, 128, 152}},
+ {(char*)0},
+#line 1920 "src/html/html_unescape.gperf"
+ {"ufisht", 3, {226, 165, 190}},
+#line 1184 "src/html/html_unescape.gperf"
+ {"NotHumpDownHump", 3, {226, 137, 142}},
+ {(char*)0}, {(char*)0},
+#line 896 "src/html/html_unescape.gperf"
+ {"LeftTee", 3, {226, 138, 163}},
+ {(char*)0},
+#line 1618 "src/html/html_unescape.gperf"
+ {"rsh", 3, {226, 134, 177}},
+ {(char*)0},
+#line 1001 "src/html/html_unescape.gperf"
+ {"lsh", 3, {226, 134, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 668 "src/html/html_unescape.gperf"
+ {"gvertneqq", 3, {226, 137, 169}},
+ {(char*)0}, {(char*)0},
+#line 1861 "src/html/html_unescape.gperf"
+ {"timesb", 3, {226, 138, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1650 "src/html/html_unescape.gperf"
+ {"scpolint", 3, {226, 168, 147}},
+ {(char*)0}, {(char*)0},
+#line 237 "src/html/html_unescape.gperf"
+ {"Cdot", 2, {196, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 455 "src/html/html_unescape.gperf"
+ {"dwangle", 3, {226, 166, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1910 "src/html/html_unescape.gperf"
+ {"Ubreve", 2, {197, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 905 "src/html/html_unescape.gperf"
+ {"LeftUpVector", 3, {226, 134, 191}},
+ {(char*)0}, {(char*)0},
+#line 904 "src/html/html_unescape.gperf"
+ {"LeftUpVectorBar", 3, {226, 165, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 462 "src/html/html_unescape.gperf"
+ {"Ecaron", 2, {196, 154}},
+ {(char*)0}, {(char*)0},
+#line 694 "src/html/html_unescape.gperf"
+ {"homtht", 3, {226, 136, 187}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 725 "src/html/html_unescape.gperf"
+ {"igrave", 2, {195, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1239 "src/html/html_unescape.gperf"
+ {"npreceq", 3, {226, 170, 175}},
+#line 467 "src/html/html_unescape.gperf"
+ {"ecolon", 3, {226, 137, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 359 "src/html/html_unescape.gperf"
+ {"dd", 3, {226, 133, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1689 "src/html/html_unescape.gperf"
+ {"simeq", 3, {226, 137, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1188 "src/html/html_unescape.gperf"
+ {"notinE", 3, {226, 139, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 120 "src/html/html_unescape.gperf"
+ {"bigoplus", 3, {226, 168, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 22 "src/html/html_unescape.gperf"
+ {"Afr", 4, {240, 157, 148, 132}},
+#line 874 "src/html/html_unescape.gperf"
+ {"leftarrow", 3, {226, 134, 144}},
+#line 1336 "src/html/html_unescape.gperf"
+ {"oint", 3, {226, 136, 174}},
+ {(char*)0},
+#line 1824 "src/html/html_unescape.gperf"
+ {"Tab", 1, {9}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1330 "src/html/html_unescape.gperf"
+ {"ogon", 2, {203, 155}},
+ {(char*)0}, {(char*)0},
+#line 1013 "src/html/html_unescape.gperf"
+ {"lt", 1, {60}},
+#line 1150 "src/html/html_unescape.gperf"
+ {"nLeftrightarrow", 3, {226, 135, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1499 "src/html/html_unescape.gperf"
+ {"rarrb", 3, {226, 135, 165}},
+ {(char*)0},
+#line 832 "src/html/html_unescape.gperf"
+ {"larrb", 3, {226, 135, 164}},
+ {(char*)0},
+#line 701 "src/html/html_unescape.gperf"
+ {"hscr", 4, {240, 157, 146, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 902 "src/html/html_unescape.gperf"
+ {"LeftUpDownVector", 3, {226, 165, 145}},
+ {(char*)0},
+#line 808 "src/html/html_unescape.gperf"
+ {"kfr", 4, {240, 157, 148, 168}},
+#line 620 "src/html/html_unescape.gperf"
+ {"gfr", 4, {240, 157, 148, 164}},
+#line 1946 "src/html/html_unescape.gperf"
+ {"UpArrowBar", 3, {226, 164, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1251 "src/html/html_unescape.gperf"
+ {"nsce", 3, {226, 170, 176}},
+#line 1016 "src/html/html_unescape.gperf"
+ {"ltdot", 3, {226, 139, 150}},
+#line 617 "src/html/html_unescape.gperf"
+ {"gesl", 3, {226, 139, 155}},
+#line 2074 "src/html/html_unescape.gperf"
+ {"xodot", 3, {226, 168, 128}},
+#line 1748 "src/html/html_unescape.gperf"
+ {"star", 3, {226, 152, 134}},
+ {(char*)0}, {(char*)0},
+#line 984 "src/html/html_unescape.gperf"
+ {"lowbar", 1, {95}},
+ {(char*)0},
+#line 2066 "src/html/html_unescape.gperf"
+ {"xharr", 3, {226, 159, 183}},
+#line 466 "src/html/html_unescape.gperf"
+ {"ecir", 3, {226, 137, 150}},
+ {(char*)0},
+#line 1976 "src/html/html_unescape.gperf"
+ {"utdot", 3, {226, 139, 176}},
+#line 1086 "src/html/html_unescape.gperf"
+ {"natur", 3, {226, 153, 174}},
+#line 1002 "src/html/html_unescape.gperf"
+ {"Lsh", 3, {226, 134, 176}},
+#line 746 "src/html/html_unescape.gperf"
+ {"infin", 3, {226, 136, 158}},
+ {(char*)0},
+#line 284 "src/html/html_unescape.gperf"
+ {"comp", 3, {226, 136, 129}},
+ {(char*)0},
+#line 1685 "src/html/html_unescape.gperf"
+ {"sigmav", 2, {207, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2078 "src/html/html_unescape.gperf"
+ {"xotime", 3, {226, 168, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1401 "src/html/html_unescape.gperf"
+ {"Pfr", 4, {240, 157, 148, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 619 "src/html/html_unescape.gperf"
+ {"Gfr", 4, {240, 157, 148, 138}},
+ {(char*)0}, {(char*)0},
+#line 116 "src/html/html_unescape.gperf"
+ {"bigcap", 3, {226, 139, 130}},
+ {(char*)0},
+#line 1693 "src/html/html_unescape.gperf"
+ {"simlE", 3, {226, 170, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 727 "src/html/html_unescape.gperf"
+ {"iiiint", 3, {226, 168, 140}},
+#line 96 "src/html/html_unescape.gperf"
+ {"barwedge", 3, {226, 140, 133}},
+#line 95 "src/html/html_unescape.gperf"
+ {"Barwed", 3, {226, 140, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2070 "src/html/html_unescape.gperf"
+ {"xlarr", 3, {226, 159, 181}},
+#line 924 "src/html/html_unescape.gperf"
+ {"LessEqualGreater", 3, {226, 139, 154}},
+ {(char*)0},
+#line 302 "src/html/html_unescape.gperf"
+ {"crarr", 3, {226, 134, 181}},
+#line 773 "src/html/html_unescape.gperf"
+ {"isindot", 3, {226, 139, 181}},
+ {(char*)0},
+#line 283 "src/html/html_unescape.gperf"
+ {"commat", 1, {64}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1055 "src/html/html_unescape.gperf"
+ {"middot", 2, {194, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 917 "src/html/html_unescape.gperf"
+ {"lesdotor", 3, {226, 170, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1684 "src/html/html_unescape.gperf"
+ {"sigmaf", 2, {207, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1500 "src/html/html_unescape.gperf"
+ {"rarrbfs", 3, {226, 164, 160}},
+ {(char*)0},
+#line 833 "src/html/html_unescape.gperf"
+ {"larrbfs", 3, {226, 164, 159}},
+ {(char*)0}, {(char*)0},
+#line 2079 "src/html/html_unescape.gperf"
+ {"xrarr", 3, {226, 159, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 118 "src/html/html_unescape.gperf"
+ {"bigcup", 3, {226, 139, 131}},
+ {(char*)0},
+#line 275 "src/html/html_unescape.gperf"
+ {"clubs", 3, {226, 153, 163}},
+#line 678 "src/html/html_unescape.gperf"
+ {"hArr", 3, {226, 135, 148}},
+#line 1626 "src/html/html_unescape.gperf"
+ {"rtrie", 3, {226, 138, 181}},
+ {(char*)0},
+#line 1022 "src/html/html_unescape.gperf"
+ {"ltrie", 3, {226, 138, 180}},
+#line 742 "src/html/html_unescape.gperf"
+ {"imped", 2, {198, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 503 "src/html/html_unescape.gperf"
+ {"eogon", 2, {196, 153}},
+#line 1631 "src/html/html_unescape.gperf"
+ {"rx", 3, {226, 132, 158}},
+#line 1024 "src/html/html_unescape.gperf"
+ {"ltrPar", 3, {226, 166, 150}},
+#line 1747 "src/html/html_unescape.gperf"
+ {"Star", 3, {226, 139, 134}},
+ {(char*)0},
+#line 1943 "src/html/html_unescape.gperf"
+ {"uogon", 2, {197, 179}},
+ {(char*)0}, {(char*)0},
+#line 1856 "src/html/html_unescape.gperf"
+ {"Tilde", 3, {226, 136, 188}},
+ {(char*)0},
+#line 672 "src/html/html_unescape.gperf"
+ {"half", 2, {194, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1855 "src/html/html_unescape.gperf"
+ {"tilde", 2, {203, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 876 "src/html/html_unescape.gperf"
+ {"Leftarrow", 3, {226, 135, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 618 "src/html/html_unescape.gperf"
+ {"gesles", 3, {226, 170, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 218 "src/html/html_unescape.gperf"
+ {"cap", 3, {226, 136, 169}},
+#line 1752 "src/html/html_unescape.gperf"
+ {"strns", 2, {194, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1015 "src/html/html_unescape.gperf"
+ {"Lt", 3, {226, 137, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1454 "src/html/html_unescape.gperf"
+ {"prnE", 3, {226, 170, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1727 "src/html/html_unescape.gperf"
+ {"sqsupe", 3, {226, 138, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1728 "src/html/html_unescape.gperf"
+ {"sqsupset", 3, {226, 138, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1883 "src/html/html_unescape.gperf"
+ {"tridot", 3, {226, 151, 172}},
+#line 1361 "src/html/html_unescape.gperf"
+ {"order", 3, {226, 132, 180}},
+ {(char*)0}, {(char*)0},
+#line 223 "src/html/html_unescape.gperf"
+ {"caps", 3, {226, 136, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 303 "src/html/html_unescape.gperf"
+ {"cross", 3, {226, 156, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 367 "src/html/html_unescape.gperf"
+ {"dfisht", 3, {226, 165, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2072 "src/html/html_unescape.gperf"
+ {"xmap", 3, {226, 159, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1726 "src/html/html_unescape.gperf"
+ {"sqsup", 3, {226, 138, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1625 "src/html/html_unescape.gperf"
+ {"rtri", 3, {226, 150, 185}},
+ {(char*)0},
+#line 1021 "src/html/html_unescape.gperf"
+ {"ltri", 3, {226, 151, 131}},
+#line 778 "src/html/html_unescape.gperf"
+ {"it", 3, {226, 129, 162}},
+#line 1599 "src/html/html_unescape.gperf"
+ {"rmoust", 3, {226, 142, 177}},
+ {(char*)0},
+#line 955 "src/html/html_unescape.gperf"
+ {"lmoust", 3, {226, 142, 176}},
+#line 634 "src/html/html_unescape.gperf"
+ {"gnE", 3, {226, 137, 169}},
+#line 937 "src/html/html_unescape.gperf"
+ {"lgE", 3, {226, 170, 145}},
+ {(char*)0}, {(char*)0},
+#line 1642 "src/html/html_unescape.gperf"
+ {"scE", 3, {226, 170, 180}},
+ {(char*)0},
+#line 1979 "src/html/html_unescape.gperf"
+ {"utri", 3, {226, 150, 181}},
+ {(char*)0},
+#line 2017 "src/html/html_unescape.gperf"
+ {"vellip", 3, {226, 139, 174}},
+ {(char*)0},
+#line 535 "src/html/html_unescape.gperf"
+ {"ETH", 2, {195, 144}},
+ {(char*)0}, {(char*)0},
+#line 953 "src/html/html_unescape.gperf"
+ {"lmidot", 2, {197, 128}},
+ {(char*)0},
+#line 1942 "src/html/html_unescape.gperf"
+ {"Uogon", 2, {197, 178}},
+#line 301 "src/html/html_unescape.gperf"
+ {"CounterClockwiseContourIntegral", 3, {226, 136, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1121 "src/html/html_unescape.gperf"
+ {"ngE", 3, {226, 137, 167}},
+#line 1310 "src/html/html_unescape.gperf"
+ {"nwnear", 3, {226, 164, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 918 "src/html/html_unescape.gperf"
+ {"lesg", 3, {226, 139, 154}},
+ {(char*)0}, {(char*)0},
+#line 1416 "src/html/html_unescape.gperf"
+ {"plusb", 3, {226, 138, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1619 "src/html/html_unescape.gperf"
+ {"Rsh", 3, {226, 134, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 300 "src/html/html_unescape.gperf"
+ {"copysr", 3, {226, 132, 151}},
+ {(char*)0},
+#line 747 "src/html/html_unescape.gperf"
+ {"infintie", 3, {226, 167, 157}},
+ {(char*)0},
+#line 739 "src/html/html_unescape.gperf"
+ {"imath", 2, {196, 177}},
+#line 531 "src/html/html_unescape.gperf"
+ {"Esim", 3, {226, 169, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1403 "src/html/html_unescape.gperf"
+ {"Phi", 2, {206, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 629 "src/html/html_unescape.gperf"
+ {"glE", 3, {226, 170, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2031 "src/html/html_unescape.gperf"
+ {"vnsup", 3, {226, 138, 131}},
+ {(char*)0}, {(char*)0},
+#line 1691 "src/html/html_unescape.gperf"
+ {"simgE", 3, {226, 170, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 414 "src/html/html_unescape.gperf"
+ {"DoubleLongLeftArrow", 3, {226, 159, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 415 "src/html/html_unescape.gperf"
+ {"DoubleLongLeftRightArrow", 3, {226, 159, 186}},
+ {(char*)0}, {(char*)0},
+#line 1296 "src/html/html_unescape.gperf"
+ {"nvgt", 1, {62}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1047 "src/html/html_unescape.gperf"
+ {"Mellintrf", 3, {226, 132, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1451 "src/html/html_unescape.gperf"
+ {"Prime", 3, {226, 128, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 729 "src/html/html_unescape.gperf"
+ {"iinfin", 3, {226, 167, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1547 "src/html/html_unescape.gperf"
+ {"ReverseElement", 3, {226, 136, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 493 "src/html/html_unescape.gperf"
+ {"EmptySmallSquare", 3, {226, 151, 187}},
+#line 1490 "src/html/html_unescape.gperf"
+ {"radic", 3, {226, 136, 154}},
+ {(char*)0}, {(char*)0},
+#line 688 "src/html/html_unescape.gperf"
+ {"hfr", 4, {240, 157, 148, 165}},
+#line 2116 "src/html/html_unescape.gperf"
+ {"zdot", 2, {197, 188}},
+#line 1030 "src/html/html_unescape.gperf"
+ {"male", 3, {226, 153, 130}},
+ {(char*)0},
+#line 1501 "src/html/html_unescape.gperf"
+ {"rarrc", 3, {226, 164, 179}},
+#line 1437 "src/html/html_unescape.gperf"
+ {"prec", 3, {226, 137, 186}},
+#line 1647 "src/html/html_unescape.gperf"
+ {"scnap", 3, {226, 170, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 384 "src/html/html_unescape.gperf"
+ {"DifferentialD", 3, {226, 133, 134}},
+ {(char*)0},
+#line 1064 "src/html/html_unescape.gperf"
+ {"models", 3, {226, 138, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1012 "src/html/html_unescape.gperf"
+ {"ltcir", 3, {226, 169, 185}},
+#line 763 "src/html/html_unescape.gperf"
+ {"iogon", 2, {196, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 217 "src/html/html_unescape.gperf"
+ {"capcap", 3, {226, 169, 139}},
+ {(char*)0},
+#line 721 "src/html/html_unescape.gperf"
+ {"iff", 3, {226, 135, 148}},
+ {(char*)0},
+#line 361 "src/html/html_unescape.gperf"
+ {"ddotseq", 3, {226, 169, 183}},
+ {(char*)0},
+#line 264 "src/html/html_unescape.gperf"
+ {"CirclePlus", 3, {226, 138, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1623 "src/html/html_unescape.gperf"
+ {"rthree", 3, {226, 139, 140}},
+ {(char*)0},
+#line 1017 "src/html/html_unescape.gperf"
+ {"lthree", 3, {226, 139, 139}},
+ {(char*)0}, {(char*)0},
+#line 1442 "src/html/html_unescape.gperf"
+ {"PrecedesTilde", 3, {226, 137, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 450 "src/html/html_unescape.gperf"
+ {"dtdot", 3, {226, 139, 177}},
+ {(char*)0},
+#line 276 "src/html/html_unescape.gperf"
+ {"clubsuit", 3, {226, 153, 163}},
+ {(char*)0},
+#line 1489 "src/html/html_unescape.gperf"
+ {"racute", 2, {197, 149}},
+ {(char*)0},
+#line 820 "src/html/html_unescape.gperf"
+ {"lacute", 2, {196, 186}},
+#line 1890 "src/html/html_unescape.gperf"
+ {"trpezium", 3, {226, 143, 162}},
+#line 1633 "src/html/html_unescape.gperf"
+ {"sacute", 2, {197, 155}},
+ {(char*)0}, {(char*)0},
+#line 2109 "src/html/html_unescape.gperf"
+ {"Zacute", 2, {197, 185}},
+#line 460 "src/html/html_unescape.gperf"
+ {"eacute", 2, {195, 169}},
+ {(char*)0},
+#line 1859 "src/html/html_unescape.gperf"
+ {"TildeTilde", 3, {226, 137, 136}},
+ {(char*)0},
+#line 1907 "src/html/html_unescape.gperf"
+ {"Uarrocir", 3, {226, 165, 137}},
+#line 1903 "src/html/html_unescape.gperf"
+ {"uacute", 2, {195, 186}},
+#line 983 "src/html/html_unescape.gperf"
+ {"lowast", 3, {226, 136, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1077 "src/html/html_unescape.gperf"
+ {"nacute", 2, {197, 132}},
+ {(char*)0},
+#line 1207 "src/html/html_unescape.gperf"
+ {"NotPrecedes", 3, {226, 138, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 952 "src/html/html_unescape.gperf"
+ {"Lmidot", 2, {196, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1948 "src/html/html_unescape.gperf"
+ {"UpArrow", 3, {226, 134, 145}},
+ {(char*)0},
+#line 1512 "src/html/html_unescape.gperf"
+ {"rarrw", 3, {226, 134, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 439 "src/html/html_unescape.gperf"
+ {"DownTee", 3, {226, 138, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 556 "src/html/html_unescape.gperf"
+ {"FilledSmallSquare", 3, {226, 151, 188}},
+#line 220 "src/html/html_unescape.gperf"
+ {"capcup", 3, {226, 169, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 643 "src/html/html_unescape.gperf"
+ {"GreaterFullEqual", 3, {226, 137, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1300 "src/html/html_unescape.gperf"
+ {"nvle", 3, {226, 137, 164}},
+ {(char*)0},
+#line 1884 "src/html/html_unescape.gperf"
+ {"trie", 3, {226, 137, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1347 "src/html/html_unescape.gperf"
+ {"omicron", 2, {206, 191}},
+ {(char*)0},
+#line 418 "src/html/html_unescape.gperf"
+ {"DoubleRightTee", 3, {226, 138, 168}},
+#line 234 "src/html/html_unescape.gperf"
+ {"Cconint", 3, {226, 136, 176}},
+#line 1622 "src/html/html_unescape.gperf"
+ {"rsquor", 3, {226, 128, 153}},
+ {(char*)0},
+#line 1008 "src/html/html_unescape.gperf"
+ {"lsquor", 3, {226, 128, 154}},
+ {(char*)0},
+#line 2125 "src/html/html_unescape.gperf"
+ {"zigrarr", 3, {226, 135, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 294 "src/html/html_unescape.gperf"
+ {"copf", 4, {240, 157, 149, 148}},
+ {(char*)0},
+#line 293 "src/html/html_unescape.gperf"
+ {"ContourIntegral", 3, {226, 136, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 671 "src/html/html_unescape.gperf"
+ {"hairsp", 3, {226, 128, 138}},
+#line 1729 "src/html/html_unescape.gperf"
+ {"sqsupseteq", 3, {226, 138, 146}},
+#line 307 "src/html/html_unescape.gperf"
+ {"csub", 3, {226, 171, 143}},
+#line 1956 "src/html/html_unescape.gperf"
+ {"upharpoonright", 3, {226, 134, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 427 "src/html/html_unescape.gperf"
+ {"DownBreve", 2, {204, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1675 "src/html/html_unescape.gperf"
+ {"ShortDownArrow", 3, {226, 134, 147}},
+ {(char*)0},
+#line 2076 "src/html/html_unescape.gperf"
+ {"xopf", 4, {240, 157, 149, 169}},
+ {(char*)0},
+#line 1632 "src/html/html_unescape.gperf"
+ {"Sacute", 2, {197, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2040 "src/html/html_unescape.gperf"
+ {"vsupnE", 3, {226, 171, 140}},
+#line 266 "src/html/html_unescape.gperf"
+ {"cir", 3, {226, 151, 139}},
+#line 1415 "src/html/html_unescape.gperf"
+ {"plusacir", 3, {226, 168, 163}},
+#line 309 "src/html/html_unescape.gperf"
+ {"csup", 3, {226, 171, 144}},
+#line 2038 "src/html/html_unescape.gperf"
+ {"vsubnE", 3, {226, 171, 139}},
+#line 1902 "src/html/html_unescape.gperf"
+ {"Uacute", 2, {195, 154}},
+ {(char*)0},
+#line 774 "src/html/html_unescape.gperf"
+ {"isinE", 3, {226, 139, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 607 "src/html/html_unescape.gperf"
+ {"gEl", 3, {226, 170, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1720 "src/html/html_unescape.gperf"
+ {"sqcups", 3, {226, 138, 148}},
+ {(char*)0},
+#line 1702 "src/html/html_unescape.gperf"
+ {"smid", 3, {226, 136, 163}},
+ {(char*)0},
+#line 936 "src/html/html_unescape.gperf"
+ {"lg", 3, {226, 137, 182}},
+ {(char*)0},
+#line 416 "src/html/html_unescape.gperf"
+ {"DoubleLongRightArrow", 3, {226, 159, 185}},
+#line 1209 "src/html/html_unescape.gperf"
+ {"NotPrecedesSlantEqual", 3, {226, 139, 160}},
+ {(char*)0}, {(char*)0},
+#line 478 "src/html/html_unescape.gperf"
+ {"eg", 3, {226, 170, 154}},
+ {(char*)0}, {(char*)0},
+#line 34 "src/html/html_unescape.gperf"
+ {"AMP", 1, {38}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1163 "src/html/html_unescape.gperf"
+ {"nmid", 3, {226, 136, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1863 "src/html/html_unescape.gperf"
+ {"timesd", 3, {226, 168, 176}},
+ {(char*)0}, {(char*)0},
+#line 434 "src/html/html_unescape.gperf"
+ {"DownLeftVector", 3, {226, 134, 189}},
+#line 2131 "src/html/html_unescape.gperf"
+ {"zwnj", 3, {226, 128, 140}},
+#line 819 "src/html/html_unescape.gperf"
+ {"Lacute", 2, {196, 185}},
+#line 433 "src/html/html_unescape.gperf"
+ {"DownLeftVectorBar", 3, {226, 165, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1332 "src/html/html_unescape.gperf"
+ {"ograve", 2, {195, 178}},
+#line 2088 "src/html/html_unescape.gperf"
+ {"Yacute", 2, {195, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1719 "src/html/html_unescape.gperf"
+ {"sqcup", 3, {226, 138, 148}},
+ {(char*)0}, {(char*)0},
+#line 1323 "src/html/html_unescape.gperf"
+ {"odot", 3, {226, 138, 153}},
+#line 213 "src/html/html_unescape.gperf"
+ {"Cacute", 2, {196, 134}},
+ {(char*)0},
+#line 1286 "src/html/html_unescape.gperf"
+ {"nu", 2, {206, 189}},
+#line 1889 "src/html/html_unescape.gperf"
+ {"tritime", 3, {226, 168, 187}},
+ {(char*)0},
+#line 479 "src/html/html_unescape.gperf"
+ {"Egrave", 2, {195, 136}},
+#line 508 "src/html/html_unescape.gperf"
+ {"eplus", 3, {226, 169, 177}},
+ {(char*)0},
+#line 86 "src/html/html_unescape.gperf"
+ {"backcong", 3, {226, 137, 140}},
+ {(char*)0}, {(char*)0},
+#line 1957 "src/html/html_unescape.gperf"
+ {"uplus", 3, {226, 138, 142}},
+ {(char*)0},
+#line 471 "src/html/html_unescape.gperf"
+ {"Edot", 2, {196, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 310 "src/html/html_unescape.gperf"
+ {"csupe", 3, {226, 171, 146}},
+ {(char*)0},
+#line 1690 "src/html/html_unescape.gperf"
+ {"simg", 3, {226, 170, 158}},
+#line 1959 "src/html/html_unescape.gperf"
+ {"UpperRightArrow", 3, {226, 134, 151}},
+#line 308 "src/html/html_unescape.gperf"
+ {"csube", 3, {226, 171, 145}},
+ {(char*)0},
+#line 451 "src/html/html_unescape.gperf"
+ {"dtri", 3, {226, 150, 191}},
+#line 1455 "src/html/html_unescape.gperf"
+ {"prnsim", 3, {226, 139, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 178 "src/html/html_unescape.gperf"
+ {"boxUr", 3, {226, 149, 153}},
+#line 1981 "src/html/html_unescape.gperf"
+ {"uuarr", 3, {226, 135, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 432 "src/html/html_unescape.gperf"
+ {"DownLeftTeeVector", 3, {226, 165, 158}},
+#line 651 "src/html/html_unescape.gperf"
+ {"gsime", 3, {226, 170, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 121 "src/html/html_unescape.gperf"
+ {"bigotimes", 3, {226, 168, 130}},
+#line 342 "src/html/html_unescape.gperf"
+ {"Dagger", 3, {226, 128, 161}},
+ {(char*)0}, {(char*)0},
+#line 755 "src/html/html_unescape.gperf"
+ {"Intersection", 3, {226, 139, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 711 "src/html/html_unescape.gperf"
+ {"iacute", 2, {195, 173}},
+ {(char*)0},
+#line 1435 "src/html/html_unescape.gperf"
+ {"prcue", 3, {226, 137, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 482 "src/html/html_unescape.gperf"
+ {"egsdot", 3, {226, 170, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 743 "src/html/html_unescape.gperf"
+ {"Implies", 3, {226, 135, 146}},
+#line 2011 "src/html/html_unescape.gperf"
+ {"VDash", 3, {226, 138, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 208 "src/html/html_unescape.gperf"
+ {"bump", 3, {226, 137, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1071 "src/html/html_unescape.gperf"
+ {"Mu", 2, {206, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2009 "src/html/html_unescape.gperf"
+ {"vDash", 3, {226, 138, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1028 "src/html/html_unescape.gperf"
+ {"lvnE", 3, {226, 137, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 895 "src/html/html_unescape.gperf"
+ {"LeftTeeArrow", 3, {226, 134, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1076 "src/html/html_unescape.gperf"
+ {"Nacute", 2, {197, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1937 "src/html/html_unescape.gperf"
+ {"UnderBrace", 3, {226, 143, 159}},
+#line 1469 "src/html/html_unescape.gperf"
+ {"Psi", 2, {206, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1560 "src/html/html_unescape.gperf"
+ {"rhov", 2, {207, 177}},
+ {(char*)0},
+#line 913 "src/html/html_unescape.gperf"
+ {"lescc", 3, {226, 170, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1790 "src/html/html_unescape.gperf"
+ {"sup1", 2, {194, 185}},
+ {(char*)0}, {(char*)0},
+#line 1791 "src/html/html_unescape.gperf"
+ {"sup2", 2, {194, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1792 "src/html/html_unescape.gperf"
+ {"sup3", 2, {194, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 119 "src/html/html_unescape.gperf"
+ {"bigodot", 3, {226, 168, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 425 "src/html/html_unescape.gperf"
+ {"Downarrow", 3, {226, 135, 147}},
+ {(char*)0},
+#line 2083 "src/html/html_unescape.gperf"
+ {"xsqcup", 3, {226, 168, 134}},
+ {(char*)0},
+#line 93 "src/html/html_unescape.gperf"
+ {"barvee", 3, {226, 138, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1107 "src/html/html_unescape.gperf"
+ {"NegativeMediumSpace", 3, {226, 128, 139}},
+#line 210 "src/html/html_unescape.gperf"
+ {"bumpe", 3, {226, 137, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 306 "src/html/html_unescape.gperf"
+ {"cscr", 4, {240, 157, 146, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1249 "src/html/html_unescape.gperf"
+ {"nsc", 3, {226, 138, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1793 "src/html/html_unescape.gperf"
+ {"sup", 3, {226, 138, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 239 "src/html/html_unescape.gperf"
+ {"cedil", 2, {194, 184}},
+ {(char*)0}, {(char*)0},
+#line 192 "src/html/html_unescape.gperf"
+ {"boxVr", 3, {226, 149, 159}},
+ {(char*)0},
+#line 1365 "src/html/html_unescape.gperf"
+ {"origof", 3, {226, 138, 182}},
+#line 2130 "src/html/html_unescape.gperf"
+ {"zwj", 3, {226, 128, 141}},
+#line 724 "src/html/html_unescape.gperf"
+ {"Igrave", 2, {195, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 717 "src/html/html_unescape.gperf"
+ {"Idot", 2, {196, 176}},
+ {(char*)0},
+#line 2082 "src/html/html_unescape.gperf"
+ {"xscr", 4, {240, 157, 147, 141}},
+#line 2069 "src/html/html_unescape.gperf"
+ {"xi", 2, {206, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1132 "src/html/html_unescape.gperf"
+ {"nGtv", 3, {226, 137, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 166 "src/html/html_unescape.gperf"
+ {"boxHu", 3, {226, 149, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1853 "src/html/html_unescape.gperf"
+ {"THORN", 2, {195, 158}},
+ {(char*)0},
+#line 1488 "src/html/html_unescape.gperf"
+ {"Racute", 2, {197, 148}},
+ {(char*)0},
+#line 1506 "src/html/html_unescape.gperf"
+ {"rarrhk", 3, {226, 134, 170}},
+ {(char*)0},
+#line 838 "src/html/html_unescape.gperf"
+ {"larrhk", 3, {226, 134, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1628 "src/html/html_unescape.gperf"
+ {"rtriltri", 3, {226, 167, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 181 "src/html/html_unescape.gperf"
+ {"boxV", 3, {226, 149, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 341 "src/html/html_unescape.gperf"
+ {"dagger", 3, {226, 128, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1346 "src/html/html_unescape.gperf"
+ {"Omicron", 2, {206, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 421 "src/html/html_unescape.gperf"
+ {"DoubleVerticalBar", 3, {226, 136, 165}},
+ {(char*)0}, {(char*)0},
+#line 1118 "src/html/html_unescape.gperf"
+ {"nexists", 3, {226, 136, 132}},
+ {(char*)0}, {(char*)0},
+#line 1285 "src/html/html_unescape.gperf"
+ {"Nu", 2, {206, 157}},
+#line 1117 "src/html/html_unescape.gperf"
+ {"nexist", 3, {226, 136, 132}},
+#line 606 "src/html/html_unescape.gperf"
+ {"gE", 3, {226, 137, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 64 "src/html/html_unescape.gperf"
+ {"ap", 3, {226, 137, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1794 "src/html/html_unescape.gperf"
+ {"Sup", 3, {226, 139, 145}},
+#line 402 "src/html/html_unescape.gperf"
+ {"doteqdot", 3, {226, 137, 145}},
+ {(char*)0}, {(char*)0},
+#line 500 "src/html/html_unescape.gperf"
+ {"eng", 2, {197, 139}},
+ {(char*)0},
+#line 225 "src/html/html_unescape.gperf"
+ {"caron", 2, {203, 135}},
+ {(char*)0},
+#line 168 "src/html/html_unescape.gperf"
+ {"boxHU", 3, {226, 149, 169}},
+#line 614 "src/html/html_unescape.gperf"
+ {"gesdot", 3, {226, 170, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1548 "src/html/html_unescape.gperf"
+ {"ReverseEquilibrium", 3, {226, 135, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 175 "src/html/html_unescape.gperf"
+ {"boxUL", 3, {226, 149, 157}},
+ {(char*)0},
+#line 1805 "src/html/html_unescape.gperf"
+ {"supmult", 3, {226, 171, 130}},
+ {(char*)0}, {(char*)0},
+#line 1410 "src/html/html_unescape.gperf"
+ {"pitchfork", 3, {226, 139, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1289 "src/html/html_unescape.gperf"
+ {"numsp", 3, {226, 128, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1492 "src/html/html_unescape.gperf"
+ {"rang", 3, {226, 159, 169}},
+ {(char*)0},
+#line 825 "src/html/html_unescape.gperf"
+ {"lang", 3, {226, 159, 168}},
+ {(char*)0}, {(char*)0},
+#line 1316 "src/html/html_unescape.gperf"
+ {"ocir", 3, {226, 138, 154}},
+ {(char*)0},
+#line 1516 "src/html/html_unescape.gperf"
+ {"rationals", 3, {226, 132, 154}},
+ {(char*)0},
+#line 296 "src/html/html_unescape.gperf"
+ {"coprod", 3, {226, 136, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1019 "src/html/html_unescape.gperf"
+ {"ltlarr", 3, {226, 165, 182}},
+#line 195 "src/html/html_unescape.gperf"
+ {"breve", 2, {203, 152}},
+ {(char*)0},
+#line 1078 "src/html/html_unescape.gperf"
+ {"nang", 3, {226, 136, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1818 "src/html/html_unescape.gperf"
+ {"swarhk", 3, {226, 164, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1497 "src/html/html_unescape.gperf"
+ {"raquo", 2, {194, 187}},
+ {(char*)0},
+#line 831 "src/html/html_unescape.gperf"
+ {"laquo", 2, {194, 171}},
+#line 1816 "src/html/html_unescape.gperf"
+ {"supsub", 3, {226, 171, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 322 "src/html/html_unescape.gperf"
+ {"Cup", 3, {226, 139, 147}},
+#line 66 "src/html/html_unescape.gperf"
+ {"ape", 3, {226, 137, 138}},
+#line 1482 "src/html/html_unescape.gperf"
+ {"quest", 1, {63}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1306 "src/html/html_unescape.gperf"
+ {"nwarhk", 3, {226, 164, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1809 "src/html/html_unescape.gperf"
+ {"supset", 3, {226, 138, 131}},
+ {(char*)0},
+#line 423 "src/html/html_unescape.gperf"
+ {"downarrow", 3, {226, 134, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 453 "src/html/html_unescape.gperf"
+ {"duarr", 3, {226, 135, 181}},
+ {(char*)0},
+#line 68 "src/html/html_unescape.gperf"
+ {"apos", 1, {39}},
+#line 1331 "src/html/html_unescape.gperf"
+ {"Ograve", 2, {195, 146}},
+#line 1678 "src/html/html_unescape.gperf"
+ {"shortparallel", 3, {226, 136, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1269 "src/html/html_unescape.gperf"
+ {"nsucc", 3, {226, 138, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 967 "src/html/html_unescape.gperf"
+ {"LongLeftArrow", 3, {226, 159, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 916 "src/html/html_unescape.gperf"
+ {"lesdoto", 3, {226, 170, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1807 "src/html/html_unescape.gperf"
+ {"supne", 3, {226, 138, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1127 "src/html/html_unescape.gperf"
+ {"nGg", 3, {226, 139, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1491 "src/html/html_unescape.gperf"
+ {"raemptyv", 3, {226, 166, 179}},
+#line 1817 "src/html/html_unescape.gperf"
+ {"supsup", 3, {226, 171, 150}},
+#line 821 "src/html/html_unescape.gperf"
+ {"laemptyv", 3, {226, 166, 180}},
+ {(char*)0}, {(char*)0},
+#line 1871 "src/html/html_unescape.gperf"
+ {"topfork", 3, {226, 171, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 502 "src/html/html_unescape.gperf"
+ {"Eogon", 2, {196, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1594 "src/html/html_unescape.gperf"
+ {"risingdotseq", 3, {226, 137, 147}},
+ {(char*)0},
+#line 212 "src/html/html_unescape.gperf"
+ {"bumpeq", 3, {226, 137, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1010 "src/html/html_unescape.gperf"
+ {"lstrok", 2, {197, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1897 "src/html/html_unescape.gperf"
+ {"Tstrok", 2, {197, 166}},
+#line 650 "src/html/html_unescape.gperf"
+ {"gsim", 3, {226, 137, 179}},
+ {(char*)0}, {(char*)0},
+#line 106 "src/html/html_unescape.gperf"
+ {"bemptyv", 3, {226, 166, 176}},
+#line 2110 "src/html/html_unescape.gperf"
+ {"zacute", 2, {197, 186}},
+#line 652 "src/html/html_unescape.gperf"
+ {"gsiml", 3, {226, 170, 144}},
+ {(char*)0}, {(char*)0},
+#line 1898 "src/html/html_unescape.gperf"
+ {"tstrok", 2, {197, 167}},
+ {(char*)0},
+#line 1601 "src/html/html_unescape.gperf"
+ {"roang", 3, {226, 159, 173}},
+#line 189 "src/html/html_unescape.gperf"
+ {"boxVL", 3, {226, 149, 163}},
+#line 963 "src/html/html_unescape.gperf"
+ {"loang", 3, {226, 159, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1153 "src/html/html_unescape.gperf"
+ {"nleqslant", 3, {226, 169, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1634 "src/html/html_unescape.gperf"
+ {"sbquo", 3, {226, 128, 154}},
+ {(char*)0},
+#line 1657 "src/html/html_unescape.gperf"
+ {"searhk", 3, {226, 164, 165}},
+#line 957 "src/html/html_unescape.gperf"
+ {"lnapprox", 3, {226, 170, 137}},
+ {(char*)0}, {(char*)0},
+#line 1810 "src/html/html_unescape.gperf"
+ {"Supset", 3, {226, 139, 145}},
+ {(char*)0},
+#line 162 "src/html/html_unescape.gperf"
+ {"boxHd", 3, {226, 149, 164}},
+#line 1987 "src/html/html_unescape.gperf"
+ {"varkappa", 2, {207, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 254 "src/html/html_unescape.gperf"
+ {"circeq", 3, {226, 137, 151}},
+ {(char*)0},
+#line 2102 "src/html/html_unescape.gperf"
+ {"yopf", 4, {240, 157, 149, 170}},
+ {(char*)0},
+#line 1941 "src/html/html_unescape.gperf"
+ {"UnionPlus", 3, {226, 138, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 826 "src/html/html_unescape.gperf"
+ {"Lang", 3, {226, 159, 170}},
+#line 1101 "src/html/html_unescape.gperf"
+ {"nearhk", 3, {226, 164, 164}},
+#line 1674 "src/html/html_unescape.gperf"
+ {"shcy", 2, {209, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 245 "src/html/html_unescape.gperf"
+ {"cfr", 4, {240, 157, 148, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 800 "src/html/html_unescape.gperf"
+ {"Kappa", 2, {206, 154}},
+#line 944 "src/html/html_unescape.gperf"
+ {"ljcy", 2, {209, 153}},
+#line 1046 "src/html/html_unescape.gperf"
+ {"MediumSpace", 3, {226, 129, 159}},
+ {(char*)0}, {(char*)0},
+#line 1811 "src/html/html_unescape.gperf"
+ {"supseteq", 3, {226, 138, 135}},
+#line 1812 "src/html/html_unescape.gperf"
+ {"supseteqq", 3, {226, 171, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1545 "src/html/html_unescape.gperf"
+ {"reg", 2, {194, 174}},
+#line 31 "src/html/html_unescape.gperf"
+ {"amacr", 2, {196, 129}},
+#line 909 "src/html/html_unescape.gperf"
+ {"leg", 3, {226, 139, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2050 "src/html/html_unescape.gperf"
+ {"weierp", 3, {226, 132, 152}},
+#line 1893 "src/html/html_unescape.gperf"
+ {"TScy", 2, {208, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1813 "src/html/html_unescape.gperf"
+ {"supsetneq", 3, {226, 138, 139}},
+#line 1141 "src/html/html_unescape.gperf"
+ {"njcy", 2, {209, 154}},
+#line 2065 "src/html/html_unescape.gperf"
+ {"xfr", 4, {240, 157, 148, 181}},
+ {(char*)0},
+#line 1072 "src/html/html_unescape.gperf"
+ {"mu", 2, {206, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1298 "src/html/html_unescape.gperf"
+ {"nvinfin", 3, {226, 167, 158}},
+#line 179 "src/html/html_unescape.gperf"
+ {"boxUR", 3, {226, 149, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2077 "src/html/html_unescape.gperf"
+ {"xoplus", 3, {226, 168, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 887 "src/html/html_unescape.gperf"
+ {"leftleftarrows", 3, {226, 135, 135}},
+#line 1787 "src/html/html_unescape.gperf"
+ {"sum", 3, {226, 136, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 112 "src/html/html_unescape.gperf"
+ {"beth", 3, {226, 132, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 286 "src/html/html_unescape.gperf"
+ {"complement", 3, {226, 136, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1287 "src/html/html_unescape.gperf"
+ {"num", 1, {35}},
+#line 33 "src/html/html_unescape.gperf"
+ {"amp", 1, {38}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 174 "src/html/html_unescape.gperf"
+ {"boxUl", 3, {226, 149, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1177 "src/html/html_unescape.gperf"
+ {"NotGreater", 3, {226, 137, 175}},
+#line 170 "src/html/html_unescape.gperf"
+ {"boxplus", 3, {226, 138, 158}},
+#line 791 "src/html/html_unescape.gperf"
+ {"jmath", 2, {200, 183}},
+ {(char*)0},
+#line 1669 "src/html/html_unescape.gperf"
+ {"sfrown", 3, {226, 140, 162}},
+ {(char*)0},
+#line 448 "src/html/html_unescape.gperf"
+ {"Dstrok", 2, {196, 144}},
+ {(char*)0},
+#line 37 "src/html/html_unescape.gperf"
+ {"and", 3, {226, 136, 167}},
+#line 1180 "src/html/html_unescape.gperf"
+ {"NotGreaterGreater", 3, {226, 137, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1182 "src/html/html_unescape.gperf"
+ {"NotGreaterSlantEqual", 3, {226, 169, 190}},
+ {(char*)0},
+#line 1181 "src/html/html_unescape.gperf"
+ {"NotGreaterLess", 3, {226, 137, 185}},
+#line 1484 "src/html/html_unescape.gperf"
+ {"quot", 1, {34}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1179 "src/html/html_unescape.gperf"
+ {"NotGreaterFullEqual", 3, {226, 137, 167}},
+#line 709 "src/html/html_unescape.gperf"
+ {"hyphen", 3, {226, 128, 144}},
+#line 1412 "src/html/html_unescape.gperf"
+ {"planck", 3, {226, 132, 143}},
+ {(char*)0},
+#line 1857 "src/html/html_unescape.gperf"
+ {"TildeEqual", 3, {226, 137, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1872 "src/html/html_unescape.gperf"
+ {"tosa", 3, {226, 164, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1009 "src/html/html_unescape.gperf"
+ {"Lstrok", 2, {197, 129}},
+ {(char*)0}, {(char*)0},
+#line 1681 "src/html/html_unescape.gperf"
+ {"shy", 2, {194, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2073 "src/html/html_unescape.gperf"
+ {"xnis", 3, {226, 139, 187}},
+#line 762 "src/html/html_unescape.gperf"
+ {"Iogon", 2, {196, 174}},
+ {(char*)0}, {(char*)0},
+#line 456 "src/html/html_unescape.gperf"
+ {"DZcy", 2, {208, 143}},
+ {(char*)0},
+#line 1334 "src/html/html_unescape.gperf"
+ {"ohbar", 3, {226, 166, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 271 "src/html/html_unescape.gperf"
+ {"cirscir", 3, {226, 167, 130}},
+ {(char*)0},
+#line 1666 "src/html/html_unescape.gperf"
+ {"sext", 3, {226, 156, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1387 "src/html/html_unescape.gperf"
+ {"para", 2, {194, 182}},
+ {(char*)0}, {(char*)0},
+#line 77 "src/html/html_unescape.gperf"
+ {"ast", 1, {42}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1483 "src/html/html_unescape.gperf"
+ {"questeq", 3, {226, 137, 159}},
+ {(char*)0},
+#line 1788 "src/html/html_unescape.gperf"
+ {"Sum", 3, {226, 136, 145}},
+ {(char*)0},
+#line 445 "src/html/html_unescape.gperf"
+ {"DScy", 2, {208, 133}},
+ {(char*)0},
+#line 499 "src/html/html_unescape.gperf"
+ {"ENG", 2, {197, 138}},
+ {(char*)0},
+#line 2123 "src/html/html_unescape.gperf"
+ {"ZHcy", 2, {208, 150}},
+ {(char*)0}, {(char*)0},
+#line 966 "src/html/html_unescape.gperf"
+ {"longleftarrow", 3, {226, 159, 181}},
+ {(char*)0},
+#line 347 "src/html/html_unescape.gperf"
+ {"dash", 3, {226, 128, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 438 "src/html/html_unescape.gperf"
+ {"DownTeeArrow", 3, {226, 134, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1814 "src/html/html_unescape.gperf"
+ {"supsetneqq", 3, {226, 171, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1458 "src/html/html_unescape.gperf"
+ {"profalar", 3, {226, 140, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1312 "src/html/html_unescape.gperf"
+ {"oacute", 2, {195, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 193 "src/html/html_unescape.gperf"
+ {"boxVR", 3, {226, 149, 160}},
+ {(char*)0}, {(char*)0},
+#line 459 "src/html/html_unescape.gperf"
+ {"Eacute", 2, {195, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1808 "src/html/html_unescape.gperf"
+ {"supplus", 3, {226, 171, 128}},
+ {(char*)0},
+#line 695 "src/html/html_unescape.gperf"
+ {"hookleftarrow", 3, {226, 134, 169}},
+ {(char*)0}, {(char*)0},
+#line 274 "src/html/html_unescape.gperf"
+ {"CloseCurlyQuote", 3, {226, 128, 153}},
+ {(char*)0}, {(char*)0},
+#line 1888 "src/html/html_unescape.gperf"
+ {"trisb", 3, {226, 167, 141}},
+#line 406 "src/html/html_unescape.gperf"
+ {"dotsquare", 3, {226, 138, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1624 "src/html/html_unescape.gperf"
+ {"rtimes", 3, {226, 139, 138}},
+ {(char*)0},
+#line 1018 "src/html/html_unescape.gperf"
+ {"ltimes", 3, {226, 139, 137}},
+ {(char*)0}, {(char*)0},
+#line 1865 "src/html/html_unescape.gperf"
+ {"toea", 3, {226, 164, 168}},
+#line 24 "src/html/html_unescape.gperf"
+ {"Agrave", 2, {195, 128}},
+ {(char*)0}, {(char*)0},
+#line 76 "src/html/html_unescape.gperf"
+ {"Assign", 3, {226, 137, 148}},
+#line 1493 "src/html/html_unescape.gperf"
+ {"Rang", 3, {226, 159, 171}},
+#line 761 "src/html/html_unescape.gperf"
+ {"iocy", 2, {209, 145}},
+ {(char*)0},
+#line 1208 "src/html/html_unescape.gperf"
+ {"NotPrecedesEqual", 3, {226, 170, 175}},
+ {(char*)0},
+#line 62 "src/html/html_unescape.gperf"
+ {"aopf", 4, {240, 157, 149, 146}},
+ {(char*)0},
+#line 252 "src/html/html_unescape.gperf"
+ {"chi", 2, {207, 135}},
+ {(char*)0}, {(char*)0},
+#line 1480 "src/html/html_unescape.gperf"
+ {"quaternions", 3, {226, 132, 141}},
+#line 188 "src/html/html_unescape.gperf"
+ {"boxVl", 3, {226, 149, 162}},
+#line 1178 "src/html/html_unescape.gperf"
+ {"NotGreaterEqual", 3, {226, 137, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2067 "src/html/html_unescape.gperf"
+ {"xhArr", 3, {226, 159, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1362 "src/html/html_unescape.gperf"
+ {"orderof", 3, {226, 132, 180}},
+ {(char*)0}, {(char*)0},
+#line 1621 "src/html/html_unescape.gperf"
+ {"rsquo", 3, {226, 128, 153}},
+ {(char*)0},
+#line 1007 "src/html/html_unescape.gperf"
+ {"lsquo", 3, {226, 128, 152}},
+#line 2104 "src/html/html_unescape.gperf"
+ {"yscr", 4, {240, 157, 147, 142}},
+ {(char*)0}, {(char*)0},
+#line 604 "src/html/html_unescape.gperf"
+ {"gdot", 2, {196, 161}},
+ {(char*)0},
+#line 1215 "src/html/html_unescape.gperf"
+ {"NotSquareSubsetEqual", 3, {226, 139, 162}},
+#line 810 "src/html/html_unescape.gperf"
+ {"KHcy", 2, {208, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 203 "src/html/html_unescape.gperf"
+ {"bsolb", 3, {226, 167, 133}},
+#line 1214 "src/html/html_unescape.gperf"
+ {"NotSquareSubset", 3, {226, 138, 143}},
+#line 1673 "src/html/html_unescape.gperf"
+ {"SHcy", 2, {208, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2099 "src/html/html_unescape.gperf"
+ {"YIcy", 2, {208, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 339 "src/html/html_unescape.gperf"
+ {"cwint", 3, {226, 136, 177}},
+ {(char*)0}, {(char*)0},
+#line 1842 "src/html/html_unescape.gperf"
+ {"Theta", 2, {206, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1843 "src/html/html_unescape.gperf"
+ {"theta", 2, {206, 184}},
+#line 2071 "src/html/html_unescape.gperf"
+ {"xlArr", 3, {226, 159, 184}},
+ {(char*)0},
+#line 1217 "src/html/html_unescape.gperf"
+ {"NotSquareSupersetEqual", 3, {226, 139, 163}},
+ {(char*)0}, {(char*)0},
+#line 366 "src/html/html_unescape.gperf"
+ {"demptyv", 3, {226, 166, 177}},
+#line 1876 "src/html/html_unescape.gperf"
+ {"triangle", 3, {226, 150, 181}},
+ {(char*)0},
+#line 603 "src/html/html_unescape.gperf"
+ {"Gdot", 2, {196, 160}},
+ {(char*)0},
+#line 1216 "src/html/html_unescape.gperf"
+ {"NotSquareSuperset", 3, {226, 138, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 9 "src/html/html_unescape.gperf"
+ {"Abreve", 2, {196, 130}},
+ {(char*)0}, {(char*)0},
+#line 449 "src/html/html_unescape.gperf"
+ {"dstrok", 2, {196, 145}},
+#line 1400 "src/html/html_unescape.gperf"
+ {"pertenk", 3, {226, 128, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1522 "src/html/html_unescape.gperf"
+ {"rbrack", 1, {93}},
+ {(char*)0},
+#line 852 "src/html/html_unescape.gperf"
+ {"lbrack", 1, {91}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1324 "src/html/html_unescape.gperf"
+ {"odsold", 3, {226, 166, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1348 "src/html/html_unescape.gperf"
+ {"omid", 3, {226, 166, 182}},
+ {(char*)0},
+#line 2080 "src/html/html_unescape.gperf"
+ {"xrArr", 3, {226, 159, 185}},
+ {(char*)0},
+#line 1878 "src/html/html_unescape.gperf"
+ {"triangleleft", 3, {226, 151, 131}},
+#line 1183 "src/html/html_unescape.gperf"
+ {"NotGreaterTilde", 3, {226, 137, 181}},
+#line 280 "src/html/html_unescape.gperf"
+ {"colone", 3, {226, 137, 148}},
+ {(char*)0},
+#line 968 "src/html/html_unescape.gperf"
+ {"Longleftarrow", 3, {226, 159, 184}},
+ {(char*)0},
+#line 767 "src/html/html_unescape.gperf"
+ {"iota", 2, {206, 185}},
+ {(char*)0},
+#line 277 "src/html/html_unescape.gperf"
+ {"colon", 1, {58}},
+#line 2119 "src/html/html_unescape.gperf"
+ {"Zeta", 2, {206, 150}},
+#line 597 "src/html/html_unescape.gperf"
+ {"gbreve", 2, {196, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 247 "src/html/html_unescape.gperf"
+ {"CHcy", 2, {208, 167}},
+ {(char*)0}, {(char*)0},
+#line 2105 "src/html/html_unescape.gperf"
+ {"YUcy", 2, {208, 174}},
+#line 1546 "src/html/html_unescape.gperf"
+ {"REG", 2, {194, 174}},
+#line 1823 "src/html/html_unescape.gperf"
+ {"szlig", 2, {195, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 457 "src/html/html_unescape.gperf"
+ {"dzcy", 2, {209, 159}},
+ {(char*)0},
+#line 111 "src/html/html_unescape.gperf"
+ {"beta", 2, {206, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 539 "src/html/html_unescape.gperf"
+ {"euro", 3, {226, 130, 172}},
+ {(char*)0}, {(char*)0},
+#line 875 "src/html/html_unescape.gperf"
+ {"LeftArrow", 3, {226, 134, 144}},
+ {(char*)0}, {(char*)0},
+#line 222 "src/html/html_unescape.gperf"
+ {"CapitalDifferentialD", 3, {226, 133, 133}},
+ {(char*)0},
+#line 1593 "src/html/html_unescape.gperf"
+ {"ring", 2, {203, 154}},
+#line 830 "src/html/html_unescape.gperf"
+ {"Laplacetrf", 3, {226, 132, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 392 "src/html/html_unescape.gperf"
+ {"djcy", 2, {209, 146}},
+ {(char*)0},
+#line 1356 "src/html/html_unescape.gperf"
+ {"oplus", 3, {226, 138, 149}},
+ {(char*)0}, {(char*)0},
+#line 752 "src/html/html_unescape.gperf"
+ {"integers", 3, {226, 132, 164}},
+#line 596 "src/html/html_unescape.gperf"
+ {"Gbreve", 2, {196, 158}},
+ {(char*)0},
+#line 1909 "src/html/html_unescape.gperf"
+ {"ubrcy", 2, {209, 158}},
+#line 538 "src/html/html_unescape.gperf"
+ {"euml", 2, {195, 171}},
+ {(char*)0}, {(char*)0},
+#line 362 "src/html/html_unescape.gperf"
+ {"deg", 2, {194, 176}},
+ {(char*)0},
+#line 1983 "src/html/html_unescape.gperf"
+ {"uuml", 2, {195, 188}},
+ {(char*)0}, {(char*)0},
+#line 710 "src/html/html_unescape.gperf"
+ {"Iacute", 2, {195, 141}},
+#line 1781 "src/html/html_unescape.gperf"
+ {"succeq", 3, {226, 170, 176}},
+ {(char*)0},
+#line 812 "src/html/html_unescape.gperf"
+ {"KJcy", 2, {208, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 320 "src/html/html_unescape.gperf"
+ {"CupCap", 3, {226, 137, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1894 "src/html/html_unescape.gperf"
+ {"tscy", 2, {209, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 242 "src/html/html_unescape.gperf"
+ {"cent", 2, {194, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 391 "src/html/html_unescape.gperf"
+ {"DJcy", 2, {208, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1858 "src/html/html_unescape.gperf"
+ {"TildeFullEqual", 3, {226, 137, 133}},
+ {(char*)0},
+#line 1880 "src/html/html_unescape.gperf"
+ {"triangleq", 3, {226, 137, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 454 "src/html/html_unescape.gperf"
+ {"duhar", 3, {226, 165, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 880 "src/html/html_unescape.gperf"
+ {"LeftDoubleBracket", 3, {226, 159, 166}},
+ {(char*)0},
+#line 943 "src/html/html_unescape.gperf"
+ {"LJcy", 2, {208, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 719 "src/html/html_unescape.gperf"
+ {"iecy", 2, {208, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1879 "src/html/html_unescape.gperf"
+ {"trianglelefteq", 3, {226, 138, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1111 "src/html/html_unescape.gperf"
+ {"nequiv", 3, {226, 137, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1255 "src/html/html_unescape.gperf"
+ {"nshortparallel", 3, {226, 136, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1100 "src/html/html_unescape.gperf"
+ {"ndash", 3, {226, 128, 147}},
+#line 149 "src/html/html_unescape.gperf"
+ {"bowtie", 3, {226, 139, 136}},
+ {(char*)0},
+#line 558 "src/html/html_unescape.gperf"
+ {"fjlig", 1, {102}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1908 "src/html/html_unescape.gperf"
+ {"Ubrcy", 2, {208, 142}},
+ {(char*)0},
+#line 2000 "src/html/html_unescape.gperf"
+ {"vartheta", 2, {207, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1982 "src/html/html_unescape.gperf"
+ {"Uuml", 2, {195, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2002 "src/html/html_unescape.gperf"
+ {"vartriangleright", 3, {226, 138, 179}},
+#line 2001 "src/html/html_unescape.gperf"
+ {"vartriangleleft", 3, {226, 138, 178}},
+#line 75 "src/html/html_unescape.gperf"
+ {"ascr", 4, {240, 157, 146, 182}},
+ {(char*)0}, {(char*)0},
+#line 1776 "src/html/html_unescape.gperf"
+ {"succcurlyeq", 3, {226, 137, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 338 "src/html/html_unescape.gperf"
+ {"cwconint", 3, {226, 136, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1639 "src/html/html_unescape.gperf"
+ {"sc", 3, {226, 137, 187}},
+ {(char*)0},
+#line 560 "src/html/html_unescape.gperf"
+ {"fllig", 3, {239, 172, 130}},
+ {(char*)0},
+#line 257 "src/html/html_unescape.gperf"
+ {"circledast", 3, {226, 138, 155}},
+ {(char*)0}, {(char*)0},
+#line 2010 "src/html/html_unescape.gperf"
+ {"Vdash", 3, {226, 138, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1293 "src/html/html_unescape.gperf"
+ {"nVdash", 3, {226, 138, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1804 "src/html/html_unescape.gperf"
+ {"suplarr", 3, {226, 165, 187}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1603 "src/html/html_unescape.gperf"
+ {"robrk", 3, {226, 159, 167}},
+ {(char*)0},
+#line 965 "src/html/html_unescape.gperf"
+ {"lobrk", 3, {226, 159, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2008 "src/html/html_unescape.gperf"
+ {"vdash", 3, {226, 138, 162}},
+#line 2108 "src/html/html_unescape.gperf"
+ {"Yuml", 2, {197, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 655 "src/html/html_unescape.gperf"
+ {"gt", 1, {62}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 227 "src/html/html_unescape.gperf"
+ {"ccaps", 3, {226, 169, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1777 "src/html/html_unescape.gperf"
+ {"Succeeds", 3, {226, 137, 187}},
+#line 1311 "src/html/html_unescape.gperf"
+ {"Oacute", 2, {195, 147}},
+#line 1875 "src/html/html_unescape.gperf"
+ {"TRADE", 3, {226, 132, 162}},
+#line 1140 "src/html/html_unescape.gperf"
+ {"NJcy", 2, {208, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 658 "src/html/html_unescape.gperf"
+ {"gtdot", 3, {226, 139, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2098 "src/html/html_unescape.gperf"
+ {"yfr", 4, {240, 157, 148, 182}},
+ {(char*)0}, {(char*)0},
+#line 285 "src/html/html_unescape.gperf"
+ {"compfn", 3, {226, 136, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 657 "src/html/html_unescape.gperf"
+ {"Gt", 3, {226, 137, 171}},
+#line 1648 "src/html/html_unescape.gperf"
+ {"scnE", 3, {226, 170, 182}},
+#line 732 "src/html/html_unescape.gperf"
+ {"ijlig", 2, {196, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 262 "src/html/html_unescape.gperf"
+ {"circledS", 3, {226, 147, 136}},
+ {(char*)0}, {(char*)0},
+#line 2096 "src/html/html_unescape.gperf"
+ {"yen", 2, {194, 165}},
+ {(char*)0},
+#line 1844 "src/html/html_unescape.gperf"
+ {"thetasym", 2, {207, 145}},
+ {(char*)0}, {(char*)0},
+#line 784 "src/html/html_unescape.gperf"
+ {"iuml", 2, {195, 175}},
+#line 1779 "src/html/html_unescape.gperf"
+ {"SucceedsSlantEqual", 3, {226, 137, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 160 "src/html/html_unescape.gperf"
+ {"boxH", 3, {226, 149, 144}},
+#line 1074 "src/html/html_unescape.gperf"
+ {"mumap", 3, {226, 138, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1578 "src/html/html_unescape.gperf"
+ {"rightrightarrows", 3, {226, 135, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 281 "src/html/html_unescape.gperf"
+ {"coloneq", 3, {226, 137, 148}},
+ {(char*)0},
+#line 1638 "src/html/html_unescape.gperf"
+ {"Sc", 3, {226, 170, 188}},
+#line 630 "src/html/html_unescape.gperf"
+ {"glj", 3, {226, 170, 164}},
+#line 720 "src/html/html_unescape.gperf"
+ {"iexcl", 2, {194, 161}},
+ {(char*)0}, {(char*)0},
+#line 235 "src/html/html_unescape.gperf"
+ {"ccups", 3, {226, 169, 140}},
+ {(char*)0},
+#line 2060 "src/html/html_unescape.gperf"
+ {"xcap", 3, {226, 139, 130}},
+#line 2124 "src/html/html_unescape.gperf"
+ {"zhcy", 2, {208, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 164 "src/html/html_unescape.gperf"
+ {"boxHD", 3, {226, 149, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 912 "src/html/html_unescape.gperf"
+ {"leqslant", 3, {226, 169, 189}},
+ {(char*)0},
+#line 1958 "src/html/html_unescape.gperf"
+ {"UpperLeftArrow", 3, {226, 134, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 351 "src/html/html_unescape.gperf"
+ {"dblac", 2, {203, 157}},
+ {(char*)0}, {(char*)0},
+#line 1471 "src/html/html_unescape.gperf"
+ {"puncsp", 3, {226, 128, 136}},
+ {(char*)0},
+#line 229 "src/html/html_unescape.gperf"
+ {"ccaron", 2, {196, 141}},
+ {(char*)0},
+#line 1520 "src/html/html_unescape.gperf"
+ {"rbbrk", 3, {226, 157, 179}},
+ {(char*)0},
+#line 850 "src/html/html_unescape.gperf"
+ {"lbbrk", 3, {226, 157, 178}},
+ {(char*)0},
+#line 59 "src/html/html_unescape.gperf"
+ {"Aogon", 2, {196, 132}},
+#line 899 "src/html/html_unescape.gperf"
+ {"LeftTriangleBar", 3, {226, 167, 143}},
+ {(char*)0}, {(char*)0},
+#line 616 "src/html/html_unescape.gperf"
+ {"gesdotol", 3, {226, 170, 132}},
+#line 901 "src/html/html_unescape.gperf"
+ {"LeftTriangleEqual", 3, {226, 138, 180}},
+#line 900 "src/html/html_unescape.gperf"
+ {"LeftTriangle", 3, {226, 138, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 291 "src/html/html_unescape.gperf"
+ {"conint", 3, {226, 136, 174}},
+ {(char*)0}, {(char*)0},
+#line 440 "src/html/html_unescape.gperf"
+ {"drbkarow", 3, {226, 164, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1627 "src/html/html_unescape.gperf"
+ {"rtrif", 3, {226, 150, 184}},
+ {(char*)0},
+#line 1023 "src/html/html_unescape.gperf"
+ {"ltrif", 3, {226, 151, 130}},
+ {(char*)0}, {(char*)0},
+#line 1549 "src/html/html_unescape.gperf"
+ {"ReverseUpEquilibrium", 3, {226, 165, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 879 "src/html/html_unescape.gperf"
+ {"LeftCeiling", 3, {226, 140, 136}},
+ {(char*)0},
+#line 1980 "src/html/html_unescape.gperf"
+ {"utrif", 3, {226, 150, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2062 "src/html/html_unescape.gperf"
+ {"xcup", 3, {226, 139, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 546 "src/html/html_unescape.gperf"
+ {"fallingdotseq", 3, {226, 137, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1529 "src/html/html_unescape.gperf"
+ {"rcedil", 2, {197, 151}},
+ {(char*)0},
+#line 859 "src/html/html_unescape.gperf"
+ {"lcedil", 2, {196, 188}},
+ {(char*)0},
+#line 1644 "src/html/html_unescape.gperf"
+ {"scedil", 2, {197, 159}},
+ {(char*)0},
+#line 1831 "src/html/html_unescape.gperf"
+ {"Tcedil", 2, {197, 162}},
+ {(char*)0},
+#line 1749 "src/html/html_unescape.gperf"
+ {"starf", 3, {226, 152, 133}},
+#line 169 "src/html/html_unescape.gperf"
+ {"boxminus", 3, {226, 138, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1832 "src/html/html_unescape.gperf"
+ {"tcedil", 2, {197, 163}},
+#line 2118 "src/html/html_unescape.gperf"
+ {"ZeroWidthSpace", 3, {226, 128, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1094 "src/html/html_unescape.gperf"
+ {"ncedil", 2, {197, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1405 "src/html/html_unescape.gperf"
+ {"phiv", 2, {207, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 712 "src/html/html_unescape.gperf"
+ {"ic", 3, {226, 129, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 221 "src/html/html_unescape.gperf"
+ {"capdot", 3, {226, 169, 128}},
+ {(char*)0}, {(char*)0},
+#line 446 "src/html/html_unescape.gperf"
+ {"dscy", 2, {209, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 249 "src/html/html_unescape.gperf"
+ {"check", 3, {226, 156, 147}},
+#line 1382 "src/html/html_unescape.gperf"
+ {"ovbar", 3, {226, 140, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1281 "src/html/html_unescape.gperf"
+ {"ntriangleleft", 3, {226, 139, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1581 "src/html/html_unescape.gperf"
+ {"RightTee", 3, {226, 138, 162}},
+#line 1295 "src/html/html_unescape.gperf"
+ {"nvge", 3, {226, 137, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 893 "src/html/html_unescape.gperf"
+ {"leftrightsquigarrow", 3, {226, 134, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 988 "src/html/html_unescape.gperf"
+ {"lozenge", 3, {226, 151, 138}},
+ {(char*)0}, {(char*)0},
+#line 1584 "src/html/html_unescape.gperf"
+ {"RightTriangleBar", 3, {226, 167, 144}},
+ {(char*)0},
+#line 1582 "src/html/html_unescape.gperf"
+ {"RightTeeVector", 3, {226, 165, 155}},
+ {(char*)0},
+#line 1586 "src/html/html_unescape.gperf"
+ {"RightTriangleEqual", 3, {226, 138, 181}},
+#line 1585 "src/html/html_unescape.gperf"
+ {"RightTriangle", 3, {226, 138, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 803 "src/html/html_unescape.gperf"
+ {"Kcedil", 2, {196, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1643 "src/html/html_unescape.gperf"
+ {"Scedil", 2, {197, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 269 "src/html/html_unescape.gperf"
+ {"cirfnint", 3, {226, 168, 144}},
+ {(char*)0}, {(char*)0},
+#line 491 "src/html/html_unescape.gperf"
+ {"empty", 3, {226, 136, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 23 "src/html/html_unescape.gperf"
+ {"afr", 4, {240, 157, 148, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 377 "src/html/html_unescape.gperf"
+ {"DiacriticalTilde", 2, {203, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 883 "src/html/html_unescape.gperf"
+ {"LeftDownVector", 3, {226, 135, 131}},
+ {(char*)0}, {(char*)0},
+#line 882 "src/html/html_unescape.gperf"
+ {"LeftDownVectorBar", 3, {226, 165, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 908 "src/html/html_unescape.gperf"
+ {"lEg", 3, {226, 170, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 69 "src/html/html_unescape.gperf"
+ {"ApplyFunction", 3, {226, 129, 161}},
+ {(char*)0}, {(char*)0},
+#line 209 "src/html/html_unescape.gperf"
+ {"bumpE", 3, {226, 170, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 858 "src/html/html_unescape.gperf"
+ {"Lcedil", 2, {196, 187}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 224 "src/html/html_unescape.gperf"
+ {"caret", 3, {226, 129, 129}},
+ {(char*)0},
+#line 92 "src/html/html_unescape.gperf"
+ {"Barv", 3, {226, 171, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 230 "src/html/html_unescape.gperf"
+ {"Ccedil", 2, {195, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 261 "src/html/html_unescape.gperf"
+ {"circledR", 2, {194, 174}},
+#line 881 "src/html/html_unescape.gperf"
+ {"LeftDownTeeVector", 3, {226, 165, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1896 "src/html/html_unescape.gperf"
+ {"tshcy", 2, {209, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 403 "src/html/html_unescape.gperf"
+ {"DotEqual", 3, {226, 137, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 243 "src/html/html_unescape.gperf"
+ {"centerdot", 2, {194, 183}},
+ {(char*)0},
+#line 1282 "src/html/html_unescape.gperf"
+ {"ntrianglelefteq", 3, {226, 139, 172}},
+ {(char*)0},
+#line 1057 "src/html/html_unescape.gperf"
+ {"minus", 3, {226, 136, 146}},
+ {(char*)0},
+#line 624 "src/html/html_unescape.gperf"
+ {"gimel", 3, {226, 132, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 7 "src/html/html_unescape.gperf"
+ {"Aacute", 2, {195, 129}},
+#line 654 "src/html/html_unescape.gperf"
+ {"gtcir", 3, {226, 169, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 662 "src/html/html_unescape.gperf"
+ {"gtrarr", 3, {226, 165, 184}},
+#line 206 "src/html/html_unescape.gperf"
+ {"bull", 3, {226, 128, 162}},
+ {(char*)0}, {(char*)0},
+#line 424 "src/html/html_unescape.gperf"
+ {"DownArrow", 3, {226, 134, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1537 "src/html/html_unescape.gperf"
+ {"rdquor", 3, {226, 128, 157}},
+ {(char*)0},
+#line 866 "src/html/html_unescape.gperf"
+ {"ldquor", 3, {226, 128, 158}},
+ {(char*)0}, {(char*)0},
+#line 756 "src/html/html_unescape.gperf"
+ {"intlarhk", 3, {226, 168, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1978 "src/html/html_unescape.gperf"
+ {"utilde", 2, {197, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 590 "src/html/html_unescape.gperf"
+ {"gacute", 2, {199, 181}},
+ {(char*)0},
+#line 1279 "src/html/html_unescape.gperf"
+ {"ntilde", 2, {195, 177}},
+#line 21 "src/html/html_unescape.gperf"
+ {"af", 3, {226, 129, 161}},
+ {(char*)0}, {(char*)0},
+#line 704 "src/html/html_unescape.gperf"
+ {"Hstrok", 2, {196, 166}},
+ {(char*)0},
+#line 544 "src/html/html_unescape.gperf"
+ {"exponentiale", 3, {226, 133, 135}},
+#line 1056 "src/html/html_unescape.gperf"
+ {"minusb", 3, {226, 138, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1588 "src/html/html_unescape.gperf"
+ {"RightUpTeeVector", 3, {226, 165, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1965 "src/html/html_unescape.gperf"
+ {"UpTeeArrow", 3, {226, 134, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2120 "src/html/html_unescape.gperf"
+ {"zeta", 2, {206, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 374 "src/html/html_unescape.gperf"
+ {"DiacriticalDot", 2, {203, 153}},
+#line 375 "src/html/html_unescape.gperf"
+ {"DiacriticalDoubleAcute", 2, {203, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1147 "src/html/html_unescape.gperf"
+ {"nleftarrow", 3, {226, 134, 154}},
+#line 692 "src/html/html_unescape.gperf"
+ {"hkswarow", 3, {226, 164, 166}},
+ {(char*)0},
+#line 730 "src/html/html_unescape.gperf"
+ {"iiota", 3, {226, 132, 169}},
+ {(char*)0}, {(char*)0},
+#line 63 "src/html/html_unescape.gperf"
+ {"apacir", 3, {226, 169, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1093 "src/html/html_unescape.gperf"
+ {"Ncedil", 2, {197, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 215 "src/html/html_unescape.gperf"
+ {"capand", 3, {226, 169, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1043 "src/html/html_unescape.gperf"
+ {"mdash", 3, {226, 128, 148}},
+ {(char*)0}, {(char*)0},
+#line 555 "src/html/html_unescape.gperf"
+ {"filig", 3, {239, 172, 129}},
+#line 1649 "src/html/html_unescape.gperf"
+ {"scnsim", 3, {226, 139, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1541 "src/html/html_unescape.gperf"
+ {"realpart", 3, {226, 132, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 898 "src/html/html_unescape.gperf"
+ {"leftthreetimes", 3, {226, 139, 139}},
+#line 78 "src/html/html_unescape.gperf"
+ {"asymp", 3, {226, 137, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 686 "src/html/html_unescape.gperf"
+ {"hellip", 3, {226, 128, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 452 "src/html/html_unescape.gperf"
+ {"dtrif", 3, {226, 150, 190}},
+ {(char*)0},
+#line 1176 "src/html/html_unescape.gperf"
+ {"NotExists", 3, {226, 136, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1640 "src/html/html_unescape.gperf"
+ {"sccue", 3, {226, 137, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2090 "src/html/html_unescape.gperf"
+ {"YAcy", 2, {208, 175}},
+#line 1977 "src/html/html_unescape.gperf"
+ {"Utilde", 2, {197, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1174 "src/html/html_unescape.gperf"
+ {"NotEqual", 3, {226, 137, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1849 "src/html/html_unescape.gperf"
+ {"ThinSpace", 3, {226, 128, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 65 "src/html/html_unescape.gperf"
+ {"apE", 3, {226, 169, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 207 "src/html/html_unescape.gperf"
+ {"bullet", 3, {226, 128, 162}},
+ {(char*)0}, {(char*)0},
+#line 273 "src/html/html_unescape.gperf"
+ {"CloseCurlyDoubleQuote", 3, {226, 128, 157}},
+#line 364 "src/html/html_unescape.gperf"
+ {"Delta", 2, {206, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 621 "src/html/html_unescape.gperf"
+ {"gg", 3, {226, 137, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1379 "src/html/html_unescape.gperf"
+ {"otimes", 3, {226, 138, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2057 "src/html/html_unescape.gperf"
+ {"wreath", 3, {226, 137, 128}},
+ {(char*)0},
+#line 1528 "src/html/html_unescape.gperf"
+ {"Rcedil", 2, {197, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 536 "src/html/html_unescape.gperf"
+ {"eth", 2, {195, 176}},
+#line 1806 "src/html/html_unescape.gperf"
+ {"supnE", 3, {226, 171, 140}},
+ {(char*)0}, {(char*)0},
+#line 85 "src/html/html_unescape.gperf"
+ {"awint", 3, {226, 168, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 196 "src/html/html_unescape.gperf"
+ {"Breve", 2, {203, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 622 "src/html/html_unescape.gperf"
+ {"Gg", 3, {226, 139, 153}},
+ {(char*)0},
+#line 707 "src/html/html_unescape.gperf"
+ {"HumpEqual", 3, {226, 137, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 949 "src/html/html_unescape.gperf"
+ {"Lleftarrow", 3, {226, 135, 154}},
+#line 155 "src/html/html_unescape.gperf"
+ {"boxdr", 3, {226, 148, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1783 "src/html/html_unescape.gperf"
+ {"succneqq", 3, {226, 170, 182}},
+#line 1972 "src/html/html_unescape.gperf"
+ {"uring", 2, {197, 175}},
+#line 930 "src/html/html_unescape.gperf"
+ {"LessSlantEqual", 3, {226, 169, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1291 "src/html/html_unescape.gperf"
+ {"nvdash", 3, {226, 138, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 670 "src/html/html_unescape.gperf"
+ {"Hacek", 2, {203, 135}},
+#line 780 "src/html/html_unescape.gperf"
+ {"itilde", 2, {196, 169}},
+ {(char*)0}, {(char*)0},
+#line 766 "src/html/html_unescape.gperf"
+ {"Iota", 2, {206, 153}},
+ {(char*)0},
+#line 760 "src/html/html_unescape.gperf"
+ {"IOcy", 2, {208, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 157 "src/html/html_unescape.gperf"
+ {"boxDr", 3, {226, 149, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1780 "src/html/html_unescape.gperf"
+ {"SucceedsTilde", 3, {226, 137, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 884 "src/html/html_unescape.gperf"
+ {"LeftFloor", 3, {226, 140, 138}},
+#line 2042 "src/html/html_unescape.gperf"
+ {"Vvdash", 3, {226, 138, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1877 "src/html/html_unescape.gperf"
+ {"triangledown", 3, {226, 150, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 970 "src/html/html_unescape.gperf"
+ {"LongLeftRightArrow", 3, {226, 159, 183}},
+#line 1573 "src/html/html_unescape.gperf"
+ {"RightFloor", 3, {226, 140, 139}},
+ {(char*)0}, {(char*)0},
+#line 435 "src/html/html_unescape.gperf"
+ {"DownRightTeeVector", 3, {226, 165, 159}},
+ {(char*)0},
+#line 1481 "src/html/html_unescape.gperf"
+ {"quatint", 3, {226, 168, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1278 "src/html/html_unescape.gperf"
+ {"Ntilde", 2, {195, 145}},
+ {(char*)0}, {(char*)0},
+#line 211 "src/html/html_unescape.gperf"
+ {"Bumpeq", 3, {226, 137, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 669 "src/html/html_unescape.gperf"
+ {"gvnE", 3, {226, 137, 169}},
+ {(char*)0},
+#line 165 "src/html/html_unescape.gperf"
+ {"boxhu", 3, {226, 148, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 659 "src/html/html_unescape.gperf"
+ {"gtlPar", 3, {226, 166, 149}},
+ {(char*)0}, {(char*)0},
+#line 1238 "src/html/html_unescape.gperf"
+ {"nprec", 3, {226, 138, 128}},
+ {(char*)0}, {(char*)0},
+#line 1381 "src/html/html_unescape.gperf"
+ {"ouml", 2, {195, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 612 "src/html/html_unescape.gperf"
+ {"gescc", 3, {226, 170, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 537 "src/html/html_unescape.gperf"
+ {"Euml", 2, {195, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1971 "src/html/html_unescape.gperf"
+ {"Uring", 2, {197, 174}},
+ {(char*)0},
+#line 1938 "src/html/html_unescape.gperf"
+ {"UnderBracket", 3, {226, 142, 181}},
+#line 1162 "src/html/html_unescape.gperf"
+ {"nLtv", 3, {226, 137, 170}},
+#line 873 "src/html/html_unescape.gperf"
+ {"LeftArrowBar", 3, {226, 135, 164}},
+#line 1096 "src/html/html_unescape.gperf"
+ {"ncongdot", 3, {226, 169, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 79 "src/html/html_unescape.gperf"
+ {"asympeq", 3, {226, 137, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1059 "src/html/html_unescape.gperf"
+ {"minusdu", 3, {226, 168, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 365 "src/html/html_unescape.gperf"
+ {"delta", 2, {206, 180}},
+ {(char*)0},
+#line 679 "src/html/html_unescape.gperf"
+ {"harrw", 3, {226, 134, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 39 "src/html/html_unescape.gperf"
+ {"andslope", 3, {226, 169, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 238 "src/html/html_unescape.gperf"
+ {"cdot", 2, {196, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 226 "src/html/html_unescape.gperf"
+ {"Cayleys", 3, {226, 132, 173}},
+#line 167 "src/html/html_unescape.gperf"
+ {"boxhU", 3, {226, 149, 168}},
+ {(char*)0}, {(char*)0},
+#line 1785 "src/html/html_unescape.gperf"
+ {"succsim", 3, {226, 137, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 267 "src/html/html_unescape.gperf"
+ {"cirE", 3, {226, 167, 131}},
+#line 1654 "src/html/html_unescape.gperf"
+ {"sdotb", 3, {226, 138, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1319 "src/html/html_unescape.gperf"
+ {"odash", 3, {226, 138, 157}},
+#line 270 "src/html/html_unescape.gperf"
+ {"cirmid", 3, {226, 171, 175}},
+#line 1803 "src/html/html_unescape.gperf"
+ {"suphsub", 3, {226, 171, 151}},
+#line 1796 "src/html/html_unescape.gperf"
+ {"supdsub", 3, {226, 171, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1795 "src/html/html_unescape.gperf"
+ {"supdot", 3, {226, 170, 190}},
+ {(char*)0},
+#line 84 "src/html/html_unescape.gperf"
+ {"awconint", 3, {226, 136, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1895 "src/html/html_unescape.gperf"
+ {"TSHcy", 2, {208, 139}},
+ {(char*)0}, {(char*)0},
+#line 640 "src/html/html_unescape.gperf"
+ {"grave", 1, {96}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1005 "src/html/html_unescape.gperf"
+ {"lsimg", 3, {226, 170, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1950 "src/html/html_unescape.gperf"
+ {"UpArrowDownArrow", 3, {226, 135, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 907 "src/html/html_unescape.gperf"
+ {"LeftVector", 3, {226, 134, 188}},
+#line 417 "src/html/html_unescape.gperf"
+ {"DoubleRightArrow", 3, {226, 135, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1109 "src/html/html_unescape.gperf"
+ {"NegativeThinSpace", 3, {226, 128, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 942 "src/html/html_unescape.gperf"
+ {"lhblk", 3, {226, 150, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 268 "src/html/html_unescape.gperf"
+ {"cire", 3, {226, 137, 151}},
+#line 1294 "src/html/html_unescape.gperf"
+ {"nVDash", 3, {226, 138, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1928 "src/html/html_unescape.gperf"
+ {"uhblk", 3, {226, 150, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 738 "src/html/html_unescape.gperf"
+ {"imagpart", 3, {226, 132, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1587 "src/html/html_unescape.gperf"
+ {"RightUpDownVector", 3, {226, 165, 143}},
+ {(char*)0}, {(char*)0},
+#line 152 "src/html/html_unescape.gperf"
+ {"boxdL", 3, {226, 149, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 627 "src/html/html_unescape.gperf"
+ {"gla", 3, {226, 170, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 783 "src/html/html_unescape.gperf"
+ {"Iuml", 2, {195, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1326 "src/html/html_unescape.gperf"
+ {"oelig", 2, {197, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1199 "src/html/html_unescape.gperf"
+ {"NotLessSlantEqual", 3, {226, 169, 189}},
+ {(char*)0},
+#line 154 "src/html/html_unescape.gperf"
+ {"boxDL", 3, {226, 149, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 592 "src/html/html_unescape.gperf"
+ {"gamma", 2, {206, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1378 "src/html/html_unescape.gperf"
+ {"Otimes", 3, {226, 168, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 969 "src/html/html_unescape.gperf"
+ {"longleftrightarrow", 3, {226, 159, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 591 "src/html/html_unescape.gperf"
+ {"Gamma", 2, {206, 147}},
+#line 128 "src/html/html_unescape.gperf"
+ {"bigwedge", 3, {226, 139, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 161 "src/html/html_unescape.gperf"
+ {"boxhd", 3, {226, 148, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1797 "src/html/html_unescape.gperf"
+ {"supE", 3, {226, 171, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 903 "src/html/html_unescape.gperf"
+ {"LeftUpTeeVector", 3, {226, 165, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 615 "src/html/html_unescape.gperf"
+ {"gesdoto", 3, {226, 170, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 801 "src/html/html_unescape.gperf"
+ {"kappa", 2, {206, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1125 "src/html/html_unescape.gperf"
+ {"ngeqslant", 3, {226, 169, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 666 "src/html/html_unescape.gperf"
+ {"gtrless", 3, {226, 137, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 551 "src/html/html_unescape.gperf"
+ {"fflig", 3, {239, 172, 128}},
+#line 122 "src/html/html_unescape.gperf"
+ {"bigsqcup", 3, {226, 168, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 809 "src/html/html_unescape.gperf"
+ {"kgreen", 2, {196, 184}},
+#line 1798 "src/html/html_unescape.gperf"
+ {"supe", 3, {226, 138, 135}},
+ {(char*)0},
+#line 171 "src/html/html_unescape.gperf"
+ {"boxtimes", 3, {226, 138, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 632 "src/html/html_unescape.gperf"
+ {"gnapprox", 3, {226, 170, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 428 "src/html/html_unescape.gperf"
+ {"downdownarrows", 3, {226, 135, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 126 "src/html/html_unescape.gperf"
+ {"biguplus", 3, {226, 168, 132}},
+#line 811 "src/html/html_unescape.gperf"
+ {"khcy", 2, {209, 133}},
+ {(char*)0},
+#line 356 "src/html/html_unescape.gperf"
+ {"ddagger", 3, {226, 128, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1380 "src/html/html_unescape.gperf"
+ {"Ouml", 2, {195, 150}},
+ {(char*)0},
+#line 110 "src/html/html_unescape.gperf"
+ {"Beta", 2, {206, 146}},
+#line 1058 "src/html/html_unescape.gperf"
+ {"minusd", 3, {226, 136, 184}},
+#line 1784 "src/html/html_unescape.gperf"
+ {"succnsim", 3, {226, 139, 169}},
+ {(char*)0},
+#line 311 "src/html/html_unescape.gperf"
+ {"ctdot", 3, {226, 139, 175}},
+ {(char*)0}, {(char*)0},
+#line 813 "src/html/html_unescape.gperf"
+ {"kjcy", 2, {209, 156}},
+#line 626 "src/html/html_unescape.gperf"
+ {"gjcy", 2, {209, 147}},
+ {(char*)0},
+#line 1095 "src/html/html_unescape.gperf"
+ {"ncong", 3, {226, 137, 135}},
+#line 2086 "src/html/html_unescape.gperf"
+ {"xvee", 3, {226, 139, 129}},
+#line 99 "src/html/html_unescape.gperf"
+ {"bcong", 3, {226, 137, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1723 "src/html/html_unescape.gperf"
+ {"sqsube", 3, {226, 138, 145}},
+ {(char*)0}, {(char*)0},
+#line 156 "src/html/html_unescape.gperf"
+ {"boxdR", 3, {226, 149, 146}},
+ {(char*)0}, {(char*)0},
+#line 971 "src/html/html_unescape.gperf"
+ {"Longleftrightarrow", 3, {226, 159, 186}},
+ {(char*)0},
+#line 1722 "src/html/html_unescape.gperf"
+ {"sqsub", 3, {226, 138, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 431 "src/html/html_unescape.gperf"
+ {"DownLeftRightVector", 3, {226, 165, 144}},
+ {(char*)0}, {(char*)0},
+#line 1724 "src/html/html_unescape.gperf"
+ {"sqsubset", 3, {226, 138, 143}},
+ {(char*)0},
+#line 1230 "src/html/html_unescape.gperf"
+ {"NotVerticalBar", 3, {226, 136, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1175 "src/html/html_unescape.gperf"
+ {"NotEqualTilde", 3, {226, 137, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 151 "src/html/html_unescape.gperf"
+ {"boxdl", 3, {226, 148, 144}},
+ {(char*)0}, {(char*)0},
+#line 158 "src/html/html_unescape.gperf"
+ {"boxDR", 3, {226, 149, 148}},
+ {(char*)0},
+#line 35 "src/html/html_unescape.gperf"
+ {"andand", 3, {226, 169, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1592 "src/html/html_unescape.gperf"
+ {"RightVector", 3, {226, 135, 128}},
+ {(char*)0},
+#line 731 "src/html/html_unescape.gperf"
+ {"IJlig", 2, {196, 178}},
+#line 1227 "src/html/html_unescape.gperf"
+ {"NotTildeEqual", 3, {226, 137, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 58 "src/html/html_unescape.gperf"
+ {"angzarr", 3, {226, 141, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 53 "src/html/html_unescape.gperf"
+ {"angrt", 3, {226, 136, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 12 "src/html/html_unescape.gperf"
+ {"acd", 3, {226, 136, 191}},
+ {(char*)0}, {(char*)0},
+#line 38 "src/html/html_unescape.gperf"
+ {"andd", 3, {226, 169, 156}},
+ {(char*)0},
+#line 1241 "src/html/html_unescape.gperf"
+ {"nrarrc", 3, {226, 164, 179}},
+#line 2026 "src/html/html_unescape.gperf"
+ {"VeryThinSpace", 3, {226, 128, 138}},
+ {(char*)0},
+#line 1800 "src/html/html_unescape.gperf"
+ {"Superset", 3, {226, 138, 131}},
+ {(char*)0},
+#line 153 "src/html/html_unescape.gperf"
+ {"boxDl", 3, {226, 149, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2030 "src/html/html_unescape.gperf"
+ {"vnsub", 3, {226, 138, 130}},
+ {(char*)0}, {(char*)0},
+#line 236 "src/html/html_unescape.gperf"
+ {"ccupssm", 3, {226, 169, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1988 "src/html/html_unescape.gperf"
+ {"varnothing", 3, {226, 136, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1533 "src/html/html_unescape.gperf"
+ {"rcy", 2, {209, 128}},
+ {(char*)0},
+#line 863 "src/html/html_unescape.gperf"
+ {"lcy", 2, {208, 187}},
+ {(char*)0},
+#line 1653 "src/html/html_unescape.gperf"
+ {"scy", 2, {209, 129}},
+ {(char*)0},
+#line 1833 "src/html/html_unescape.gperf"
+ {"Tcy", 2, {208, 162}},
+#line 2113 "src/html/html_unescape.gperf"
+ {"Zcy", 2, {208, 151}},
+#line 469 "src/html/html_unescape.gperf"
+ {"ecy", 2, {209, 141}},
+#line 1538 "src/html/html_unescape.gperf"
+ {"rdsh", 3, {226, 134, 179}},
+ {(char*)0},
+#line 869 "src/html/html_unescape.gperf"
+ {"ldsh", 3, {226, 134, 178}},
+ {(char*)0},
+#line 1915 "src/html/html_unescape.gperf"
+ {"ucy", 2, {209, 131}},
+#line 185 "src/html/html_unescape.gperf"
+ {"boxVH", 3, {226, 149, 172}},
+#line 1834 "src/html/html_unescape.gperf"
+ {"tcy", 2, {209, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1099 "src/html/html_unescape.gperf"
+ {"ncy", 2, {208, 189}},
+ {(char*)0},
+#line 101 "src/html/html_unescape.gperf"
+ {"bcy", 2, {208, 177}},
+#line 1277 "src/html/html_unescape.gperf"
+ {"ntgl", 3, {226, 137, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 787 "src/html/html_unescape.gperf"
+ {"Jcy", 2, {208, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 289 "src/html/html_unescape.gperf"
+ {"congdot", 3, {226, 169, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 57 "src/html/html_unescape.gperf"
+ {"angst", 2, {195, 133}},
+ {(char*)0},
+#line 1570 "src/html/html_unescape.gperf"
+ {"RightDownTeeVector", 3, {226, 165, 157}},
+ {(char*)0}, {(char*)0},
+#line 1386 "src/html/html_unescape.gperf"
+ {"OverParenthesis", 3, {226, 143, 156}},
+#line 1020 "src/html/html_unescape.gperf"
+ {"ltquest", 3, {226, 169, 187}},
+ {(char*)0},
+#line 1395 "src/html/html_unescape.gperf"
+ {"pcy", 2, {208, 191}},
+ {(char*)0}, {(char*)0},
+#line 1376 "src/html/html_unescape.gperf"
+ {"otilde", 2, {195, 181}},
+#line 1536 "src/html/html_unescape.gperf"
+ {"rdquo", 3, {226, 128, 157}},
+ {(char*)0},
+#line 865 "src/html/html_unescape.gperf"
+ {"ldquo", 3, {226, 128, 156}},
+ {(char*)0},
+#line 2006 "src/html/html_unescape.gperf"
+ {"Vcy", 2, {208, 146}},
+ {(char*)0}, {(char*)0},
+#line 216 "src/html/html_unescape.gperf"
+ {"capbrcup", 3, {226, 169, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 102 "src/html/html_unescape.gperf"
+ {"bdquo", 3, {226, 128, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 422 "src/html/html_unescape.gperf"
+ {"DownArrowBar", 3, {226, 164, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2007 "src/html/html_unescape.gperf"
+ {"vcy", 2, {208, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 54 "src/html/html_unescape.gperf"
+ {"angrtvb", 3, {226, 138, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 805 "src/html/html_unescape.gperf"
+ {"Kcy", 2, {208, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1041 "src/html/html_unescape.gperf"
+ {"Mcy", 2, {208, 156}},
+#line 1652 "src/html/html_unescape.gperf"
+ {"Scy", 2, {208, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1116 "src/html/html_unescape.gperf"
+ {"NewLine", 1, {10}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 548 "src/html/html_unescape.gperf"
+ {"fcy", 2, {209, 132}},
+#line 1914 "src/html/html_unescape.gperf"
+ {"Ucy", 2, {208, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 184 "src/html/html_unescape.gperf"
+ {"boxVh", 3, {226, 149, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 354 "src/html/html_unescape.gperf"
+ {"Dcy", 2, {208, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 705 "src/html/html_unescape.gperf"
+ {"hstrok", 2, {196, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 862 "src/html/html_unescape.gperf"
+ {"Lcy", 2, {208, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2094 "src/html/html_unescape.gperf"
+ {"Ycy", 2, {208, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1815 "src/html/html_unescape.gperf"
+ {"supsim", 3, {226, 171, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1165 "src/html/html_unescape.gperf"
+ {"NonBreakingSpace", 2, {194, 160}},
+#line 1383 "src/html/html_unescape.gperf"
+ {"OverBar", 3, {226, 128, 190}},
+#line 1725 "src/html/html_unescape.gperf"
+ {"sqsubseteq", 3, {226, 138, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 625 "src/html/html_unescape.gperf"
+ {"GJcy", 2, {208, 131}},
+ {(char*)0}, {(char*)0},
+#line 1384 "src/html/html_unescape.gperf"
+ {"OverBrace", 3, {226, 143, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 513 "src/html/html_unescape.gperf"
+ {"eqcirc", 3, {226, 137, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1385 "src/html/html_unescape.gperf"
+ {"OverBracket", 3, {226, 142, 180}},
+ {(char*)0},
+#line 82 "src/html/html_unescape.gperf"
+ {"Auml", 2, {195, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 16 "src/html/html_unescape.gperf"
+ {"acute", 2, {194, 180}},
+#line 716 "src/html/html_unescape.gperf"
+ {"icy", 2, {208, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 779 "src/html/html_unescape.gperf"
+ {"Itilde", 2, {196, 168}},
+#line 690 "src/html/html_unescape.gperf"
+ {"HilbertSpace", 3, {226, 132, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1345 "src/html/html_unescape.gperf"
+ {"omega", 2, {207, 137}},
+#line 214 "src/html/html_unescape.gperf"
+ {"cacute", 2, {196, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1646 "src/html/html_unescape.gperf"
+ {"scirc", 2, {197, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 465 "src/html/html_unescape.gperf"
+ {"ecirc", 2, {195, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1913 "src/html/html_unescape.gperf"
+ {"ucirc", 2, {195, 187}},
+ {(char*)0},
+#line 646 "src/html/html_unescape.gperf"
+ {"GreaterSlantEqual", 3, {226, 169, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 785 "src/html/html_unescape.gperf"
+ {"Jcirc", 2, {196, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1292 "src/html/html_unescape.gperf"
+ {"nvDash", 3, {226, 138, 173}},
+#line 2044 "src/html/html_unescape.gperf"
+ {"Wcirc", 2, {197, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1098 "src/html/html_unescape.gperf"
+ {"Ncy", 2, {208, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1580 "src/html/html_unescape.gperf"
+ {"RightTeeArrow", 3, {226, 134, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 925 "src/html/html_unescape.gperf"
+ {"LessFullEqual", 3, {226, 137, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1011 "src/html/html_unescape.gperf"
+ {"ltcc", 3, {226, 170, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 27 "src/html/html_unescape.gperf"
+ {"aleph", 3, {226, 132, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 355 "src/html/html_unescape.gperf"
+ {"dcy", 2, {208, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1645 "src/html/html_unescape.gperf"
+ {"Scirc", 2, {197, 156}},
+ {(char*)0},
+#line 920 "src/html/html_unescape.gperf"
+ {"lessapprox", 3, {226, 170, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 718 "src/html/html_unescape.gperf"
+ {"IEcy", 2, {208, 149}},
+#line 986 "src/html/html_unescape.gperf"
+ {"LowerRightArrow", 3, {226, 134, 152}},
+#line 1912 "src/html/html_unescape.gperf"
+ {"Ucirc", 2, {195, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 25 "src/html/html_unescape.gperf"
+ {"agrave", 2, {195, 160}},
+ {(char*)0},
+#line 1060 "src/html/html_unescape.gperf"
+ {"MinusPlus", 3, {226, 136, 147}},
+#line 127 "src/html/html_unescape.gperf"
+ {"bigvee", 3, {226, 139, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1532 "src/html/html_unescape.gperf"
+ {"Rcy", 2, {208, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1802 "src/html/html_unescape.gperf"
+ {"suphsol", 3, {226, 159, 137}},
+ {(char*)0}, {(char*)0},
+#line 495 "src/html/html_unescape.gperf"
+ {"EmptyVerySmallSquare", 3, {226, 150, 171}},
+ {(char*)0},
+#line 163 "src/html/html_unescape.gperf"
+ {"boxhD", 3, {226, 149, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1436 "src/html/html_unescape.gperf"
+ {"precapprox", 3, {226, 170, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 55 "src/html/html_unescape.gperf"
+ {"angrtvbd", 3, {226, 166, 157}},
+#line 2092 "src/html/html_unescape.gperf"
+ {"Ycirc", 2, {197, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1753 "src/html/html_unescape.gperf"
+ {"sub", 3, {226, 138, 130}},
+ {(char*)0}, {(char*)0},
+#line 1375 "src/html/html_unescape.gperf"
+ {"Otilde", 2, {195, 149}},
+#line 232 "src/html/html_unescape.gperf"
+ {"Ccirc", 2, {196, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 547 "src/html/html_unescape.gperf"
+ {"Fcy", 2, {208, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 287 "src/html/html_unescape.gperf"
+ {"complexes", 3, {226, 132, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1763 "src/html/html_unescape.gperf"
+ {"subrarr", 3, {226, 165, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 758 "src/html/html_unescape.gperf"
+ {"InvisibleComma", 3, {226, 129, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 176 "src/html/html_unescape.gperf"
+ {"boxur", 3, {226, 148, 148}},
+#line 10 "src/html/html_unescape.gperf"
+ {"abreve", 2, {196, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1280 "src/html/html_unescape.gperf"
+ {"ntlg", 3, {226, 137, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 714 "src/html/html_unescape.gperf"
+ {"icirc", 2, {195, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2063 "src/html/html_unescape.gperf"
+ {"xdtri", 3, {226, 150, 189}},
+#line 253 "src/html/html_unescape.gperf"
+ {"circ", 2, {203, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 663 "src/html/html_unescape.gperf"
+ {"gtrdot", 3, {226, 139, 151}},
+ {(char*)0}, {(char*)0},
+#line 611 "src/html/html_unescape.gperf"
+ {"geqslant", 3, {226, 169, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1283 "src/html/html_unescape.gperf"
+ {"ntriangleright", 3, {226, 139, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 314 "src/html/html_unescape.gperf"
+ {"cuepr", 3, {226, 139, 158}},
+#line 1754 "src/html/html_unescape.gperf"
+ {"Sub", 3, {226, 139, 144}},
+ {(char*)0},
+#line 1042 "src/html/html_unescape.gperf"
+ {"mcy", 2, {208, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1860 "src/html/html_unescape.gperf"
+ {"timesbar", 3, {226, 168, 177}},
+ {(char*)0},
+#line 691 "src/html/html_unescape.gperf"
+ {"hksearow", 3, {226, 164, 165}},
+ {(char*)0}, {(char*)0},
+#line 1683 "src/html/html_unescape.gperf"
+ {"sigma", 2, {207, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 325 "src/html/html_unescape.gperf"
+ {"cupor", 3, {226, 169, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1373 "src/html/html_unescape.gperf"
+ {"oslash", 2, {195, 184}},
+#line 458 "src/html/html_unescape.gperf"
+ {"dzigrarr", 3, {226, 159, 191}},
+ {(char*)0}, {(char*)0},
+#line 892 "src/html/html_unescape.gperf"
+ {"leftrightharpoons", 3, {226, 135, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1577 "src/html/html_unescape.gperf"
+ {"rightleftharpoons", 3, {226, 135, 140}},
+ {(char*)0},
+#line 804 "src/html/html_unescape.gperf"
+ {"kcedil", 2, {196, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1759 "src/html/html_unescape.gperf"
+ {"submult", 3, {226, 171, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 333 "src/html/html_unescape.gperf"
+ {"curren", 2, {194, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 897 "src/html/html_unescape.gperf"
+ {"LeftTeeVector", 3, {226, 165, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 123 "src/html/html_unescape.gperf"
+ {"bigstar", 3, {226, 152, 133}},
+ {(char*)0}, {(char*)0},
+#line 321 "src/html/html_unescape.gperf"
+ {"cup", 3, {226, 136, 170}},
+#line 974 "src/html/html_unescape.gperf"
+ {"LongRightArrow", 3, {226, 159, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 598 "src/html/html_unescape.gperf"
+ {"Gcedil", 2, {196, 162}},
+ {(char*)0},
+#line 1440 "src/html/html_unescape.gperf"
+ {"PrecedesEqual", 3, {226, 170, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 2114 "src/html/html_unescape.gperf"
+ {"zcy", 2, {208, 183}},
+ {(char*)0},
+#line 1413 "src/html/html_unescape.gperf"
+ {"planckh", 3, {226, 132, 142}},
+#line 1344 "src/html/html_unescape.gperf"
+ {"Omega", 2, {206, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1772 "src/html/html_unescape.gperf"
+ {"subsub", 3, {226, 171, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1534 "src/html/html_unescape.gperf"
+ {"rdca", 3, {226, 164, 183}},
+#line 326 "src/html/html_unescape.gperf"
+ {"cups", 3, {226, 136, 170}},
+#line 864 "src/html/html_unescape.gperf"
+ {"ldca", 3, {226, 164, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1764 "src/html/html_unescape.gperf"
+ {"subset", 3, {226, 138, 130}},
+#line 1220 "src/html/html_unescape.gperf"
+ {"NotSucceeds", 3, {226, 138, 129}},
+#line 877 "src/html/html_unescape.gperf"
+ {"LeftArrowRightArrow", 3, {226, 135, 134}},
+ {(char*)0}, {(char*)0},
+#line 2045 "src/html/html_unescape.gperf"
+ {"wcirc", 2, {197, 181}},
+#line 1561 "src/html/html_unescape.gperf"
+ {"RightAngleBracket", 3, {226, 159, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1284 "src/html/html_unescape.gperf"
+ {"ntrianglerighteq", 3, {226, 139, 173}},
+#line 1682 "src/html/html_unescape.gperf"
+ {"Sigma", 2, {206, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1223 "src/html/html_unescape.gperf"
+ {"NotSucceedsTilde", 3, {226, 137, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 373 "src/html/html_unescape.gperf"
+ {"DiacriticalAcute", 2, {194, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1761 "src/html/html_unescape.gperf"
+ {"subne", 3, {226, 138, 138}},
+ {(char*)0},
+#line 1457 "src/html/html_unescape.gperf"
+ {"Product", 3, {226, 136, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 259 "src/html/html_unescape.gperf"
+ {"circleddash", 3, {226, 138, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1773 "src/html/html_unescape.gperf"
+ {"subsup", 3, {226, 171, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 298 "src/html/html_unescape.gperf"
+ {"copy", 2, {194, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 534 "src/html/html_unescape.gperf"
+ {"eta", 2, {206, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 52 "src/html/html_unescape.gperf"
+ {"angmsd", 3, {226, 136, 161}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1084 "src/html/html_unescape.gperf"
+ {"natural", 3, {226, 153, 174}},
+ {(char*)0},
+#line 1799 "src/html/html_unescape.gperf"
+ {"supedot", 3, {226, 171, 132}},
+#line 1085 "src/html/html_unescape.gperf"
+ {"naturals", 3, {226, 132, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1881 "src/html/html_unescape.gperf"
+ {"triangleright", 3, {226, 150, 185}},
+ {(char*)0},
+#line 376 "src/html/html_unescape.gperf"
+ {"DiacriticalGrave", 1, {96}},
+#line 173 "src/html/html_unescape.gperf"
+ {"boxuL", 3, {226, 149, 155}},
+#line 288 "src/html/html_unescape.gperf"
+ {"cong", 3, {226, 137, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1836 "src/html/html_unescape.gperf"
+ {"telrec", 3, {226, 140, 149}},
+ {(char*)0}, {(char*)0},
+#line 282 "src/html/html_unescape.gperf"
+ {"comma", 1, {44}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1765 "src/html/html_unescape.gperf"
+ {"Subset", 3, {226, 139, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1222 "src/html/html_unescape.gperf"
+ {"NotSucceedsSlantEqual", 3, {226, 139, 161}},
+#line 664 "src/html/html_unescape.gperf"
+ {"gtreqless", 3, {226, 139, 155}},
+#line 80 "src/html/html_unescape.gperf"
+ {"Atilde", 2, {195, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 327 "src/html/html_unescape.gperf"
+ {"curarr", 3, {226, 134, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 313 "src/html/html_unescape.gperf"
+ {"cudarrr", 3, {226, 164, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 312 "src/html/html_unescape.gperf"
+ {"cudarrl", 3, {226, 164, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1766 "src/html/html_unescape.gperf"
+ {"subseteq", 3, {226, 138, 134}},
+#line 1767 "src/html/html_unescape.gperf"
+ {"subseteqq", 3, {226, 171, 133}},
+#line 1579 "src/html/html_unescape.gperf"
+ {"rightsquigarrow", 3, {226, 134, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 319 "src/html/html_unescape.gperf"
+ {"cupcap", 3, {226, 169, 134}},
+#line 1769 "src/html/html_unescape.gperf"
+ {"subsetneq", 3, {226, 138, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 60 "src/html/html_unescape.gperf"
+ {"aogon", 2, {196, 133}},
+#line 1191 "src/html/html_unescape.gperf"
+ {"notinvc", 3, {226, 139, 182}},
+#line 1583 "src/html/html_unescape.gperf"
+ {"rightthreetimes", 3, {226, 139, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 2089 "src/html/html_unescape.gperf"
+ {"yacute", 2, {195, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1148 "src/html/html_unescape.gperf"
+ {"nLeftarrow", 3, {226, 135, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1318 "src/html/html_unescape.gperf"
+ {"ocy", 2, {208, 190}},
+#line 241 "src/html/html_unescape.gperf"
+ {"cemptyv", 3, {226, 166, 178}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 468 "src/html/html_unescape.gperf"
+ {"Ecy", 2, {208, 173}},
+ {(char*)0}, {(char*)0},
+#line 323 "src/html/html_unescape.gperf"
+ {"cupcup", 3, {226, 169, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1882 "src/html/html_unescape.gperf"
+ {"trianglerighteq", 3, {226, 138, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 889 "src/html/html_unescape.gperf"
+ {"LeftRightArrow", 3, {226, 134, 148}},
+ {(char*)0}, {(char*)0},
+#line 1775 "src/html/html_unescape.gperf"
+ {"succ", 3, {226, 137, 187}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 426 "src/html/html_unescape.gperf"
+ {"DownArrowUpArrow", 3, {226, 135, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1325 "src/html/html_unescape.gperf"
+ {"OElig", 2, {197, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 248 "src/html/html_unescape.gperf"
+ {"chcy", 2, {209, 135}},
+#line 665 "src/html/html_unescape.gperf"
+ {"gtreqqless", 3, {226, 170, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 43 "src/html/html_unescape.gperf"
+ {"angle", 3, {226, 136, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 13 "src/html/html_unescape.gperf"
+ {"acE", 3, {226, 136, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1598 "src/html/html_unescape.gperf"
+ {"rmoustache", 3, {226, 142, 177}},
+ {(char*)0},
+#line 954 "src/html/html_unescape.gperf"
+ {"lmoustache", 3, {226, 142, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1110 "src/html/html_unescape.gperf"
+ {"NegativeVeryThinSpace", 3, {226, 128, 139}},
+ {(char*)0}, {(char*)0},
+#line 1083 "src/html/html_unescape.gperf"
+ {"napprox", 3, {226, 137, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1372 "src/html/html_unescape.gperf"
+ {"Oslash", 2, {195, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1770 "src/html/html_unescape.gperf"
+ {"subsetneqq", 3, {226, 171, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 72 "src/html/html_unescape.gperf"
+ {"Aring", 2, {195, 133}},
+#line 177 "src/html/html_unescape.gperf"
+ {"boxuR", 3, {226, 149, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1762 "src/html/html_unescape.gperf"
+ {"subplus", 3, {226, 170, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2087 "src/html/html_unescape.gperf"
+ {"xwedge", 3, {226, 139, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 172 "src/html/html_unescape.gperf"
+ {"boxul", 3, {226, 148, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 190 "src/html/html_unescape.gperf"
+ {"boxvr", 3, {226, 148, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 706 "src/html/html_unescape.gperf"
+ {"HumpDownHump", 3, {226, 137, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 715 "src/html/html_unescape.gperf"
+ {"Icy", 2, {208, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 71 "src/html/html_unescape.gperf"
+ {"approxeq", 3, {226, 137, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 8 "src/html/html_unescape.gperf"
+ {"aacute", 2, {195, 161}},
+#line 67 "src/html/html_unescape.gperf"
+ {"apid", 3, {226, 137, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1952 "src/html/html_unescape.gperf"
+ {"UpDownArrow", 3, {226, 134, 149}},
+ {(char*)0},
+#line 1114 "src/html/html_unescape.gperf"
+ {"NestedGreaterGreater", 3, {226, 137, 171}},
+ {(char*)0},
+#line 788 "src/html/html_unescape.gperf"
+ {"jcy", 2, {208, 185}},
+ {(char*)0}, {(char*)0},
+#line 667 "src/html/html_unescape.gperf"
+ {"gtrsim", 3, {226, 137, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 180 "src/html/html_unescape.gperf"
+ {"boxv", 3, {226, 148, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1315 "src/html/html_unescape.gperf"
+ {"ocirc", 2, {195, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 464 "src/html/html_unescape.gperf"
+ {"Ecirc", 2, {195, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1206 "src/html/html_unescape.gperf"
+ {"notnivc", 3, {226, 139, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 125 "src/html/html_unescape.gperf"
+ {"bigtriangleup", 3, {226, 150, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 343 "src/html/html_unescape.gperf"
+ {"daleth", 3, {226, 132, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1317 "src/html/html_unescape.gperf"
+ {"Ocy", 2, {208, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 682 "src/html/html_unescape.gperf"
+ {"Hcirc", 2, {196, 164}},
+#line 1591 "src/html/html_unescape.gperf"
+ {"RightVectorBar", 3, {226, 165, 147}},
+#line 19 "src/html/html_unescape.gperf"
+ {"AElig", 2, {195, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 557 "src/html/html_unescape.gperf"
+ {"FilledVerySmallSquare", 3, {226, 150, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 623 "src/html/html_unescape.gperf"
+ {"ggg", 3, {226, 139, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 100 "src/html/html_unescape.gperf"
+ {"Bcy", 2, {208, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1427 "src/html/html_unescape.gperf"
+ {"Poincareplane", 3, {226, 132, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 187 "src/html/html_unescape.gperf"
+ {"boxvL", 3, {226, 149, 161}},
+ {(char*)0}, {(char*)0},
+#line 1393 "src/html/html_unescape.gperf"
+ {"PartialD", 3, {226, 136, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 713 "src/html/html_unescape.gperf"
+ {"Icirc", 2, {195, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 316 "src/html/html_unescape.gperf"
+ {"cularr", 3, {226, 134, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 159 "src/html/html_unescape.gperf"
+ {"boxh", 3, {226, 148, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 40 "src/html/html_unescape.gperf"
+ {"andv", 3, {226, 169, 154}},
+ {(char*)0},
+#line 1789 "src/html/html_unescape.gperf"
+ {"sung", 3, {226, 153, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1569 "src/html/html_unescape.gperf"
+ {"RightDoubleBracket", 3, {226, 159, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 786 "src/html/html_unescape.gperf"
+ {"jcirc", 2, {196, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1936 "src/html/html_unescape.gperf"
+ {"UnderBar", 1, {95}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1564 "src/html/html_unescape.gperf"
+ {"RightArrow", 3, {226, 134, 146}},
+#line 258 "src/html/html_unescape.gperf"
+ {"circledcirc", 3, {226, 138, 154}},
+#line 28 "src/html/html_unescape.gperf"
+ {"Alpha", 2, {206, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 886 "src/html/html_unescape.gperf"
+ {"leftharpoonup", 3, {226, 134, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 317 "src/html/html_unescape.gperf"
+ {"cularrp", 3, {226, 164, 189}},
+ {(char*)0},
+#line 1566 "src/html/html_unescape.gperf"
+ {"RightArrowLeftArrow", 3, {226, 135, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1995 "src/html/html_unescape.gperf"
+ {"varsigma", 2, {207, 130}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1288 "src/html/html_unescape.gperf"
+ {"numero", 3, {226, 132, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 552 "src/html/html_unescape.gperf"
+ {"ffllig", 3, {239, 172, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 985 "src/html/html_unescape.gperf"
+ {"LowerLeftArrow", 3, {226, 134, 153}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 543 "src/html/html_unescape.gperf"
+ {"expectation", 3, {226, 132, 176}},
+ {(char*)0},
+#line 1314 "src/html/html_unescape.gperf"
+ {"Ocirc", 2, {195, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2091 "src/html/html_unescape.gperf"
+ {"yacy", 2, {209, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 824 "src/html/html_unescape.gperf"
+ {"lambda", 2, {206, 187}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1221 "src/html/html_unescape.gperf"
+ {"NotSucceedsEqual", 3, {226, 170, 176}},
+#line 191 "src/html/html_unescape.gperf"
+ {"boxvR", 3, {226, 149, 158}},
+ {(char*)0},
+#line 124 "src/html/html_unescape.gperf"
+ {"bigtriangledown", 3, {226, 150, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 41 "src/html/html_unescape.gperf"
+ {"ang", 3, {226, 136, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2084 "src/html/html_unescape.gperf"
+ {"xuplus", 3, {226, 168, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1075 "src/html/html_unescape.gperf"
+ {"nabla", 3, {226, 136, 135}},
+#line 186 "src/html/html_unescape.gperf"
+ {"boxvl", 3, {226, 148, 164}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 533 "src/html/html_unescape.gperf"
+ {"Eta", 2, {206, 151}},
+ {(char*)0},
+#line 17 "src/html/html_unescape.gperf"
+ {"Acy", 2, {208, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 806 "src/html/html_unescape.gperf"
+ {"kcy", 2, {208, 186}},
+#line 602 "src/html/html_unescape.gperf"
+ {"gcy", 2, {208, 179}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 894 "src/html/html_unescape.gperf"
+ {"LeftRightVector", 3, {226, 165, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 231 "src/html/html_unescape.gperf"
+ {"ccedil", 2, {195, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 91 "src/html/html_unescape.gperf"
+ {"Backslash", 3, {226, 136, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 703 "src/html/html_unescape.gperf"
+ {"hslash", 3, {226, 132, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1394 "src/html/html_unescape.gperf"
+ {"Pcy", 2, {208, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 601 "src/html/html_unescape.gperf"
+ {"Gcy", 2, {208, 147}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 660 "src/html/html_unescape.gperf"
+ {"gtquest", 3, {226, 169, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 823 "src/html/html_unescape.gperf"
+ {"Lambda", 2, {206, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1322 "src/html/html_unescape.gperf"
+ {"odiv", 3, {226, 168, 184}},
+ {(char*)0},
+#line 885 "src/html/html_unescape.gperf"
+ {"leftharpoondown", 3, {226, 134, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 972 "src/html/html_unescape.gperf"
+ {"longmapsto", 3, {226, 159, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 798 "src/html/html_unescape.gperf"
+ {"Jukcy", 2, {208, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 867 "src/html/html_unescape.gperf"
+ {"ldrdhar", 3, {226, 165, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2085 "src/html/html_unescape.gperf"
+ {"xutri", 3, {226, 150, 179}},
+#line 1246 "src/html/html_unescape.gperf"
+ {"nRightarrow", 3, {226, 135, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 545 "src/html/html_unescape.gperf"
+ {"ExponentialE", 3, {226, 133, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1245 "src/html/html_unescape.gperf"
+ {"nrightarrow", 3, {226, 134, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 14 "src/html/html_unescape.gperf"
+ {"Acirc", 2, {195, 130}},
+#line 1164 "src/html/html_unescape.gperf"
+ {"NoBreak", 3, {226, 129, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 600 "src/html/html_unescape.gperf"
+ {"gcirc", 2, {196, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 42 "src/html/html_unescape.gperf"
+ {"ange", 3, {226, 166, 164}},
+#line 328 "src/html/html_unescape.gperf"
+ {"curarrm", 3, {226, 164, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1671 "src/html/html_unescape.gperf"
+ {"SHCHcy", 2, {208, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2107 "src/html/html_unescape.gperf"
+ {"yuml", 2, {195, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1760 "src/html/html_unescape.gperf"
+ {"subnE", 3, {226, 171, 139}},
+ {(char*)0}, {(char*)0},
+#line 360 "src/html/html_unescape.gperf"
+ {"DDotrahd", 3, {226, 164, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1629 "src/html/html_unescape.gperf"
+ {"RuleDelayed", 3, {226, 167, 180}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 599 "src/html/html_unescape.gperf"
+ {"Gcirc", 2, {196, 156}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 796 "src/html/html_unescape.gperf"
+ {"Jsercy", 2, {208, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 653 "src/html/html_unescape.gperf"
+ {"gtcc", 3, {226, 170, 167}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 782 "src/html/html_unescape.gperf"
+ {"iukcy", 2, {209, 150}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1951 "src/html/html_unescape.gperf"
+ {"updownarrow", 3, {226, 134, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 331 "src/html/html_unescape.gperf"
+ {"curlyvee", 3, {226, 139, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 550 "src/html/html_unescape.gperf"
+ {"ffilig", 3, {239, 172, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2100 "src/html/html_unescape.gperf"
+ {"yicy", 2, {209, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 390 "src/html/html_unescape.gperf"
+ {"divonx", 3, {226, 139, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 661 "src/html/html_unescape.gperf"
+ {"gtrapprox", 3, {226, 170, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1755 "src/html/html_unescape.gperf"
+ {"subdot", 3, {226, 170, 189}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 891 "src/html/html_unescape.gperf"
+ {"leftrightarrows", 3, {226, 135, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 83 "src/html/html_unescape.gperf"
+ {"auml", 2, {195, 164}},
+ {(char*)0}, {(char*)0},
+#line 1953 "src/html/html_unescape.gperf"
+ {"Updownarrow", 3, {226, 135, 149}},
+ {(char*)0},
+#line 1576 "src/html/html_unescape.gperf"
+ {"rightleftarrows", 3, {226, 135, 132}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 437 "src/html/html_unescape.gperf"
+ {"DownRightVector", 3, {226, 135, 129}},
+ {(char*)0}, {(char*)0},
+#line 436 "src/html/html_unescape.gperf"
+ {"DownRightVectorBar", 3, {226, 165, 151}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 683 "src/html/html_unescape.gperf"
+ {"hcirc", 2, {196, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1614 "src/html/html_unescape.gperf"
+ {"Rrightarrow", 3, {226, 135, 155}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 973 "src/html/html_unescape.gperf"
+ {"longrightarrow", 3, {226, 159, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 324 "src/html/html_unescape.gperf"
+ {"cupdot", 3, {226, 138, 141}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 11 "src/html/html_unescape.gperf"
+ {"ac", 3, {226, 136, 190}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 696 "src/html/html_unescape.gperf"
+ {"hookrightarrow", 3, {226, 134, 170}},
+ {(char*)0}, {(char*)0},
+#line 1108 "src/html/html_unescape.gperf"
+ {"NegativeThickSpace", 3, {226, 128, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1756 "src/html/html_unescape.gperf"
+ {"subE", 3, {226, 171, 133}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1901 "src/html/html_unescape.gperf"
+ {"twoheadrightarrow", 3, {226, 134, 160}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 430 "src/html/html_unescape.gperf"
+ {"downharpoonright", 3, {226, 135, 130}},
+#line 429 "src/html/html_unescape.gperf"
+ {"downharpoonleft", 3, {226, 135, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 20 "src/html/html_unescape.gperf"
+ {"aelig", 2, {195, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1535 "src/html/html_unescape.gperf"
+ {"rdldhar", 3, {226, 165, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 332 "src/html/html_unescape.gperf"
+ {"curlywedge", 3, {226, 139, 143}},
+ {(char*)0},
+#line 708 "src/html/html_unescape.gperf"
+ {"hybull", 3, {226, 129, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1757 "src/html/html_unescape.gperf"
+ {"sube", 3, {226, 138, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 975 "src/html/html_unescape.gperf"
+ {"Longrightarrow", 3, {226, 159, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 240 "src/html/html_unescape.gperf"
+ {"Cedilla", 2, {194, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1189 "src/html/html_unescape.gperf"
+ {"notinva", 3, {226, 136, 137}},
+#line 1778 "src/html/html_unescape.gperf"
+ {"SucceedsEqual", 3, {226, 170, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 888 "src/html/html_unescape.gperf"
+ {"leftrightarrow", 3, {226, 134, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1750 "src/html/html_unescape.gperf"
+ {"straightepsilon", 2, {207, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 32 "src/html/html_unescape.gperf"
+ {"amalg", 3, {226, 168, 191}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 81 "src/html/html_unescape.gperf"
+ {"atilde", 2, {195, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1568 "src/html/html_unescape.gperf"
+ {"RightCeiling", 3, {226, 140, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 890 "src/html/html_unescape.gperf"
+ {"Leftrightarrow", 3, {226, 135, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1771 "src/html/html_unescape.gperf"
+ {"subsim", 3, {226, 171, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 2023 "src/html/html_unescape.gperf"
+ {"VerticalLine", 1, {124}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1590 "src/html/html_unescape.gperf"
+ {"RightUpVector", 3, {226, 134, 190}},
+ {(char*)0}, {(char*)0},
+#line 1589 "src/html/html_unescape.gperf"
+ {"RightUpVectorBar", 3, {226, 165, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1572 "src/html/html_unescape.gperf"
+ {"RightDownVector", 3, {226, 135, 130}},
+ {(char*)0}, {(char*)0},
+#line 1571 "src/html/html_unescape.gperf"
+ {"RightDownVectorBar", 3, {226, 165, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 26 "src/html/html_unescape.gperf"
+ {"alefsym", 3, {226, 132, 181}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 256 "src/html/html_unescape.gperf"
+ {"circlearrowright", 3, {226, 134, 187}},
+#line 255 "src/html/html_unescape.gperf"
+ {"circlearrowleft", 3, {226, 134, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 781 "src/html/html_unescape.gperf"
+ {"Iukcy", 2, {208, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1377 "src/html/html_unescape.gperf"
+ {"otimesas", 3, {226, 168, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 754 "src/html/html_unescape.gperf"
+ {"intercal", 3, {226, 138, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1846 "src/html/html_unescape.gperf"
+ {"thickapprox", 3, {226, 137, 136}},
+ {(char*)0}, {(char*)0},
+#line 799 "src/html/html_unescape.gperf"
+ {"jukcy", 2, {209, 148}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1204 "src/html/html_unescape.gperf"
+ {"notniva", 3, {226, 136, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1444 "src/html/html_unescape.gperf"
+ {"precnapprox", 3, {226, 170, 185}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 336 "src/html/html_unescape.gperf"
+ {"cuvee", 3, {226, 139, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 73 "src/html/html_unescape.gperf"
+ {"aring", 2, {195, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 233 "src/html/html_unescape.gperf"
+ {"ccirc", 2, {196, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1563 "src/html/html_unescape.gperf"
+ {"rightarrow", 3, {226, 134, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 753 "src/html/html_unescape.gperf"
+ {"Integral", 3, {226, 136, 171}},
+#line 2061 "src/html/html_unescape.gperf"
+ {"xcirc", 3, {226, 151, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 797 "src/html/html_unescape.gperf"
+ {"jsercy", 2, {209, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 250 "src/html/html_unescape.gperf"
+ {"checkmark", 3, {226, 156, 147}},
+ {(char*)0},
+#line 2025 "src/html/html_unescape.gperf"
+ {"VerticalTilde", 3, {226, 137, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 183 "src/html/html_unescape.gperf"
+ {"boxvH", 3, {226, 149, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1211 "src/html/html_unescape.gperf"
+ {"NotRightTriangleBar", 3, {226, 167, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1213 "src/html/html_unescape.gperf"
+ {"NotRightTriangleEqual", 3, {226, 139, 173}},
+#line 1212 "src/html/html_unescape.gperf"
+ {"NotRightTriangle", 3, {226, 139, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 906 "src/html/html_unescape.gperf"
+ {"LeftVectorBar", 3, {226, 165, 146}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 182 "src/html/html_unescape.gperf"
+ {"boxvh", 3, {226, 148, 188}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 150 "src/html/html_unescape.gperf"
+ {"boxbox", 3, {226, 167, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2095 "src/html/html_unescape.gperf"
+ {"ycy", 2, {209, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1758 "src/html/html_unescape.gperf"
+ {"subedot", 3, {226, 171, 131}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1707 "src/html/html_unescape.gperf"
+ {"SOFTcy", 2, {208, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1565 "src/html/html_unescape.gperf"
+ {"Rightarrow", 3, {226, 135, 146}},
+ {(char*)0},
+#line 29 "src/html/html_unescape.gperf"
+ {"alpha", 2, {206, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1672 "src/html/html_unescape.gperf"
+ {"shchcy", 2, {209, 137}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1708 "src/html/html_unescape.gperf"
+ {"softcy", 2, {209, 140}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 18 "src/html/html_unescape.gperf"
+ {"acy", 2, {208, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2093 "src/html/html_unescape.gperf"
+ {"ycirc", 2, {197, 183}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 117 "src/html/html_unescape.gperf"
+ {"bigcirc", 3, {226, 151, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 736 "src/html/html_unescape.gperf"
+ {"ImaginaryI", 3, {226, 133, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 70 "src/html/html_unescape.gperf"
+ {"approx", 3, {226, 137, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1801 "src/html/html_unescape.gperf"
+ {"SupersetEqual", 3, {226, 138, 135}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2043 "src/html/html_unescape.gperf"
+ {"vzigzag", 3, {226, 166, 154}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 315 "src/html/html_unescape.gperf"
+ {"cuesc", 3, {226, 139, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1939 "src/html/html_unescape.gperf"
+ {"UnderParenthesis", 3, {226, 143, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 15 "src/html/html_unescape.gperf"
+ {"acirc", 2, {195, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1774 "src/html/html_unescape.gperf"
+ {"succapprox", 3, {226, 170, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1040 "src/html/html_unescape.gperf"
+ {"mcomma", 3, {226, 168, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 48 "src/html/html_unescape.gperf"
+ {"angmsdae", 3, {226, 166, 172}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 45 "src/html/html_unescape.gperf"
+ {"angmsdab", 3, {226, 166, 169}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 49 "src/html/html_unescape.gperf"
+ {"angmsdaf", 3, {226, 166, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 56 "src/html/html_unescape.gperf"
+ {"angsph", 3, {226, 136, 162}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1026 "src/html/html_unescape.gperf"
+ {"luruhar", 3, {226, 165, 166}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 47 "src/html/html_unescape.gperf"
+ {"angmsdad", 3, {226, 166, 171}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1900 "src/html/html_unescape.gperf"
+ {"twoheadleftarrow", 3, {226, 134, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 340 "src/html/html_unescape.gperf"
+ {"cylcty", 3, {226, 140, 173}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1751 "src/html/html_unescape.gperf"
+ {"straightphi", 2, {207, 149}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1073 "src/html/html_unescape.gperf"
+ {"multimap", 3, {226, 138, 184}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1562 "src/html/html_unescape.gperf"
+ {"RightArrowBar", 3, {226, 135, 165}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 868 "src/html/html_unescape.gperf"
+ {"ldrushar", 3, {226, 165, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 872 "src/html/html_unescape.gperf"
+ {"LeftAngleBracket", 3, {226, 159, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1630 "src/html/html_unescape.gperf"
+ {"ruluhar", 3, {226, 165, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 329 "src/html/html_unescape.gperf"
+ {"curlyeqprec", 3, {226, 139, 158}},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2106 "src/html/html_unescape.gperf"
+ {"yucy", 2, {209, 142}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1025 "src/html/html_unescape.gperf"
+ {"lurdshar", 3, {226, 165, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 675 "src/html/html_unescape.gperf"
+ {"hardcy", 2, {209, 138}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1574 "src/html/html_unescape.gperf"
+ {"rightharpoondown", 3, {226, 135, 129}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1575 "src/html/html_unescape.gperf"
+ {"rightharpoonup", 3, {226, 135, 128}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 674 "src/html/html_unescape.gperf"
+ {"HARDcy", 2, {208, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1768 "src/html/html_unescape.gperf"
+ {"SubsetEqual", 3, {226, 138, 134}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 385 "src/html/html_unescape.gperf"
+ {"digamma", 2, {207, 157}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1918 "src/html/html_unescape.gperf"
+ {"udblac", 2, {197, 177}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1786 "src/html/html_unescape.gperf"
+ {"SuchThat", 3, {226, 136, 139}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 337 "src/html/html_unescape.gperf"
+ {"cuwed", 3, {226, 139, 143}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1917 "src/html/html_unescape.gperf"
+ {"Udblac", 2, {197, 176}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 50 "src/html/html_unescape.gperf"
+ {"angmsdag", 3, {226, 166, 174}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 51 "src/html/html_unescape.gperf"
+ {"angmsdah", 3, {226, 166, 175}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2022 "src/html/html_unescape.gperf"
+ {"VerticalBar", 3, {226, 136, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 2024 "src/html/html_unescape.gperf"
+ {"VerticalSeparator", 3, {226, 157, 152}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 1567 "src/html/html_unescape.gperf"
+ {"rightarrowtail", 3, {226, 134, 163}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 1321 "src/html/html_unescape.gperf"
+ {"odblac", 2, {197, 145}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 1782 "src/html/html_unescape.gperf"
+ {"succnapprox", 3, {226, 170, 186}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 46 "src/html/html_unescape.gperf"
+ {"angmsdac", 3, {226, 166, 170}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 1320 "src/html/html_unescape.gperf"
+ {"Odblac", 2, {197, 144}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0},
+#line 318 "src/html/html_unescape.gperf"
+ {"cupbrcap", 3, {226, 169, 136}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 44 "src/html/html_unescape.gperf"
+ {"angmsdaa", 3, {226, 166, 168}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0},
+#line 330 "src/html/html_unescape.gperf"
+ {"curlyeqsucc", 3, {226, 139, 159}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+#line 334 "src/html/html_unescape.gperf"
+ {"curvearrowleft", 3, {226, 134, 182}},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0}, {(char*)0}, {(char*)0},
+ {(char*)0}, {(char*)0},
+#line 335 "src/html/html_unescape.gperf"
+ {"curvearrowright", 3, {226, 134, 183}}
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = hash_entity (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ if (len == lengthtable[key])
+ {
+ register const char *s = wordlist[key].entity;
+
+ if (s && *str == *s && !memcmp (str + 1, s + 1, len - 1))
+ return &wordlist[key];
+ }
+ }
+ return 0;
+}
diff --git a/src/utf8.h b/src/utf8.h
new file mode 100644
index 0000000..1e4e556
--- /dev/null
+++ b/src/utf8.h
@@ -0,0 +1,12 @@
+#ifndef _H_STMD_UTF8_
+#define _H_STMD_UTF8_
+
+#include "buffer.h"
+
+void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
+void utf8proc_encode_char(int32_t uc, strbuf *buf);
+ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst);
+ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len);
+void utf8proc_detab(strbuf *dest, const unsigned char *line, size_t size);
+
+#endif
--
cgit v1.2.3
From 798f58a2b614280201141b398c8e498cecc8ab5e Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Sat, 6 Sep 2014 21:17:23 +0200
Subject: This is going well
---
spec.txt | 35 +++++++++++++++++++-----------
src/inlines.c | 68 +++++++++++++++++++++++++++++++++++------------------------
2 files changed, 64 insertions(+), 39 deletions(-)
diff --git a/spec.txt b/spec.txt
index 616cb96..ebd6d98 100644
--- a/spec.txt
+++ b/spec.txt
@@ -3688,7 +3688,7 @@ raw HTML:
.
.
-http://google.com?find=\*
+http://google.com?find=\*
.
.
@@ -3727,25 +3727,37 @@ foo
## Entities
-Entities are parsed as entities, not as literal text, in all contexts
-except code spans and code blocks. Three kinds of entities are recognized.
+With the goal of making this standard as HTML-agnostic as possible, all HTML valid HTML Entities in any
+context are recognized as such and converted into their actual values (i.e. the UTF8 characters representing
+the entity itself) before they are stored in the AST.
+
+This allows implementations that target HTML output to trivially escape the entities when generating HTML,
+and simplifies the job of implementations targetting other languages, as these will only need to handle the
+UTF8 chars and need not be HTML-entity aware.
[Named entities](#name-entities) consist of `&`
-+ a string of 2-32 alphanumerics beginning with a letter + `;`.
++ any of the valid HTML5 entity names + `;`. The [following document](http://www.whatwg.org/specs/web-apps/current-work/multipage/entities.json)
+is used as an authoritative source of the valid entity names and their corresponding codepoints.
+
+Conforming implementations that target Markdown don't need to generate entities for all the valid
+named entities that exist, with the exception of `"` (`"`), `&` (`&`), `<` (`<`) and `>` (`>`),
+which always need to be written as entities for security reasons.
.
& © Æ Ď ¾ ℋ ⅆ ∲
.
- & © Æ Ď ¾ ℋ ⅆ ∲
+ & © Æ Ď ¾ ℋ ⅆ ∲
.
[Decimal entities](#decimal-entities)
-consist of `` + a string of 1--8 arabic digits + `;`.
+consist of `` + a string of 1--8 arabic digits + `;`. Again, these entities need to be recognised
+and tranformed into their corresponding UTF8 codepoints. Invalid Unicode codepoints will be written
+as the "unknown codepoint" character (`0xFFFD`)
.
- # Ӓ Ϡ
+# Ӓ Ϡ
.
- # Ӓ Ϡ
+# Ӓ Ϡ �
.
[Hexadecimal entities](#hexadecimal-entities)
@@ -3767,7 +3779,7 @@ Here are some nonentities:
.
Although HTML5 does accept some entities without a trailing semicolon
-(such as `©`), these are not recognized as entities here:
+(such as `©`), these are not recognized as entities here, because it makes the grammar too ambiguous:
.
©
@@ -3775,13 +3787,12 @@ Although HTML5 does accept some entities without a trailing semicolon
©
.
-On the other hand, many strings that are not on the list of HTML5
-named entities are recognized as entities here:
+Strings that are not on the list of HTML5 named entities are not recognized as entities either:
.
&MadeUpEntity;
.
-&MadeUpEntity;
+&MadeUpEntity;
.
Entities are recognized in any context besides code spans or
diff --git a/src/inlines.c b/src/inlines.c
index 7b27150..aa0e13e 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -20,8 +20,9 @@ typedef struct Subject {
reference* lookup_reference(reference** refmap, chunk *label);
reference* make_reference(chunk *label, chunk *url, chunk *title);
-static unsigned char *clean_url(chunk *url, int is_email);
+static unsigned char *clean_url(chunk *url);
static unsigned char *clean_title(chunk *title);
+static unsigned char *clean_autolink(chunk *url, int is_email);
inline static void chunk_free(chunk *c);
inline static void chunk_trim(chunk *c);
@@ -91,7 +92,7 @@ extern reference* make_reference(chunk *label, chunk *url, chunk *title)
reference *ref;
ref = malloc(sizeof(reference));
ref->label = normalize_reference(label);
- ref->url = clean_url(url, 0);
+ ref->url = clean_url(url);
ref->title = clean_title(title);
return ref;
}
@@ -123,27 +124,31 @@ static unsigned char *bufdup(const unsigned char *buf)
return new;
}
-inline static node_inl* make_link_from_reference(node_inl* label, reference *ref)
+static inline node_inl *make_link_(node_inl *label, unsigned char *url, unsigned char *title)
{
node_inl* e = (node_inl*) malloc(sizeof(node_inl));
e->tag = INL_LINK;
e->content.linkable.label = label;
- e->content.linkable.url = bufdup(ref->url);
- e->content.linkable.title = bufdup(ref->title);
+ e->content.linkable.url = url;
+ e->content.linkable.title = title;
e->next = NULL;
return e;
}
+inline static node_inl* make_ref_link(node_inl* label, reference *ref)
+{
+ return make_link_(label, bufdup(ref->url), bufdup(ref->title));
+}
+
+inline static node_inl* make_autolink(node_inl* label, chunk url, int is_email)
+{
+ return make_link_(label, clean_autolink(&url, is_email), NULL);
+}
+
// Create an inline with a linkable string value.
-inline static node_inl* make_link(node_inl* label, chunk url, chunk title, int is_email)
+inline static node_inl* make_link(node_inl* label, chunk url, chunk title)
{
- node_inl* e = (node_inl*) malloc(sizeof(node_inl));
- e->tag = INL_LINK;
- e->content.linkable.label = label;
- e->content.linkable.url = clean_url(&url, is_email);
- e->content.linkable.title = clean_title(&title);
- e->next = NULL;
- return e;
+ return make_link_(label, clean_url(&url), clean_title(&title));
}
inline static node_inl* make_inlines(int t, node_inl* contents)
@@ -587,7 +592,7 @@ extern void unescape_buffer(strbuf *buf)
// Clean a URL: remove surrounding whitespace and surrounding <>,
// and remove \ that escape punctuation.
-static unsigned char *clean_url(chunk *url, int is_email)
+static unsigned char *clean_url(chunk *url)
{
strbuf buf = GH_BUF_INIT;
@@ -596,9 +601,6 @@ static unsigned char *clean_url(chunk *url, int is_email)
if (url->len == 0)
return NULL;
- if (is_email)
- strbuf_puts(&buf, "mailto:");
-
if (url->data[0] == '<' && url->data[url->len - 1] == '>') {
houdini_unescape_html_f(&buf, url->data + 1, url->len - 2);
} else {
@@ -609,6 +611,22 @@ static unsigned char *clean_url(chunk *url, int is_email)
return strbuf_detach(&buf);
}
+static unsigned char *clean_autolink(chunk *url, int is_email)
+{
+ strbuf buf = GH_BUF_INIT;
+
+ chunk_trim(url);
+
+ if (url->len == 0)
+ return NULL;
+
+ if (is_email)
+ strbuf_puts(&buf, "mailto:");
+
+ houdini_unescape_html_f(&buf, url->data, url->len);
+ return strbuf_detach(&buf);
+}
+
// Clean a title: remove surrounding quotes and remove \ that escape punctuation.
static unsigned char *clean_title(chunk *title)
{
@@ -649,11 +667,9 @@ static node_inl* handle_pointy_brace(subject* subj)
contents = chunk_dup(&subj->input, subj->pos, matchlen - 1);
subj->pos += matchlen;
- return make_link(
+ return make_autolink(
make_str_with_entities(&contents),
- contents,
- chunk_literal(""),
- 0
+ contents, 0
);
}
@@ -663,11 +679,9 @@ static node_inl* handle_pointy_brace(subject* subj)
contents = chunk_dup(&subj->input, subj->pos, matchlen - 1);
subj->pos += matchlen;
- return make_link(
+ return make_autolink(
make_str_with_entities(&contents),
- contents,
- chunk_literal(""),
- 1
+ contents, 1
);
}
@@ -792,7 +806,7 @@ static node_inl* handle_left_bracket(subject* subj)
title = chunk_dup(&subj->input, starttitle, endtitle - starttitle);
lab = parse_chunk_inlines(&rawlabel, NULL);
- return make_link(lab, url, title, 0);
+ return make_link(lab, url, title);
} else {
// if we get here, we matched a label but didn't get further:
subj->pos = endlabel;
@@ -823,7 +837,7 @@ static node_inl* handle_left_bracket(subject* subj)
ref = lookup_reference(subj->reference_map, &reflabel);
if (ref != NULL) { // found
lab = parse_chunk_inlines(&rawlabel, NULL);
- result = make_link_from_reference(lab, ref);
+ result = make_ref_link(lab, ref);
} else {
subj->pos = endlabel;
lab = parse_chunk_inlines(&rawlabel, subj->reference_map);
--
cgit v1.2.3
From 7426f9ae60272a19bd4611b8579647118033a1e6 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Sun, 7 Sep 2014 22:48:33 +0200
Subject: Abstract the Block union
---
src/blocks.c | 94 +++++++++++++++++++++++++++------------------------------
src/html/html.c | 8 ++---
src/print.c | 11 +++----
src/stmd.h | 20 +++++++-----
4 files changed, 67 insertions(+), 66 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index 8c7d49c..72b2dc2 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -18,35 +18,32 @@ static void finalize(node_block* b, int line_number);
static node_block* make_block(int tag, int start_line, int start_column)
{
node_block* e;
- e = (node_block*) malloc(sizeof(node_block));
+
+ e = malloc(sizeof(node_block));
+ memset(e, 0x0, sizeof(*e));
+
e->tag = tag;
e->open = true;
- e->last_line_blank = false;
e->start_line = start_line;
e->start_column = start_column;
e->end_line = start_line;
- e->children = NULL;
- e->last_child = NULL;
- e->parent = NULL;
- e->top = NULL;
- e->attributes.refmap = NULL;
strbuf_init(&e->string_content, 32);
- e->inline_content = NULL;
- e->next = NULL;
- e->prev = NULL;
+
return e;
}
// Create a root document node_block.
extern node_block* make_document()
{
- node_block * e = make_block(BLOCK_DOCUMENT, 1, 1);
- reference * map = NULL;
+ node_block *e = make_block(BLOCK_DOCUMENT, 1, 1);
+ reference *map = NULL;
reference ** refmap;
+
refmap = (reference**) malloc(sizeof(reference*));
*refmap = map;
- e->attributes.refmap = refmap;
+ e->as.document.refmap = refmap;
e->top = e;
+
return e;
}
@@ -128,8 +125,8 @@ static bool ends_with_blank_line(node_block* node_block)
// Break out of all containing lists
static int break_out_of_lists(node_block ** bptr, int line_number)
{
- node_block * container = *bptr;
- node_block * b = container->top;
+ node_block *container = *bptr;
+ node_block *b = container->top;
// find first containing BLOCK_LIST:
while (b && b->tag != BLOCK_LIST) {
b = b->last_child;
@@ -167,7 +164,7 @@ static void finalize(node_block* b, int line_number)
case BLOCK_PARAGRAPH:
pos = 0;
while (strbuf_at(&b->string_content, 0) == '[' &&
- (pos = parse_reference(&b->string_content, b->top->attributes.refmap))) {
+ (pos = parse_reference(&b->string_content, b->top->as.document.refmap))) {
strbuf_drop(&b->string_content, pos);
}
@@ -185,27 +182,27 @@ static void finalize(node_block* b, int line_number)
// first line of contents becomes info
firstlinelen = strbuf_strchr(&b->string_content, '\n', 0);
- strbuf_init(&b->attributes.fenced_code_data.info, 0);
+ strbuf_init(&b->as.code.info, 0);
houdini_unescape_html_f(
- &b->attributes.fenced_code_data.info,
+ &b->as.code.info,
b->string_content.ptr,
firstlinelen
);
strbuf_drop(&b->string_content, firstlinelen + 1);
- strbuf_trim(&b->attributes.fenced_code_data.info);
- unescape_buffer(&b->attributes.fenced_code_data.info);
+ strbuf_trim(&b->as.code.info);
+ unescape_buffer(&b->as.code.info);
break;
case BLOCK_LIST: // determine tight/loose status
- b->attributes.list_data.tight = true; // tight by default
+ b->as.list.tight = true; // tight by default
item = b->children;
while (item) {
// check for non-final non-empty list item ending with blank line:
if (item->last_line_blank && item->next) {
- b->attributes.list_data.tight = false;
+ b->as.list.tight = false;
break;
}
// recurse into children of list item, to see if there are
@@ -214,12 +211,12 @@ static void finalize(node_block* b, int line_number)
while (subitem) {
if (ends_with_blank_line(subitem) &&
(item->next || subitem->next)) {
- b->attributes.list_data.tight = false;
+ b->as.list.tight = false;
break;
}
subitem = subitem->next;
}
- if (!(b->attributes.list_data.tight)) {
+ if (!(b->as.list.tight)) {
break;
}
item = item->next;
@@ -269,9 +266,9 @@ extern void free_blocks(node_block* e)
free_inlines(e->inline_content);
strbuf_free(&e->string_content);
if (e->tag == BLOCK_FENCED_CODE) {
- strbuf_free(&e->attributes.fenced_code_data.info);
+ strbuf_free(&e->as.code.info);
} else if (e->tag == BLOCK_DOCUMENT) {
- free_reference_map(e->attributes.refmap);
+ free_reference_map(e->as.document.refmap);
}
free_blocks(e->children);
free(e);
@@ -362,13 +359,12 @@ static int parse_list_marker(chunk *input, int pos, struct ListData ** dataptr)
}
// Return 1 if list item belongs in list, else 0.
-static int lists_match(struct ListData list_data,
- struct ListData item_data)
+static int lists_match(struct ListData *list_data, struct ListData *item_data)
{
- return (list_data.list_type == item_data.list_type &&
- list_data.delimiter == item_data.delimiter &&
- // list_data.marker_offset == item_data.marker_offset &&
- list_data.bullet_char == item_data.bullet_char);
+ return (list_data->list_type == item_data->list_type &&
+ list_data->delimiter == item_data->delimiter &&
+ // list_data->marker_offset == item_data.marker_offset &&
+ list_data->bullet_char == item_data->bullet_char);
}
static node_block *finalize_document(node_block *document, int linenum)
@@ -379,7 +375,7 @@ static node_block *finalize_document(node_block *document, int linenum)
}
finalize(document, linenum);
- process_inlines(document, document->attributes.refmap);
+ process_inlines(document, document->as.document.refmap);
return document;
}
@@ -496,10 +492,10 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
} else if (container->tag == BLOCK_LIST_ITEM) {
- if (indent >= container->attributes.list_data.marker_offset +
- container->attributes.list_data.padding) {
- offset += container->attributes.list_data.marker_offset +
- container->attributes.list_data.padding;
+ if (indent >= container->as.list.marker_offset +
+ container->as.list.padding) {
+ offset += container->as.list.marker_offset +
+ container->as.list.padding;
} else if (blank) {
offset = first_nonspace;
} else {
@@ -525,7 +521,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
} else if (container->tag == BLOCK_FENCED_CODE) {
// skip optional spaces of fence offset
- i = container->attributes.fenced_code_data.fence_offset;
+ i = container->as.code.fence_offset;
while (i > 0 && peek_at(&input, offset) == ' ') {
offset++;
i--;
@@ -598,14 +594,14 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
level++;
hashpos++;
}
- container->attributes.header_level = level;
+ container->as.header.level = level;
} else if ((matched = scan_open_code_fence(&input, first_nonspace))) {
container = add_child(container, BLOCK_FENCED_CODE, line_number, first_nonspace + 1);
- container->attributes.fenced_code_data.fence_char = peek_at(&input, first_nonspace);
- container->attributes.fenced_code_data.fence_length = matched;
- container->attributes.fenced_code_data.fence_offset = first_nonspace - offset;
+ container->as.code.fence_char = peek_at(&input, first_nonspace);
+ container->as.code.fence_length = matched;
+ container->as.code.fence_offset = first_nonspace - offset;
offset = first_nonspace + matched;
} else if ((matched = scan_html_block_tag(&input, first_nonspace))) {
@@ -620,7 +616,7 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
strbuf_len(&container->string_content) - 2) < 0) {
container->tag = BLOCK_SETEXT_HEADER;
- container->attributes.header_level = lev;
+ container->as.header.level = lev;
offset = input.len - 1;
} else if (!(container->tag == BLOCK_PARAGRAPH && !all_matched) &&
@@ -657,19 +653,19 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
data->marker_offset = indent;
if (container->tag != BLOCK_LIST ||
- !lists_match(container->attributes.list_data, *data)) {
+ !lists_match(&container->as.list, data)) {
container = add_child(container, BLOCK_LIST, line_number,
first_nonspace + 1);
- container->attributes.list_data = *data;
+
+ memcpy(&container->as.list, data, sizeof(*data));
}
// add the list item
container = add_child(container, BLOCK_LIST_ITEM, line_number,
first_nonspace + 1);
/* TODO: static */
- container->attributes.list_data = *data;
+ memcpy(&container->as.list, data, sizeof(*data));
free(data);
-
} else {
break;
}
@@ -732,9 +728,9 @@ static void incorporate_line(strbuf *line, int line_number, node_block** curptr)
matched = 0;
if (indent <= 3 &&
- peek_at(&input, first_nonspace) == container->attributes.fenced_code_data.fence_char) {
+ peek_at(&input, first_nonspace) == container->as.code.fence_char) {
int fence_len = scan_close_code_fence(&input, first_nonspace);
- if (fence_len > container->attributes.fenced_code_data.fence_length)
+ if (fence_len > container->as.code.fence_length)
matched = 1;
}
diff --git a/src/html/html.c b/src/html/html.c
index 595dfcd..129335f 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -72,7 +72,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
case BLOCK_LIST:
// make sure a list starts at the beginning of the line:
cr(html);
- data = &(b->attributes.list_data);
+ data = &(b->as.list);
if (data->start > 1) {
strbuf_printf(html, "<%s start=\"%d\">\n",
@@ -90,9 +90,9 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
case BLOCK_ATX_HEADER:
case BLOCK_SETEXT_HEADER:
cr(html);
- strbuf_printf(html, "", b->attributes.header_level);
+ strbuf_printf(html, "", b->as.header.level);
inlines_to_html(html, b->inline_content);
- strbuf_printf(html, "\n", b->attributes.header_level);
+ strbuf_printf(html, "\n", b->as.header.level);
break;
case BLOCK_INDENTED_CODE:
@@ -102,7 +102,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
strbuf_puts(html, "tag == BLOCK_FENCED_CODE) {
- strbuf *info = &b->attributes.fenced_code_data.info;
+ strbuf *info = &b->as.code.info;
if (strbuf_len(info) > 0) {
int first_tag = strbuf_strchr(info, ' ', 0);
diff --git a/src/print.c b/src/print.c
index 9240dac..36140a8 100644
--- a/src/print.c
+++ b/src/print.c
@@ -54,12 +54,11 @@ extern void print_blocks(node_block* b, int indent)
print_blocks(b->children, indent + 2);
break;
case BLOCK_LIST_ITEM:
- data = &(b->attributes.list_data);
printf("list_item\n");
print_blocks(b->children, indent + 2);
break;
case BLOCK_LIST:
- data = &(b->attributes.list_data);
+ data = &(b->as.list);
if (data->list_type == ordered) {
printf("list (type=ordered tight=%s start=%d delim=%s)\n",
(data->tight ? "true" : "false"),
@@ -73,11 +72,11 @@ extern void print_blocks(node_block* b, int indent)
print_blocks(b->children, indent + 2);
break;
case BLOCK_ATX_HEADER:
- printf("atx_header (level=%d)\n", b->attributes.header_level);
+ printf("atx_header (level=%d)\n", b->as.header.level);
print_inlines(b->inline_content, indent + 2);
break;
case BLOCK_SETEXT_HEADER:
- printf("setext_header (level=%d)\n", b->attributes.header_level);
+ printf("setext_header (level=%d)\n", b->as.header.level);
print_inlines(b->inline_content, indent + 2);
break;
case BLOCK_PARAGRAPH:
@@ -94,8 +93,8 @@ extern void print_blocks(node_block* b, int indent)
break;
case BLOCK_FENCED_CODE:
printf("fenced_code length=%d info=",
- b->attributes.fenced_code_data.fence_length);
- print_str(b->attributes.fenced_code_data.info.ptr, -1);
+ b->as.code.fence_length);
+ print_str(b->as.code.info.ptr, -1);
putchar(' ');
print_str(b->string_content.ptr, -1);
putchar('\n');
diff --git a/src/stmd.h b/src/stmd.h
index c80eeda..21a86b0 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -96,14 +96,20 @@ struct node_block {
struct node_block* top;
strbuf string_content;
node_inl* inline_content;
+
union {
- struct ListData list_data;
- struct FencedCodeData fenced_code_data;
- int header_level;
- reference** refmap;
- } attributes;
- struct node_block * next;
- struct node_block * prev;
+ struct ListData list;
+ struct FencedCodeData code;
+ struct {
+ int level;
+ } header;
+ struct {
+ reference** refmap;
+ } document;
+ } as;
+
+ struct node_block *next;
+ struct node_block *prev;
};
typedef struct node_block node_block;
--
cgit v1.2.3
From 2c06fa95fd3059a099bbe403beaf62f2e033f5b7 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 9 Sep 2014 03:42:05 +0200
Subject: Fix the class attribute for code fences
---
src/html/html.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/html/html.c b/src/html/html.c
index 129335f..74f6791 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -99,7 +99,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
case BLOCK_FENCED_CODE:
cr(html);
- strbuf_puts(html, "tag == BLOCK_FENCED_CODE) {
strbuf *info = &b->as.code.info;
@@ -109,14 +109,13 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
if (first_tag < 0)
first_tag = strbuf_len(info);
-
- strbuf_puts(html, " class=\"");
+ strbuf_puts(html, " class=\"lang-");
escape_html(html, info->ptr, first_tag);
strbuf_putc(html, '"');
}
}
- strbuf_puts(html, ">");
+ strbuf_putc(html, '>');
escape_html(html, b->string_content.ptr, b->string_content.size);
strbuf_puts(html, "
\n");
break;
--
cgit v1.2.3
From d21ef7b5db11075e038e60732682dfd8a5cf6a13 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 9 Sep 2014 03:42:46 +0200
Subject: Oops
---
src/html/html.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/html/html.c b/src/html/html.c
index 74f6791..b48b10b 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -109,7 +109,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
if (first_tag < 0)
first_tag = strbuf_len(info);
- strbuf_puts(html, " class=\"lang-");
+ strbuf_puts(html, " class=\"language-");
escape_html(html, info->ptr, first_tag);
strbuf_putc(html, '"');
}
--
cgit v1.2.3
From 9d86d2f32303ae0048f6a5daa552bacceb9b12ea Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Tue, 9 Sep 2014 04:00:36 +0200
Subject: Update the spec with better entity handling
---
Makefile | 4 ++--
spec.txt | 22 ++++++++++++----------
src/html/houdini_html_u.c | 2 +-
3 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/Makefile b/Makefile
index b5e487d..5d13272 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-CFLAGS=-g -pg -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-g -pg -O3 -Wall -Werror
+CFLAGS=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS=-g -O3 -Wall -Werror
SRCDIR=src
DATADIR=data
diff --git a/spec.txt b/spec.txt
index ebd6d98..112dccc 100644
--- a/spec.txt
+++ b/spec.txt
@@ -3762,20 +3762,20 @@ as the "unknown codepoint" character (`0xFFFD`)
[Hexadecimal entities](#hexadecimal-entities)
consist of `` + either `X` or `x` + a string of 1-8 hexadecimal digits
-+ `;`.
++ `;`. They will also be parsed and turned into their corresponding UTF8 values in the AST.
.
- " ആ ಫ
+" ആ ಫ
.
- " ആ ಫ
+" ആ ಫ
.
Here are some nonentities:
.
-  &x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;
+  &x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;
.
-  &x; &#; &#x; � &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;
+  &x; &#; &#x; &ThisIsWayTooLongToBeAnEntityIsntIt; &hi?;
.
Although HTML5 does accept some entities without a trailing semicolon
@@ -3808,7 +3808,7 @@ code blocks, including raw HTML, URLs, [link titles](#link-title), and
.
[foo](/föö "föö")
.
-foo
+foo
.
.
@@ -3816,7 +3816,7 @@ code blocks, including raw HTML, URLs, [link titles](#link-title), and
[foo]: /föö "föö"
.
-foo
+foo
.
.
@@ -3824,7 +3824,7 @@ code blocks, including raw HTML, URLs, [link titles](#link-title), and
foo
```
.
-foo
+foo
.
@@ -4817,12 +4817,14 @@ in Markdown:
link
.
-URL-escaping and entities should be left alone inside the destination:
+URL-escaping and should be left alone inside the destination, as all URL-escaped characters
+are also valid URL characters. HTML entities in the destination will be parsed into their UTF8
+codepoints, as usual, and optionally URL-escaped when written as HTML.
.
[link](foo%20bä)
.
-link
+link
.
Note that, because titles can often be parsed as destinations,
diff --git a/src/html/houdini_html_u.c b/src/html/houdini_html_u.c
index 762f980..b8e2d8d 100644
--- a/src/html/houdini_html_u.c
+++ b/src/html/houdini_html_u.c
@@ -24,7 +24,7 @@ houdini_unescape_ent(strbuf *ob, const uint8_t *src, size_t size)
codepoint = (codepoint * 16) + ((src[i] | 32) % 39 - 9);
}
- if (i < size && src[i] == ';') {
+ if (i < size && src[i] == ';' && codepoint) {
utf8proc_encode_char(codepoint, ob);
return i + 1;
}
--
cgit v1.2.3
From 3567b844ca1fd7bec62801f8758545f7bd5cbaae Mon Sep 17 00:00:00 2001
From: Kārlis Gaņģis
Date: Wed, 10 Sep 2014 00:11:35 +0300
Subject: Moved removal of `\r` into `tidy()`
---
runtests.pl | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/runtests.pl b/runtests.pl
index d847140..f3e91ca 100644
--- a/runtests.pl
+++ b/runtests.pl
@@ -38,7 +38,9 @@ sub tidy
} elsif (/<\/pre/) {
$inpre = 0;
}
- if ($inpre) {
+ # remove \r to allow mixing linux/windows newlines
+ s/\r//;
+ if ($inpre) {
print $outfh $_;
} else {
# remove leading spaces
@@ -79,11 +81,7 @@ sub dotest
$html = &tidy($html);
$actual = &tidy($actual);
$actual =~ s/\'/'/;
-
- # remove \r to allow mixing of linux/windows newlines
- $actual =~ s/\r//g;
- $html =~ s/\r//g;
-
+
if ($actual eq $html) {
print colored("✓", "green");
return 1;
--
cgit v1.2.3
From 94a79a605f3e76a43f1f87a5044f6761b99e5ca5 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 18:33:27 +0200
Subject: Cleanup reference implementation
---
Makefile | 2 +-
src/blocks.c | 16 ++---
src/buffer.c | 43 ++++++++++++++
src/buffer.h | 2 +
src/inlines.c | 176 +++++++------------------------------------------------
src/references.c | 109 ++++++++++++++++++++++++++++++++++
src/references.h | 27 +++++++++
src/stmd.h | 26 +++-----
src/utf8.c | 10 ++--
src/utf8.h | 5 +-
10 files changed, 225 insertions(+), 191 deletions(-)
create mode 100644 src/references.c
create mode 100644 src/references.h
diff --git a/Makefile b/Makefile
index 5d13272..11e2141 100644
--- a/Makefile
+++ b/Makefile
@@ -42,7 +42,7 @@ benchjs:
node js/bench.js ${BENCHINP}
HTML_OBJ=$(SRCDIR)/html/html.o $(SRCDIR)/html/houdini_href_e.o $(SRCDIR)/html/houdini_html_e.o $(SRCDIR)/html/houdini_html_u.o
-STMD_OBJ=$(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/utf8.o
+STMD_OBJ=$(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/utf8.o $(SRCDIR)/references.c
$(PROG): $(SRCDIR)/html/html_unescape.h $(SRCDIR)/case_fold_switch.inc $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c
$(CC) $(LDFLAGS) -o $@ $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c
diff --git a/src/blocks.c b/src/blocks.c
index 72b2dc2..30a8284 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -8,7 +8,6 @@
#include "utf8.h"
#include "html/houdini.h"
#include "scanners.h"
-#include "uthash.h"
#define peek_at(i, n) (i)->data[n]
@@ -36,12 +35,7 @@ static node_block* make_block(int tag, int start_line, int start_column)
extern node_block* make_document()
{
node_block *e = make_block(BLOCK_DOCUMENT, 1, 1);
- reference *map = NULL;
- reference ** refmap;
-
- refmap = (reference**) malloc(sizeof(reference*));
- *refmap = map;
- e->as.document.refmap = refmap;
+ e->as.document.refmap = reference_map_new();
e->top = e;
return e;
@@ -164,7 +158,7 @@ static void finalize(node_block* b, int line_number)
case BLOCK_PARAGRAPH:
pos = 0;
while (strbuf_at(&b->string_content, 0) == '[' &&
- (pos = parse_reference(&b->string_content, b->top->as.document.refmap))) {
+ (pos = parse_reference_inline(&b->string_content, b->top->as.document.refmap))) {
strbuf_drop(&b->string_content, pos);
}
@@ -192,7 +186,7 @@ static void finalize(node_block* b, int line_number)
strbuf_drop(&b->string_content, firstlinelen + 1);
strbuf_trim(&b->as.code.info);
- unescape_buffer(&b->as.code.info);
+ strbuf_unescape(&b->as.code.info);
break;
case BLOCK_LIST: // determine tight/loose status
@@ -268,7 +262,7 @@ extern void free_blocks(node_block* e)
if (e->tag == BLOCK_FENCED_CODE) {
strbuf_free(&e->as.code.info);
} else if (e->tag == BLOCK_DOCUMENT) {
- free_reference_map(e->as.document.refmap);
+ reference_map_free(e->as.document.refmap);
}
free_blocks(e->children);
free(e);
@@ -278,7 +272,7 @@ extern void free_blocks(node_block* e)
// Walk through node_block and all children, recursively, parsing
// string content into inline content where appropriate.
-void process_inlines(node_block* cur, reference** refmap)
+void process_inlines(node_block* cur, reference_map *refmap)
{
switch (cur->tag) {
case BLOCK_PARAGRAPH:
diff --git a/src/buffer.c b/src/buffer.c
index 90c2186..cdf8ca0 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -308,3 +308,46 @@ void strbuf_trim(strbuf *buf)
buf->ptr[buf->size] = '\0';
}
+
+// Destructively modify string, collapsing consecutive
+// space and newline characters into a single space.
+void strbuf_normalize_whitespace(strbuf *s)
+{
+ bool last_char_was_space = false;
+ int r, w;
+
+ for (r = 0, w = 0; r < s->size; ++r) {
+ switch (s->ptr[r]) {
+ case ' ':
+ case '\n':
+ if (last_char_was_space)
+ break;
+
+ s->ptr[w++] = ' ';
+ last_char_was_space = true;
+ break;
+
+ default:
+ s->ptr[w++] = s->ptr[r];
+ last_char_was_space = false;
+ }
+ }
+
+ strbuf_truncate(s, w);
+}
+
+// Destructively unescape a string: remove backslashes before punctuation chars.
+extern void strbuf_unescape(strbuf *buf)
+{
+ int r, w;
+
+ for (r = 0, w = 0; r < buf->size; ++r) {
+ if (buf->ptr[r] == '\\' && ispunct(buf->ptr[r + 1]))
+ continue;
+
+ buf->ptr[w++] = buf->ptr[r];
+ }
+
+ strbuf_truncate(buf, w);
+}
+
diff --git a/src/buffer.h b/src/buffer.h
index 6f45cbb..1bc1eee 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -108,5 +108,7 @@ int strbuf_strrchr(const strbuf *buf, int c, int pos);
void strbuf_drop(strbuf *buf, int n);
void strbuf_truncate(strbuf *buf, int len);
void strbuf_trim(strbuf *buf);
+void strbuf_normalize_whitespace(strbuf *s);
+void strbuf_unescape(strbuf *s);
#endif
diff --git a/src/inlines.c b/src/inlines.c
index aa0e13e..3040f09 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -7,110 +7,23 @@
#include "stmd.h"
#include "html/houdini.h"
#include "utf8.h"
-#include "uthash.h"
#include "scanners.h"
typedef struct Subject {
chunk input;
int pos;
- int label_nestlevel;
- reference** reference_map;
+ int label_nestlevel;
+ reference_map *refmap;
} subject;
-reference* lookup_reference(reference** refmap, chunk *label);
-reference* make_reference(chunk *label, chunk *url, chunk *title);
-
-static unsigned char *clean_url(chunk *url);
-static unsigned char *clean_title(chunk *title);
-static unsigned char *clean_autolink(chunk *url, int is_email);
-
-inline static void chunk_free(chunk *c);
-inline static void chunk_trim(chunk *c);
-
-inline static chunk chunk_literal(const char *data);
-inline static chunk chunk_buf_detach(strbuf *buf);
-inline static chunk chunk_dup(const chunk *ch, int pos, int len);
-
-static node_inl *parse_chunk_inlines(chunk *chunk, reference** refmap);
+static node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap);
static node_inl *parse_inlines_while(subject* subj, int (*f)(subject*));
static int parse_inline(subject* subj, node_inl ** last);
-static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap);
-static void subject_from_buf(subject *e, strbuf *buffer, reference** refmap);
+static void subject_from_chunk(subject *e, chunk *chunk, reference_map *refmap);
+static void subject_from_buf(subject *e, strbuf *buffer, reference_map *refmap);
static int subject_find_special_char(subject *subj);
-static void normalize_whitespace(strbuf *s);
-
-extern void free_reference(reference *ref) {
- free(ref->label);
- free(ref->url);
- free(ref->title);
- free(ref);
-}
-
-extern void free_reference_map(reference **refmap) {
- /* free the hash table contents */
- reference *s;
- reference *tmp;
- if (refmap != NULL) {
- HASH_ITER(hh, *refmap, s, tmp) {
- HASH_DEL(*refmap, s);
- free_reference(s);
- }
- free(refmap);
- }
-}
-
-// normalize reference: collapse internal whitespace to single space,
-// remove leading/trailing whitespace, case fold
-static unsigned char *normalize_reference(chunk *ref)
-{
- strbuf normalized = GH_BUF_INIT;
-
- utf8proc_case_fold(&normalized, ref->data, ref->len);
- strbuf_trim(&normalized);
- normalize_whitespace(&normalized);
-
- return strbuf_detach(&normalized);
-}
-
-// Returns reference if refmap contains a reference with matching
-// label, otherwise NULL.
-extern reference* lookup_reference(reference** refmap, chunk *label)
-{
- reference *ref = NULL;
- unsigned char *norm = normalize_reference(label);
- if (refmap != NULL) {
- HASH_FIND_STR(*refmap, (char*)norm, ref);
- }
- free(norm);
- return ref;
-}
-
-extern reference* make_reference(chunk *label, chunk *url, chunk *title)
-{
- reference *ref;
- ref = malloc(sizeof(reference));
- ref->label = normalize_reference(label);
- ref->url = clean_url(url);
- ref->title = clean_title(title);
- return ref;
-}
-
-extern void add_reference(reference** refmap, reference* ref)
-{
- reference * t = NULL;
- const char *label = (const char *)ref->label;
-
- HASH_FIND(hh, *refmap, label, strlen(label), t);
-
- if (t == NULL) {
- HASH_ADD_KEYPTR(hh, *refmap, label, strlen(label), ref);
- } else {
- free_reference(ref); // we free this now since it won't be in the refmap
- }
-}
-
static unsigned char *bufdup(const unsigned char *buf)
{
unsigned char *new = NULL;
@@ -236,26 +149,26 @@ inline static node_inl* append_inlines(node_inl* a, node_inl* b)
return a;
}
-static void subject_from_buf(subject *e, strbuf *buffer, reference** refmap)
+static void subject_from_buf(subject *e, strbuf *buffer, reference_map *refmap)
{
e->input.data = buffer->ptr;
e->input.len = buffer->size;
e->input.alloc = 0;
e->pos = 0;
e->label_nestlevel = 0;
- e->reference_map = refmap;
+ e->refmap = refmap;
chunk_rtrim(&e->input);
}
-static void subject_from_chunk(subject *e, chunk *chunk, reference** refmap)
+static void subject_from_chunk(subject *e, chunk *chunk, reference_map *refmap)
{
e->input.data = chunk->data;
e->input.len = chunk->len;
e->input.alloc = 0;
e->pos = 0;
e->label_nestlevel = 0;
- e->reference_map = refmap;
+ e->refmap = refmap;
chunk_rtrim(&e->input);
}
@@ -325,33 +238,6 @@ static int scan_to_closing_backticks(subject* subj, int openticklength)
return (subj->pos);
}
-// Destructively modify string, collapsing consecutive
-// space and newline characters into a single space.
-static void normalize_whitespace(strbuf *s)
-{
- bool last_char_was_space = false;
- int r, w;
-
- for (r = 0, w = 0; r < s->size; ++r) {
- switch (s->ptr[r]) {
- case ' ':
- case '\n':
- if (last_char_was_space)
- break;
-
- s->ptr[w++] = ' ';
- last_char_was_space = true;
- break;
-
- default:
- s->ptr[w++] = s->ptr[r];
- last_char_was_space = false;
- }
- }
-
- strbuf_truncate(s, w);
-}
-
// Parse backtick code section or raw backticks, return an inline.
// Assumes that the subject has a backtick at the current position.
static node_inl* handle_backticks(subject *subj)
@@ -368,7 +254,7 @@ static node_inl* handle_backticks(subject *subj)
strbuf_set(&buf, subj->input.data + startpos, endpos - startpos - openticks.len);
strbuf_trim(&buf);
- normalize_whitespace(&buf);
+ strbuf_normalize_whitespace(&buf);
return make_code(chunk_buf_detach(&buf));
}
@@ -575,24 +461,9 @@ static node_inl *make_str_with_entities(chunk *content)
}
}
-// Destructively unescape a string: remove backslashes before punctuation chars.
-extern void unescape_buffer(strbuf *buf)
-{
- int r, w;
-
- for (r = 0, w = 0; r < buf->size; ++r) {
- if (buf->ptr[r] == '\\' && ispunct(buf->ptr[r + 1]))
- continue;
-
- buf->ptr[w++] = buf->ptr[r];
- }
-
- strbuf_truncate(buf, w);
-}
-
// Clean a URL: remove surrounding whitespace and surrounding <>,
// and remove \ that escape punctuation.
-static unsigned char *clean_url(chunk *url)
+unsigned char *clean_url(chunk *url)
{
strbuf buf = GH_BUF_INIT;
@@ -607,11 +478,11 @@ static unsigned char *clean_url(chunk *url)
houdini_unescape_html_f(&buf, url->data, url->len);
}
- unescape_buffer(&buf);
+ strbuf_unescape(&buf);
return strbuf_detach(&buf);
}
-static unsigned char *clean_autolink(chunk *url, int is_email)
+unsigned char *clean_autolink(chunk *url, int is_email)
{
strbuf buf = GH_BUF_INIT;
@@ -628,7 +499,7 @@ static unsigned char *clean_autolink(chunk *url, int is_email)
}
// Clean a title: remove surrounding quotes and remove \ that escape punctuation.
-static unsigned char *clean_title(chunk *title)
+unsigned char *clean_title(chunk *title)
{
strbuf buf = GH_BUF_INIT;
unsigned char first, last;
@@ -648,7 +519,7 @@ static unsigned char *clean_title(chunk *title)
houdini_unescape_html_f(&buf, title->data, title->len);
}
- unescape_buffer(&buf);
+ strbuf_unescape(&buf);
return strbuf_detach(&buf);
}
@@ -810,7 +681,7 @@ static node_inl* handle_left_bracket(subject* subj)
} else {
// if we get here, we matched a label but didn't get further:
subj->pos = endlabel;
- lab = parse_chunk_inlines(&rawlabel, subj->reference_map);
+ lab = parse_chunk_inlines(&rawlabel, subj->refmap);
result = append_inlines(make_str(chunk_literal("[")),
append_inlines(lab,
make_str(chunk_literal("]"))));
@@ -834,13 +705,13 @@ static node_inl* handle_left_bracket(subject* subj)
}
// lookup rawlabel in subject->reference_map:
- ref = lookup_reference(subj->reference_map, &reflabel);
+ ref = reference_lookup(subj->refmap, &reflabel);
if (ref != NULL) { // found
lab = parse_chunk_inlines(&rawlabel, NULL);
result = make_ref_link(lab, ref);
} else {
subj->pos = endlabel;
- lab = parse_chunk_inlines(&rawlabel, subj->reference_map);
+ lab = parse_chunk_inlines(&rawlabel, subj->refmap);
result = append_inlines(make_str(chunk_literal("[")),
append_inlines(lab, make_str(chunk_literal("]"))));
}
@@ -887,7 +758,7 @@ extern node_inl* parse_inlines_while(subject* subj, int (*f)(subject*))
return result;
}
-node_inl *parse_chunk_inlines(chunk *chunk, reference** refmap)
+node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap)
{
subject subj;
subject_from_chunk(&subj, chunk, refmap);
@@ -987,7 +858,7 @@ static int parse_inline(subject* subj, node_inl ** last)
return 1;
}
-extern node_inl* parse_inlines(strbuf *input, reference** refmap)
+extern node_inl* parse_inlines(strbuf *input, reference_map *refmap)
{
subject subj;
subject_from_buf(&subj, input, refmap);
@@ -1009,7 +880,7 @@ void spnl(subject* subj)
// Modify refmap if a reference is encountered.
// Return 0 if no reference found, otherwise position of subject
// after reference is parsed.
-extern int parse_reference(strbuf *input, reference** refmap)
+int parse_reference_inline(strbuf *input, reference_map *refmap)
{
subject subj;
@@ -1019,7 +890,6 @@ extern int parse_reference(strbuf *input, reference** refmap)
int matchlen = 0;
int beforetitle;
- reference *new = NULL;
subject_from_buf(&subj, input, NULL);
@@ -1065,9 +935,7 @@ extern int parse_reference(strbuf *input, reference** refmap)
return 0;
}
// insert reference into refmap
- new = make_reference(&lab, &url, &title);
- add_reference(refmap, new);
-
+ reference_create(refmap, &lab, &url, &title);
return subj.pos;
}
diff --git a/src/references.c b/src/references.c
new file mode 100644
index 0000000..ff64b00
--- /dev/null
+++ b/src/references.c
@@ -0,0 +1,109 @@
+#include "stmd.h"
+#include "utf8.h"
+#include "references.h"
+
+static unsigned int
+refhash(const unsigned char *link_ref)
+{
+ unsigned int hash = 0;
+
+ while (*link_ref)
+ hash = (*link_ref++) + (hash << 6) + (hash << 16) - hash;
+
+ return hash;
+}
+
+// normalize reference: collapse internal whitespace to single space,
+// remove leading/trailing whitespace, case fold
+static unsigned char *normalize_reference(chunk *ref)
+{
+ strbuf normalized = GH_BUF_INIT;
+
+ utf8proc_case_fold(&normalized, ref->data, ref->len);
+ strbuf_trim(&normalized);
+ strbuf_normalize_whitespace(&normalized);
+
+ return strbuf_detach(&normalized);
+}
+
+static void add_reference(reference_map *map, reference* ref)
+{
+ ref->next = map->table[ref->hash % REFMAP_SIZE];
+ map->table[ref->hash % REFMAP_SIZE] = ref;
+}
+
+extern reference *reference_create(reference_map *map, chunk *label, chunk *url, chunk *title)
+{
+ reference *ref;
+ ref = malloc(sizeof(reference));
+ ref->label = normalize_reference(label);
+ ref->hash = refhash(ref->label);
+ ref->url = clean_url(url);
+ ref->title = clean_title(title);
+ ref->next = NULL;
+
+ add_reference(map, ref);
+
+ return ref;
+}
+
+// Returns reference if refmap contains a reference with matching
+// label, otherwise NULL.
+reference* reference_lookup(reference_map *map, chunk *label)
+{
+ reference *ref = NULL;
+ unsigned char *norm;
+ unsigned int hash;
+
+ if (map == NULL)
+ return NULL;
+
+ norm = normalize_reference(label);
+ hash = refhash(norm);
+ ref = map->table[hash % REFMAP_SIZE];
+
+ while (ref) {
+ if (ref->label[0] == norm[0] &&
+ !strcmp((char *)ref->label, (char *)norm))
+ break;
+ ref = ref->next;
+ }
+
+ free(norm);
+ return ref;
+}
+
+static void reference_free(reference *ref)
+{
+ free(ref->label);
+ free(ref->url);
+ free(ref->title);
+ free(ref);
+}
+
+void reference_map_free(reference_map *map)
+{
+ unsigned int i;
+
+ for (i = 0; i < REFMAP_SIZE; ++i) {
+ reference *ref = map->table[i];
+ reference *next;
+
+ while (ref) {
+ next = ref->next;
+ reference_free(ref);
+ ref = next;
+ }
+ }
+
+ free(map->table);
+ free(map);
+}
+
+reference_map *reference_map_new(void)
+{
+ reference_map *map = malloc(sizeof(reference_map));
+ memset(map, 0x0, sizeof(reference_map));
+ return map;
+}
+
diff --git a/src/references.h b/src/references.h
new file mode 100644
index 0000000..78fffe7
--- /dev/null
+++ b/src/references.h
@@ -0,0 +1,27 @@
+#ifndef _REFERENCES_H_
+#define _REFERENCES_H_
+
+#define REFMAP_SIZE 16
+
+struct reference {
+ struct reference *next;
+ unsigned char *label;
+ unsigned char *url;
+ unsigned char *title;
+ unsigned int hash;
+};
+
+typedef struct reference reference;
+
+struct reference_map {
+ reference *table[REFMAP_SIZE];
+};
+
+typedef struct reference_map reference_map;
+
+reference_map *reference_map_new(void);
+void reference_map_free(reference_map *map);
+reference* reference_lookup(reference_map *map, chunk *label);
+extern reference *reference_create(reference_map *map, chunk *label, chunk *url, chunk *title);
+
+#endif
diff --git a/src/stmd.h b/src/stmd.h
index 21a86b0..4e21e6c 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -5,7 +5,7 @@
#include
#include "buffer.h"
#include "chunk.h"
-#include "uthash.h"
+#include "references.h"
#define VERSION "0.1"
#define CODE_INDENT 4
@@ -36,17 +36,7 @@ struct node_inl {
typedef struct node_inl node_inl;
-struct reference {
- unsigned char *label;
- unsigned char *url;
- unsigned char *title;
- UT_hash_handle hh; // used by uthash
-};
-
-typedef struct reference reference;
-
// Types for blocks
-
struct ListData {
enum {
bullet,
@@ -104,7 +94,7 @@ struct node_block {
int level;
} header;
struct {
- reference** refmap;
+ reference_map *refmap;
} document;
} as;
@@ -114,14 +104,10 @@ struct node_block {
typedef struct node_block node_block;
-node_inl* parse_inlines(strbuf *input, reference** refmap);
+node_inl* parse_inlines(strbuf *input, reference_map *refmap);
void free_inlines(node_inl* e);
-int parse_reference(strbuf *input, reference** refmap);
-void free_reference(reference *ref);
-void free_reference_map(reference **refmap);
-
-void add_reference(reference** refmap, reference* ref);
+int parse_reference_inline(strbuf *input, reference_map *refmap);
void unescape_buffer(strbuf *buf);
extern node_block* make_document();
@@ -138,4 +124,8 @@ void print_blocks(node_block* blk, int indent);
void blocks_to_html(strbuf *html, node_block *b, bool tight);
void inlines_to_html(strbuf *html, node_inl *b);
+unsigned char *clean_url(chunk *url);
+unsigned char *clean_autolink(chunk *url, int is_email);
+unsigned char *clean_title(chunk *title);
+
#endif
diff --git a/src/utf8.c b/src/utf8.c
index 12d7ba5..c65aec6 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -25,7 +25,7 @@ static const int8_t utf8proc_utf8class[256] = {
static void encode_unknown(strbuf *buf)
{
- static const unsigned char repl[] = {239, 191, 189};
+ static const uint8_t repl[] = {239, 191, 189};
strbuf_put(buf, repl, 3);
}
@@ -52,9 +52,9 @@ ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len)
return length;
}
-void utf8proc_detab(strbuf *ob, const unsigned char *line, size_t size)
+void utf8proc_detab(strbuf *ob, const uint8_t *line, size_t size)
{
- static const unsigned char whitespace[] = " ";
+ static const uint8_t whitespace[] = " ";
size_t i = 0, tab = 0;
@@ -132,7 +132,7 @@ ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst)
void utf8proc_encode_char(int32_t uc, strbuf *buf)
{
- unsigned char dst[4];
+ uint8_t dst[4];
int len = 0;
assert(uc >= 0);
@@ -169,7 +169,7 @@ void utf8proc_encode_char(int32_t uc, strbuf *buf)
strbuf_put(buf, dst, len);
}
-void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len)
+void utf8proc_case_fold(strbuf *dest, const uint8_t *str, int len)
{
int32_t c;
diff --git a/src/utf8.h b/src/utf8.h
index 1e4e556..9506b75 100644
--- a/src/utf8.h
+++ b/src/utf8.h
@@ -1,12 +1,13 @@
#ifndef _H_STMD_UTF8_
#define _H_STMD_UTF8_
+#include
#include "buffer.h"
-void utf8proc_case_fold(strbuf *dest, const unsigned char *str, int len);
+void utf8proc_case_fold(strbuf *dest, const uint8_t *str, int len);
void utf8proc_encode_char(int32_t uc, strbuf *buf);
ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst);
ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len);
-void utf8proc_detab(strbuf *dest, const unsigned char *line, size_t size);
+void utf8proc_detab(strbuf *dest, const uint8_t *line, size_t size);
#endif
--
cgit v1.2.3
From 0a0a87333083058e945a54fcf196a6f119302d6b Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 18:33:51 +0200
Subject: Remove old hash table
---
src/uthash.h | 948 -----------------------------------------------------------
1 file changed, 948 deletions(-)
delete mode 100644 src/uthash.h
diff --git a/src/uthash.h b/src/uthash.h
deleted file mode 100644
index b9bc7e9..0000000
--- a/src/uthash.h
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
-Copyright (c) 2003-2013, Troy D. Hanson http://troydhanson.github.com/uthash/
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef UTHASH_H
-#define UTHASH_H
-
-#include /* memcmp,strlen */
-#include /* ptrdiff_t */
-#include /* exit() */
-
-/* These macros use decltype or the earlier __typeof GNU extension.
- As decltype is only available in newer compilers (VS2010 or gcc 4.3+
- when compiling c++ source) this code uses whatever method is needed
- or, for VS2008 where neither is available, uses casting workarounds. */
-#ifdef _MSC_VER /* MS compiler */
-#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
-#define DECLTYPE(x) (decltype(x))
-#else /* VS2008 or older (or VS2010 in C mode) */
-#define NO_DECLTYPE
-#define DECLTYPE(x)
-#endif
-#else /* GNU, Sun and other compilers */
-#define DECLTYPE(x) (__typeof(x))
-#endif
-
-#ifdef NO_DECLTYPE
-#define DECLTYPE_ASSIGN(dst,src) \
-do { \
- char **_da_dst = (char**)(&(dst)); \
- *_da_dst = (char*)(src); \
-} while(0)
-#else
-#define DECLTYPE_ASSIGN(dst,src) \
-do { \
- (dst) = DECLTYPE(dst)(src); \
-} while(0)
-#endif
-
-/* a number of the hash function use uint32_t which isn't defined on win32 */
-#ifdef _MSC_VER
-typedef unsigned int uint32_t;
-typedef unsigned char uint8_t;
-#else
-#include /* uint32_t */
-#endif
-
-#define UTHASH_VERSION 1.9.8
-
-#ifndef uthash_fatal
-#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
-#endif
-#ifndef uthash_malloc
-#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
-#endif
-#ifndef uthash_free
-#define uthash_free(ptr,sz) free(ptr) /* free fcn */
-#endif
-
-#ifndef uthash_noexpand_fyi
-#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
-#endif
-#ifndef uthash_expand_fyi
-#define uthash_expand_fyi(tbl) /* can be defined to log expands */
-#endif
-
-/* initial number of buckets */
-#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
-#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
-#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
-
-/* calculate the element whose hash handle address is hhe */
-#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
-
-#define HASH_FIND(hh,head,keyptr,keylen,out) \
-do { \
- unsigned _hf_bkt,_hf_hashv; \
- out=NULL; \
- if (head) { \
- HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
- if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
- HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
- keyptr,keylen,out); \
- } \
- } \
-} while (0)
-
-#ifdef HASH_BLOOM
-#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
-#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
-#define HASH_BLOOM_MAKE(tbl) \
-do { \
- (tbl)->bloom_nbits = HASH_BLOOM; \
- (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
- if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
- memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
- (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
-} while (0)
-
-#define HASH_BLOOM_FREE(tbl) \
-do { \
- uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
-} while (0)
-
-#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
-#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
-
-#define HASH_BLOOM_ADD(tbl,hashv) \
- HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
-
-#define HASH_BLOOM_TEST(tbl,hashv) \
- HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
-
-#else
-#define HASH_BLOOM_MAKE(tbl)
-#define HASH_BLOOM_FREE(tbl)
-#define HASH_BLOOM_ADD(tbl,hashv)
-#define HASH_BLOOM_TEST(tbl,hashv) (1)
-#define HASH_BLOOM_BYTELEN 0
-#endif
-
-#define HASH_MAKE_TABLE(hh,head) \
-do { \
- (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
- sizeof(UT_hash_table)); \
- if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
- memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
- (head)->hh.tbl->tail = &((head)->hh); \
- (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
- (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
- (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
- (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
- HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
- if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
- memset((head)->hh.tbl->buckets, 0, \
- HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
- HASH_BLOOM_MAKE((head)->hh.tbl); \
- (head)->hh.tbl->signature = HASH_SIGNATURE; \
-} while(0)
-
-#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
- HASH_ADD_KEYPTR(hh,head,&((add)->fieldname),keylen_in,add)
-
-#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \
-do { \
- replaced=NULL; \
- HASH_FIND(hh,head,&((add)->fieldname),keylen_in,replaced); \
- if (replaced!=NULL) { \
- HASH_DELETE(hh,head,replaced); \
- }; \
- HASH_ADD(hh,head,fieldname,keylen_in,add); \
-} while(0)
-
-#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
-do { \
- unsigned _ha_bkt; \
- (add)->hh.next = NULL; \
- (add)->hh.key = (char*)(keyptr); \
- (add)->hh.keylen = (unsigned)(keylen_in); \
- if (!(head)) { \
- head = (add); \
- (head)->hh.prev = NULL; \
- HASH_MAKE_TABLE(hh,head); \
- } else { \
- (head)->hh.tbl->tail->next = (add); \
- (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
- (head)->hh.tbl->tail = &((add)->hh); \
- } \
- (head)->hh.tbl->num_items++; \
- (add)->hh.tbl = (head)->hh.tbl; \
- HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
- (add)->hh.hashv, _ha_bkt); \
- HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
- HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
- HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
- HASH_FSCK(hh,head); \
-} while(0)
-
-#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
-do { \
- bkt = ((hashv) & ((num_bkts) - 1)); \
-} while(0)
-
-/* delete "delptr" from the hash table.
- * "the usual" patch-up process for the app-order doubly-linked-list.
- * The use of _hd_hh_del below deserves special explanation.
- * These used to be expressed using (delptr) but that led to a bug
- * if someone used the same symbol for the head and deletee, like
- * HASH_DELETE(hh,users,users);
- * We want that to work, but by changing the head (users) below
- * we were forfeiting our ability to further refer to the deletee (users)
- * in the patch-up process. Solution: use scratch space to
- * copy the deletee pointer, then the latter references are via that
- * scratch pointer rather than through the repointed (users) symbol.
- */
-#define HASH_DELETE(hh,head,delptr) \
-do { \
- unsigned _hd_bkt; \
- struct UT_hash_handle *_hd_hh_del; \
- if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
- uthash_free((head)->hh.tbl->buckets, \
- (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
- HASH_BLOOM_FREE((head)->hh.tbl); \
- uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
- head = NULL; \
- } else { \
- _hd_hh_del = &((delptr)->hh); \
- if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
- (head)->hh.tbl->tail = \
- (UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
- (head)->hh.tbl->hho); \
- } \
- if ((delptr)->hh.prev) { \
- ((UT_hash_handle*)((ptrdiff_t)((delptr)->hh.prev) + \
- (head)->hh.tbl->hho))->next = (delptr)->hh.next; \
- } else { \
- DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
- } \
- if (_hd_hh_del->next) { \
- ((UT_hash_handle*)((ptrdiff_t)_hd_hh_del->next + \
- (head)->hh.tbl->hho))->prev = \
- _hd_hh_del->prev; \
- } \
- HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
- HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
- (head)->hh.tbl->num_items--; \
- } \
- HASH_FSCK(hh,head); \
-} while (0)
-
-
-/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
-#define HASH_FIND_STR(head,findstr,out) \
- HASH_FIND(hh,head,findstr,strlen(findstr),out)
-#define HASH_ADD_STR(head,strfield,add) \
- HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
-#define HASH_REPLACE_STR(head,strfield,add,replaced) \
- HASH_REPLACE(hh,head,strfield,strlen(add->strfield),add,replaced)
-#define HASH_FIND_INT(head,findint,out) \
- HASH_FIND(hh,head,findint,sizeof(int),out)
-#define HASH_ADD_INT(head,intfield,add) \
- HASH_ADD(hh,head,intfield,sizeof(int),add)
-#define HASH_REPLACE_INT(head,intfield,add,replaced) \
- HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced)
-#define HASH_FIND_PTR(head,findptr,out) \
- HASH_FIND(hh,head,findptr,sizeof(void *),out)
-#define HASH_ADD_PTR(head,ptrfield,add) \
- HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
-#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \
- HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced)
-#define HASH_DEL(head,delptr) \
- HASH_DELETE(hh,head,delptr)
-
-/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
- * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
- */
-#ifdef HASH_DEBUG
-#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
-#define HASH_FSCK(hh,head) \
-do { \
- unsigned _bkt_i; \
- unsigned _count, _bkt_count; \
- char *_prev; \
- struct UT_hash_handle *_thh; \
- if (head) { \
- _count = 0; \
- for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
- _bkt_count = 0; \
- _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
- _prev = NULL; \
- while (_thh) { \
- if (_prev != (char*)(_thh->hh_prev)) { \
- HASH_OOPS("invalid hh_prev %p, actual %p\n", \
- _thh->hh_prev, _prev ); \
- } \
- _bkt_count++; \
- _prev = (char*)(_thh); \
- _thh = _thh->hh_next; \
- } \
- _count += _bkt_count; \
- if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
- HASH_OOPS("invalid bucket count %d, actual %d\n", \
- (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
- } \
- } \
- if (_count != (head)->hh.tbl->num_items) { \
- HASH_OOPS("invalid hh item count %d, actual %d\n", \
- (head)->hh.tbl->num_items, _count ); \
- } \
- /* traverse hh in app order; check next/prev integrity, count */ \
- _count = 0; \
- _prev = NULL; \
- _thh = &(head)->hh; \
- while (_thh) { \
- _count++; \
- if (_prev !=(char*)(_thh->prev)) { \
- HASH_OOPS("invalid prev %p, actual %p\n", \
- _thh->prev, _prev ); \
- } \
- _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
- _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
- (head)->hh.tbl->hho) : NULL ); \
- } \
- if (_count != (head)->hh.tbl->num_items) { \
- HASH_OOPS("invalid app item count %d, actual %d\n", \
- (head)->hh.tbl->num_items, _count ); \
- } \
- } \
-} while (0)
-#else
-#define HASH_FSCK(hh,head)
-#endif
-
-/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
- * the descriptor to which this macro is defined for tuning the hash function.
- * The app can #include to get the prototype for write(2). */
-#ifdef HASH_EMIT_KEYS
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
-do { \
- unsigned _klen = fieldlen; \
- write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
- write(HASH_EMIT_KEYS, keyptr, fieldlen); \
-} while (0)
-#else
-#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
-#endif
-
-/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
-#ifdef HASH_FUNCTION
-#define HASH_FCN HASH_FUNCTION
-#else
-#define HASH_FCN HASH_JEN
-#endif
-
-/* The Bernstein hash function, used in Perl prior to v5.6 */
-#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
-do { \
- unsigned _hb_keylen=keylen; \
- char *_hb_key=(char*)(key); \
- (hashv) = 0; \
- while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
- bkt = (hashv) & (num_bkts-1); \
-} while (0)
-
-
-/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
- * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
-#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
-do { \
- unsigned _sx_i; \
- char *_hs_key=(char*)(key); \
- hashv = 0; \
- for(_sx_i=0; _sx_i < keylen; _sx_i++) \
- hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
- bkt = hashv & (num_bkts-1); \
-} while (0)
-
-#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
-do { \
- unsigned _fn_i; \
- char *_hf_key=(char*)(key); \
- hashv = 2166136261UL; \
- for(_fn_i=0; _fn_i < keylen; _fn_i++) \
- hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
- bkt = hashv & (num_bkts-1); \
-} while(0)
-
-#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
-do { \
- unsigned _ho_i; \
- char *_ho_key=(char*)(key); \
- hashv = 0; \
- for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
- hashv += _ho_key[_ho_i]; \
- hashv += (hashv << 10); \
- hashv ^= (hashv >> 6); \
- } \
- hashv += (hashv << 3); \
- hashv ^= (hashv >> 11); \
- hashv += (hashv << 15); \
- bkt = hashv & (num_bkts-1); \
-} while(0)
-
-#define HASH_JEN_MIX(a,b,c) \
-do { \
- a -= b; a -= c; a ^= ( c >> 13 ); \
- b -= c; b -= a; b ^= ( a << 8 ); \
- c -= a; c -= b; c ^= ( b >> 13 ); \
- a -= b; a -= c; a ^= ( c >> 12 ); \
- b -= c; b -= a; b ^= ( a << 16 ); \
- c -= a; c -= b; c ^= ( b >> 5 ); \
- a -= b; a -= c; a ^= ( c >> 3 ); \
- b -= c; b -= a; b ^= ( a << 10 ); \
- c -= a; c -= b; c ^= ( b >> 15 ); \
-} while (0)
-
-#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
-do { \
- unsigned _hj_i,_hj_j,_hj_k; \
- unsigned char *_hj_key=(unsigned char*)(key); \
- hashv = 0xfeedbeef; \
- _hj_i = _hj_j = 0x9e3779b9; \
- _hj_k = (unsigned)(keylen); \
- while (_hj_k >= 12) { \
- _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
- + ( (unsigned)_hj_key[2] << 16 ) \
- + ( (unsigned)_hj_key[3] << 24 ) ); \
- _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
- + ( (unsigned)_hj_key[6] << 16 ) \
- + ( (unsigned)_hj_key[7] << 24 ) ); \
- hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
- + ( (unsigned)_hj_key[10] << 16 ) \
- + ( (unsigned)_hj_key[11] << 24 ) ); \
- \
- HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
- \
- _hj_key += 12; \
- _hj_k -= 12; \
- } \
- hashv += keylen; \
- switch ( _hj_k ) { \
- case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
- case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
- case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
- case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
- case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
- case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
- case 5: _hj_j += _hj_key[4]; \
- case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
- case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
- case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
- case 1: _hj_i += _hj_key[0]; \
- } \
- HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
- bkt = hashv & (num_bkts-1); \
-} while(0)
-
-/* The Paul Hsieh hash function */
-#undef get16bits
-#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
- || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
-#define get16bits(d) (*((const uint16_t *) (d)))
-#endif
-
-#if !defined (get16bits)
-#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
- +(uint32_t)(((const uint8_t *)(d))[0]) )
-#endif
-#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
-do { \
- unsigned char *_sfh_key=(unsigned char*)(key); \
- uint32_t _sfh_tmp, _sfh_len = keylen; \
- \
- int _sfh_rem = _sfh_len & 3; \
- _sfh_len >>= 2; \
- hashv = 0xcafebabe; \
- \
- /* Main loop */ \
- for (;_sfh_len > 0; _sfh_len--) { \
- hashv += get16bits (_sfh_key); \
- _sfh_tmp = (uint32_t)(get16bits (_sfh_key+2)) << 11 ^ hashv; \
- hashv = (hashv << 16) ^ _sfh_tmp; \
- _sfh_key += 2*sizeof (uint16_t); \
- hashv += hashv >> 11; \
- } \
- \
- /* Handle end cases */ \
- switch (_sfh_rem) { \
- case 3: hashv += get16bits (_sfh_key); \
- hashv ^= hashv << 16; \
- hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)] << 18); \
- hashv += hashv >> 11; \
- break; \
- case 2: hashv += get16bits (_sfh_key); \
- hashv ^= hashv << 11; \
- hashv += hashv >> 17; \
- break; \
- case 1: hashv += *_sfh_key; \
- hashv ^= hashv << 10; \
- hashv += hashv >> 1; \
- } \
- \
- /* Force "avalanching" of final 127 bits */ \
- hashv ^= hashv << 3; \
- hashv += hashv >> 5; \
- hashv ^= hashv << 4; \
- hashv += hashv >> 17; \
- hashv ^= hashv << 25; \
- hashv += hashv >> 6; \
- bkt = hashv & (num_bkts-1); \
-} while(0)
-
-#ifdef HASH_USING_NO_STRICT_ALIASING
-/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
- * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
- * MurmurHash uses the faster approach only on CPU's where we know it's safe.
- *
- * Note the preprocessor built-in defines can be emitted using:
- *
- * gcc -m64 -dM -E - < /dev/null (on gcc)
- * cc -## a.c (where a.c is a simple test file) (Sun Studio)
- */
-#if (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86))
-#define MUR_GETBLOCK(p,i) p[i]
-#else /* non intel */
-#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
-#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
-#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
-#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
-#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
-#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
-#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
-#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
-#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
-#else /* assume little endian non-intel */
-#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
-#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
-#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
-#endif
-#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
- (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
- (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
- MUR_ONE_THREE(p))))
-#endif
-#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
-#define MUR_FMIX(_h) \
-do { \
- _h ^= _h >> 16; \
- _h *= 0x85ebca6b; \
- _h ^= _h >> 13; \
- _h *= 0xc2b2ae35l; \
- _h ^= _h >> 16; \
-} while(0)
-
-#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
-do { \
- const uint8_t *_mur_data = (const uint8_t*)(key); \
- const int _mur_nblocks = (keylen) / 4; \
- uint32_t _mur_h1 = 0xf88D5353; \
- uint32_t _mur_c1 = 0xcc9e2d51; \
- uint32_t _mur_c2 = 0x1b873593; \
- uint32_t _mur_k1 = 0; \
- const uint8_t *_mur_tail; \
- const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
- int _mur_i; \
- for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
- _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
- _mur_k1 *= _mur_c1; \
- _mur_k1 = MUR_ROTL32(_mur_k1,15); \
- _mur_k1 *= _mur_c2; \
- \
- _mur_h1 ^= _mur_k1; \
- _mur_h1 = MUR_ROTL32(_mur_h1,13); \
- _mur_h1 = _mur_h1*5+0xe6546b64; \
- } \
- _mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \
- _mur_k1=0; \
- switch((keylen) & 3) { \
- case 3: _mur_k1 ^= _mur_tail[2] << 16; \
- case 2: _mur_k1 ^= _mur_tail[1] << 8; \
- case 1: _mur_k1 ^= _mur_tail[0]; \
- _mur_k1 *= _mur_c1; \
- _mur_k1 = MUR_ROTL32(_mur_k1,15); \
- _mur_k1 *= _mur_c2; \
- _mur_h1 ^= _mur_k1; \
- } \
- _mur_h1 ^= (keylen); \
- MUR_FMIX(_mur_h1); \
- hashv = _mur_h1; \
- bkt = hashv & (num_bkts-1); \
-} while(0)
-#endif /* HASH_USING_NO_STRICT_ALIASING */
-
-/* key comparison function; return 0 if keys equal */
-#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
-
-/* iterate over items in a known bucket to find desired item */
-#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
-do { \
- if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
- else out=NULL; \
- while (out) { \
- if ((out)->hh.keylen == keylen_in) { \
- if ((HASH_KEYCMP((out)->hh.key,keyptr,keylen_in)) == 0) break; \
- } \
- if ((out)->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,(out)->hh.hh_next)); \
- else out = NULL; \
- } \
-} while(0)
-
-/* add an item to a bucket */
-#define HASH_ADD_TO_BKT(head,addhh) \
-do { \
- head.count++; \
- (addhh)->hh_next = head.hh_head; \
- (addhh)->hh_prev = NULL; \
- if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
- (head).hh_head=addhh; \
- if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
- && (addhh)->tbl->noexpand != 1) { \
- HASH_EXPAND_BUCKETS((addhh)->tbl); \
- } \
-} while(0)
-
-/* remove an item from a given bucket */
-#define HASH_DEL_IN_BKT(hh,head,hh_del) \
- (head).count--; \
- if ((head).hh_head == hh_del) { \
- (head).hh_head = hh_del->hh_next; \
- } \
- if (hh_del->hh_prev) { \
- hh_del->hh_prev->hh_next = hh_del->hh_next; \
- } \
- if (hh_del->hh_next) { \
- hh_del->hh_next->hh_prev = hh_del->hh_prev; \
- }
-
-/* Bucket expansion has the effect of doubling the number of buckets
- * and redistributing the items into the new buckets. Ideally the
- * items will distribute more or less evenly into the new buckets
- * (the extent to which this is true is a measure of the quality of
- * the hash function as it applies to the key domain).
- *
- * With the items distributed into more buckets, the chain length
- * (item count) in each bucket is reduced. Thus by expanding buckets
- * the hash keeps a bound on the chain length. This bounded chain
- * length is the essence of how a hash provides constant time lookup.
- *
- * The calculation of tbl->ideal_chain_maxlen below deserves some
- * explanation. First, keep in mind that we're calculating the ideal
- * maximum chain length based on the *new* (doubled) bucket count.
- * In fractions this is just n/b (n=number of items,b=new num buckets).
- * Since the ideal chain length is an integer, we want to calculate
- * ceil(n/b). We don't depend on floating point arithmetic in this
- * hash, so to calculate ceil(n/b) with integers we could write
- *
- * ceil(n/b) = (n/b) + ((n%b)?1:0)
- *
- * and in fact a previous version of this hash did just that.
- * But now we have improved things a bit by recognizing that b is
- * always a power of two. We keep its base 2 log handy (call it lb),
- * so now we can write this with a bit shift and logical AND:
- *
- * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
- *
- */
-#define HASH_EXPAND_BUCKETS(tbl) \
-do { \
- unsigned _he_bkt; \
- unsigned _he_bkt_i; \
- struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
- UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
- _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
- 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
- if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
- memset(_he_new_buckets, 0, \
- 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
- tbl->ideal_chain_maxlen = \
- (tbl->num_items >> (tbl->log2_num_buckets+1)) + \
- ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
- tbl->nonideal_items = 0; \
- for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
- { \
- _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
- while (_he_thh) { \
- _he_hh_nxt = _he_thh->hh_next; \
- HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
- _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
- if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
- tbl->nonideal_items++; \
- _he_newbkt->expand_mult = _he_newbkt->count / \
- tbl->ideal_chain_maxlen; \
- } \
- _he_thh->hh_prev = NULL; \
- _he_thh->hh_next = _he_newbkt->hh_head; \
- if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
- _he_thh; \
- _he_newbkt->hh_head = _he_thh; \
- _he_thh = _he_hh_nxt; \
- } \
- } \
- uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
- tbl->num_buckets *= 2; \
- tbl->log2_num_buckets++; \
- tbl->buckets = _he_new_buckets; \
- tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
- (tbl->ineff_expands+1) : 0; \
- if (tbl->ineff_expands > 1) { \
- tbl->noexpand=1; \
- uthash_noexpand_fyi(tbl); \
- } \
- uthash_expand_fyi(tbl); \
-} while(0)
-
-
-/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
-/* Note that HASH_SORT assumes the hash handle name to be hh.
- * HASH_SRT was added to allow the hash handle name to be passed in. */
-#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
-#define HASH_SRT(hh,head,cmpfcn) \
-do { \
- unsigned _hs_i; \
- unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
- struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
- if (head) { \
- _hs_insize = 1; \
- _hs_looping = 1; \
- _hs_list = &((head)->hh); \
- while (_hs_looping) { \
- _hs_p = _hs_list; \
- _hs_list = NULL; \
- _hs_tail = NULL; \
- _hs_nmerges = 0; \
- while (_hs_p) { \
- _hs_nmerges++; \
- _hs_q = _hs_p; \
- _hs_psize = 0; \
- for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
- _hs_psize++; \
- _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
- ((void*)((char*)(_hs_q->next) + \
- (head)->hh.tbl->hho)) : NULL); \
- if (! (_hs_q) ) break; \
- } \
- _hs_qsize = _hs_insize; \
- while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
- if (_hs_psize == 0) { \
- _hs_e = _hs_q; \
- _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
- ((void*)((char*)(_hs_q->next) + \
- (head)->hh.tbl->hho)) : NULL); \
- _hs_qsize--; \
- } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
- _hs_e = _hs_p; \
- if (_hs_p){ \
- _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
- ((void*)((char*)(_hs_p->next) + \
- (head)->hh.tbl->hho)) : NULL); \
- } \
- _hs_psize--; \
- } else if (( \
- cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
- DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
- ) <= 0) { \
- _hs_e = _hs_p; \
- if (_hs_p){ \
- _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
- ((void*)((char*)(_hs_p->next) + \
- (head)->hh.tbl->hho)) : NULL); \
- } \
- _hs_psize--; \
- } else { \
- _hs_e = _hs_q; \
- _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
- ((void*)((char*)(_hs_q->next) + \
- (head)->hh.tbl->hho)) : NULL); \
- _hs_qsize--; \
- } \
- if ( _hs_tail ) { \
- _hs_tail->next = ((_hs_e) ? \
- ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
- } else { \
- _hs_list = _hs_e; \
- } \
- if (_hs_e) { \
- _hs_e->prev = ((_hs_tail) ? \
- ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
- } \
- _hs_tail = _hs_e; \
- } \
- _hs_p = _hs_q; \
- } \
- if (_hs_tail){ \
- _hs_tail->next = NULL; \
- } \
- if ( _hs_nmerges <= 1 ) { \
- _hs_looping=0; \
- (head)->hh.tbl->tail = _hs_tail; \
- DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
- } \
- _hs_insize *= 2; \
- } \
- HASH_FSCK(hh,head); \
- } \
-} while (0)
-
-/* This function selects items from one hash into another hash.
- * The end result is that the selected items have dual presence
- * in both hashes. There is no copy of the items made; rather
- * they are added into the new hash through a secondary hash
- * hash handle that must be present in the structure. */
-#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
-do { \
- unsigned _src_bkt, _dst_bkt; \
- void *_last_elt=NULL, *_elt; \
- UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
- ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
- if (src) { \
- for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
- for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
- _src_hh; \
- _src_hh = _src_hh->hh_next) { \
- _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
- if (cond(_elt)) { \
- _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
- _dst_hh->key = _src_hh->key; \
- _dst_hh->keylen = _src_hh->keylen; \
- _dst_hh->hashv = _src_hh->hashv; \
- _dst_hh->prev = _last_elt; \
- _dst_hh->next = NULL; \
- if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
- if (!dst) { \
- DECLTYPE_ASSIGN(dst,_elt); \
- HASH_MAKE_TABLE(hh_dst,dst); \
- } else { \
- _dst_hh->tbl = (dst)->hh_dst.tbl; \
- } \
- HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
- HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
- (dst)->hh_dst.tbl->num_items++; \
- _last_elt = _elt; \
- _last_elt_hh = _dst_hh; \
- } \
- } \
- } \
- } \
- HASH_FSCK(hh_dst,dst); \
-} while (0)
-
-#define HASH_CLEAR(hh,head) \
-do { \
- if (head) { \
- uthash_free((head)->hh.tbl->buckets, \
- (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
- HASH_BLOOM_FREE((head)->hh.tbl); \
- uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
- (head)=NULL; \
- } \
-} while(0)
-
-#define HASH_OVERHEAD(hh,head) \
- (size_t)((((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \
- ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \
- (sizeof(UT_hash_table)) + \
- (HASH_BLOOM_BYTELEN)))
-
-#ifdef NO_DECLTYPE
-#define HASH_ITER(hh,head,el,tmp) \
-for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
- el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
-#else
-#define HASH_ITER(hh,head,el,tmp) \
-for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
- el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
-#endif
-
-/* obtain a count of items in the hash */
-#define HASH_COUNT(head) HASH_CNT(hh,head)
-#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
-
-typedef struct UT_hash_bucket {
- struct UT_hash_handle *hh_head;
- unsigned count;
-
- /* expand_mult is normally set to 0. In this situation, the max chain length
- * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
- * the bucket's chain exceeds this length, bucket expansion is triggered).
- * However, setting expand_mult to a non-zero value delays bucket expansion
- * (that would be triggered by additions to this particular bucket)
- * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
- * (The multiplier is simply expand_mult+1). The whole idea of this
- * multiplier is to reduce bucket expansions, since they are expensive, in
- * situations where we know that a particular bucket tends to be overused.
- * It is better to let its chain length grow to a longer yet-still-bounded
- * value, than to do an O(n) bucket expansion too often.
- */
- unsigned expand_mult;
-
-} UT_hash_bucket;
-
-/* random signature used only to find hash tables in external analysis */
-#define HASH_SIGNATURE 0xa0111fe1
-#define HASH_BLOOM_SIGNATURE 0xb12220f2
-
-typedef struct UT_hash_table {
- UT_hash_bucket *buckets;
- unsigned num_buckets, log2_num_buckets;
- unsigned num_items;
- struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
- ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
-
- /* in an ideal situation (all buckets used equally), no bucket would have
- * more than ceil(#items/#buckets) items. that's the ideal chain length. */
- unsigned ideal_chain_maxlen;
-
- /* nonideal_items is the number of items in the hash whose chain position
- * exceeds the ideal chain maxlen. these items pay the penalty for an uneven
- * hash distribution; reaching them in a chain traversal takes >ideal steps */
- unsigned nonideal_items;
-
- /* ineffective expands occur when a bucket doubling was performed, but
- * afterward, more than half the items in the hash had nonideal chain
- * positions. If this happens on two consecutive expansions we inhibit any
- * further expansion, as it's not helping; this happens when the hash
- * function isn't a good fit for the key domain. When expansion is inhibited
- * the hash will still work, albeit no longer in constant time. */
- unsigned ineff_expands, noexpand;
-
- uint32_t signature; /* used only to find hash tables in external analysis */
-#ifdef HASH_BLOOM
- uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
- uint8_t *bloom_bv;
- char bloom_nbits;
-#endif
-
-} UT_hash_table;
-
-typedef struct UT_hash_handle {
- struct UT_hash_table *tbl;
- void *prev; /* prev element in app order */
- void *next; /* next element in app order */
- struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
- struct UT_hash_handle *hh_next; /* next hh in bucket order */
- void *key; /* ptr to enclosing struct's key */
- unsigned keylen; /* enclosing struct's key len */
- unsigned hashv; /* result of hash-fcn(key) */
-} UT_hash_handle;
-
-#endif /* UTHASH_H */
--
cgit v1.2.3
From c04e1e7aef06ce0836984b17e48a1d09bb83ce04 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 18:38:56 +0200
Subject: Fix misc bugs
---
src/references.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/references.c b/src/references.c
index ff64b00..84cb773 100644
--- a/src/references.c
+++ b/src/references.c
@@ -13,6 +13,14 @@ refhash(const unsigned char *link_ref)
return hash;
}
+static void reference_free(reference *ref)
+{
+ free(ref->label);
+ free(ref->url);
+ free(ref->title);
+ free(ref);
+}
+
// normalize reference: collapse internal whitespace to single space,
// remove leading/trailing whitespace, case fold
static unsigned char *normalize_reference(chunk *ref)
@@ -28,7 +36,18 @@ static unsigned char *normalize_reference(chunk *ref)
static void add_reference(reference_map *map, reference* ref)
{
- ref->next = map->table[ref->hash % REFMAP_SIZE];
+ reference *t = ref->next = map->table[ref->hash % REFMAP_SIZE];
+
+ while (t) {
+ if (t->hash == ref->hash &&
+ !strcmp((char *)t->label, (char *)ref->label)) {
+ reference_free(ref);
+ return;
+ }
+
+ t = t->next;
+ }
+
map->table[ref->hash % REFMAP_SIZE] = ref;
}
@@ -63,7 +82,7 @@ reference* reference_lookup(reference_map *map, chunk *label)
ref = map->table[hash % REFMAP_SIZE];
while (ref) {
- if (ref->label[0] == norm[0] &&
+ if (ref->hash == hash &&
!strcmp((char *)ref->label, (char *)norm))
break;
ref = ref->next;
@@ -73,14 +92,6 @@ reference* reference_lookup(reference_map *map, chunk *label)
return ref;
}
-static void reference_free(reference *ref)
-{
- free(ref->label);
- free(ref->url);
- free(ref->title);
- free(ref);
-}
-
void reference_map_free(reference_map *map)
{
unsigned int i;
@@ -96,7 +107,6 @@ void reference_map_free(reference_map *map)
}
}
- free(map->table);
free(map);
}
--
cgit v1.2.3
From c47e3a34adac00a262f72c6d17a1c87deefa33c4 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 19:39:03 +0200
Subject: Fix infinite loop when case folding invalid UTF8 chars
---
src/utf8.c | 24 ++++++++++++------------
src/utf8.h | 4 ++--
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/utf8.c b/src/utf8.c
index c65aec6..1b0224b 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -29,9 +29,9 @@ static void encode_unknown(strbuf *buf)
strbuf_put(buf, repl, 3);
}
-ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len)
+int utf8proc_charlen(const uint8_t *str, int str_len)
{
- ssize_t length, i;
+ int length, i;
if (!str_len)
return 0;
@@ -42,11 +42,11 @@ ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len)
return -1;
if (str_len >= 0 && length > str_len)
- return -1;
+ return -str_len;
for (i = 1; i < length; i++) {
if ((str[i] & 0xC0) != 0x80)
- return -1;
+ return -i;
}
return length;
@@ -77,7 +77,7 @@ void utf8proc_detab(strbuf *ob, const uint8_t *line, size_t size)
i += 1;
tab += numspaces;
} else {
- ssize_t charlen = utf8proc_charlen(line + i, size - i);
+ int charlen = utf8proc_charlen(line + i, size - i);
if (charlen < 0) {
encode_unknown(ob);
@@ -92,9 +92,9 @@ void utf8proc_detab(strbuf *ob, const uint8_t *line, size_t size)
}
}
-ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst)
+int utf8proc_iterate(const uint8_t *str, int str_len, int32_t *dst)
{
- ssize_t length;
+ int length;
int32_t uc = -1;
*dst = -1;
@@ -177,15 +177,15 @@ void utf8proc_case_fold(strbuf *dest, const uint8_t *str, int len)
utf8proc_encode_char(x, dest)
while (len > 0) {
- ssize_t char_len = utf8proc_iterate(str, len, &c);
+ int char_len = utf8proc_iterate(str, len, &c);
- if (char_len < 0) {
+ if (char_len >= 0) {
+#include "case_fold_switch.inc"
+ } else {
encode_unknown(dest);
- continue;
+ char_len = -char_len;
}
-#include "case_fold_switch.inc"
-
str += char_len;
len -= char_len;
}
diff --git a/src/utf8.h b/src/utf8.h
index 9506b75..c971250 100644
--- a/src/utf8.h
+++ b/src/utf8.h
@@ -6,8 +6,8 @@
void utf8proc_case_fold(strbuf *dest, const uint8_t *str, int len);
void utf8proc_encode_char(int32_t uc, strbuf *buf);
-ssize_t utf8proc_iterate(const uint8_t *str, ssize_t str_len, int32_t *dst);
-ssize_t utf8proc_charlen(const uint8_t *str, ssize_t str_len);
+int utf8proc_iterate(const uint8_t *str, int str_len, int32_t *dst);
+int utf8proc_charlen(const uint8_t *str, int str_len);
void utf8proc_detab(strbuf *dest, const uint8_t *line, size_t size);
#endif
--
cgit v1.2.3
From 79e7a4bbf7055e33b346564db769f03e85f98988 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 19:40:40 +0200
Subject: Improve invalid UTF8 codepoint skipping
---
src/utf8.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/utf8.c b/src/utf8.c
index 1b0224b..6b34831 100644
--- a/src/utf8.c
+++ b/src/utf8.c
@@ -79,14 +79,14 @@ void utf8proc_detab(strbuf *ob, const uint8_t *line, size_t size)
} else {
int charlen = utf8proc_charlen(line + i, size - i);
- if (charlen < 0) {
- encode_unknown(ob);
- i++;
- } else {
+ if (charlen >= 0) {
strbuf_put(ob, line + i, charlen);
- i += charlen;
+ } else {
+ encode_unknown(ob);
+ charlen = -charlen;
}
+ i += charlen;
tab += 1;
}
}
--
cgit v1.2.3
From 7c2a062cdf9c0514cdf32f4f8bd07cf52d183c8b Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 19:46:34 +0200
Subject: Do not use strchr for span searches
Strchr will return a valid pointer for '\0' when searching a static
string, as the NULL byte is part of the string.
---
src/inlines.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/inlines.c b/src/inlines.c
index 3040f09..cd2d124 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -767,10 +767,13 @@ node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap)
static int subject_find_special_char(subject *subj)
{
+ static const char CHARS[] = "\n\\`&_*[]pos + 1;
while (n < subj->input.len) {
- if (strchr("\n\\`&_*[]input.data[n]))
+ if (memchr(CHARS, subj->input.data[n], CHARS_SIZE))
return n;
n++;
}
--
cgit v1.2.3
From 8c028e1a88c2d2aac4a4086202568bee43678aa8 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 19:50:29 +0200
Subject: Do not create references with empty names
---
src/buffer.c | 7 ++++---
src/references.c | 31 ++++++++++++++++++++++++++-----
src/references.h | 2 +-
3 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/src/buffer.c b/src/buffer.c
index cdf8ca0..7c2b86b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -215,11 +215,12 @@ unsigned char *strbuf_detach(strbuf *buf)
{
unsigned char *data = buf->ptr;
- if (buf->asize == 0 || buf->ptr == strbuf__oom)
- return NULL;
+ if (buf->asize == 0 || buf->ptr == strbuf__oom) {
+ /* return an empty string */
+ return calloc(1, 1);
+ }
strbuf_init(buf, 0);
-
return data;
}
diff --git a/src/references.c b/src/references.c
index 84cb773..300bbcc 100644
--- a/src/references.c
+++ b/src/references.c
@@ -23,15 +23,29 @@ static void reference_free(reference *ref)
// normalize reference: collapse internal whitespace to single space,
// remove leading/trailing whitespace, case fold
+// Return NULL if the reference name is actually empty (i.e. composed
+// solely from whitespace)
static unsigned char *normalize_reference(chunk *ref)
{
strbuf normalized = GH_BUF_INIT;
+ unsigned char *result;
+
+ if (ref->len == 0)
+ return NULL;
utf8proc_case_fold(&normalized, ref->data, ref->len);
strbuf_trim(&normalized);
strbuf_normalize_whitespace(&normalized);
- return strbuf_detach(&normalized);
+ result = strbuf_detach(&normalized);
+ assert(result);
+
+ if (result[0] == '\0') {
+ free(result);
+ return NULL;
+ }
+
+ return result;
}
static void add_reference(reference_map *map, reference* ref)
@@ -51,19 +65,23 @@ static void add_reference(reference_map *map, reference* ref)
map->table[ref->hash % REFMAP_SIZE] = ref;
}
-extern reference *reference_create(reference_map *map, chunk *label, chunk *url, chunk *title)
+extern void reference_create(reference_map *map, chunk *label, chunk *url, chunk *title)
{
reference *ref;
+ unsigned char *reflabel = normalize_reference(label);
+
+ /* empty reference name, or composed from only whitespace */
+ if (reflabel == NULL)
+ return;
+
ref = malloc(sizeof(reference));
- ref->label = normalize_reference(label);
+ ref->label = reflabel;
ref->hash = refhash(ref->label);
ref->url = clean_url(url);
ref->title = clean_title(title);
ref->next = NULL;
add_reference(map, ref);
-
- return ref;
}
// Returns reference if refmap contains a reference with matching
@@ -78,6 +96,9 @@ reference* reference_lookup(reference_map *map, chunk *label)
return NULL;
norm = normalize_reference(label);
+ if (norm == NULL)
+ return NULL;
+
hash = refhash(norm);
ref = map->table[hash % REFMAP_SIZE];
diff --git a/src/references.h b/src/references.h
index 78fffe7..28937f1 100644
--- a/src/references.h
+++ b/src/references.h
@@ -22,6 +22,6 @@ typedef struct reference_map reference_map;
reference_map *reference_map_new(void);
void reference_map_free(reference_map *map);
reference* reference_lookup(reference_map *map, chunk *label);
-extern reference *reference_create(reference_map *map, chunk *label, chunk *url, chunk *title);
+extern void reference_create(reference_map *map, chunk *label, chunk *url, chunk *title);
#endif
--
cgit v1.2.3
From 0ae7f4f53720e867c92ac9465062285293568856 Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Wed, 10 Sep 2014 20:02:01 +0200
Subject: Handle overflows in the codepoint parser
---
src/html/houdini_html_u.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/html/houdini_html_u.c b/src/html/houdini_html_u.c
index b8e2d8d..49b4956 100644
--- a/src/html/houdini_html_u.c
+++ b/src/html/houdini_html_u.c
@@ -15,13 +15,25 @@ houdini_unescape_ent(strbuf *ob, const uint8_t *src, size_t size)
int codepoint = 0;
if (_isdigit(src[1])) {
- for (i = 1; i < size && _isdigit(src[i]); ++i)
- codepoint = (codepoint * 10) + (src[i] - '0');
+ for (i = 1; i < size && _isdigit(src[i]); ++i) {
+ int cp = (codepoint * 10) + (src[i] - '0');
+
+ if (cp < codepoint)
+ return 0;
+
+ codepoint = cp;
+ }
}
else if (src[1] == 'x' || src[1] == 'X') {
- for (i = 2; i < size && _isxdigit(src[i]); ++i)
- codepoint = (codepoint * 16) + ((src[i] | 32) % 39 - 9);
+ for (i = 2; i < size && _isxdigit(src[i]); ++i) {
+ int cp = (codepoint * 16) + ((src[i] | 32) % 39 - 9);
+
+ if (cp < codepoint)
+ return 0;
+
+ codepoint = cp;
+ }
}
if (i < size && src[i] == ';' && codepoint) {
--
cgit v1.2.3
From 118e3d3c39242225baa876319cdbfbb1adadc77b Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Mon, 15 Sep 2014 15:28:49 +0200
Subject: Cleanup external APIs
---
src/blocks.c | 11 ++--
src/html/html.c | 163 ++++++++++++++++++++++++++++---------------------------
src/inlines.c | 1 +
src/main.c | 8 +--
src/print.c | 114 +++++++++++++++++++-------------------
src/references.c | 1 +
src/stmd.h | 26 ++-------
7 files changed, 159 insertions(+), 165 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index 30a8284..2ac7032 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -6,8 +6,9 @@
#include "stmd.h"
#include "utf8.h"
-#include "html/houdini.h"
#include "scanners.h"
+#include "inlines.h"
+#include "html/houdini.h"
#define peek_at(i, n) (i)->data[n]
@@ -224,7 +225,7 @@ static void finalize(node_block* b, int line_number)
}
// Add a node_block as child of another. Return pointer to child.
-extern node_block* add_child(node_block* parent,
+static node_block* add_child(node_block* parent,
int block_type, int start_line, int start_column)
{
assert(parent);
@@ -252,7 +253,7 @@ extern node_block* add_child(node_block* parent,
}
// Free a node_block list and any children.
-extern void free_blocks(node_block* e)
+void stmd_free_nodes(node_block *e)
{
node_block * next;
while (e != NULL) {
@@ -264,7 +265,7 @@ extern void free_blocks(node_block* e)
} else if (e->tag == BLOCK_DOCUMENT) {
reference_map_free(e->as.document.refmap);
}
- free_blocks(e->children);
+ stmd_free_nodes(e->children);
free(e);
e = next;
}
@@ -279,8 +280,6 @@ void process_inlines(node_block* cur, reference_map *refmap)
case BLOCK_ATX_HEADER:
case BLOCK_SETEXT_HEADER:
cur->inline_content = parse_inlines(&cur->string_content, refmap);
- // MEM
- // strbuf_free(&cur->string_content);
break;
default:
diff --git a/src/html/html.c b/src/html/html.c
index b48b10b..6f3bc76 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -32,8 +32,89 @@ static inline void cr(strbuf *html)
strbuf_putc(html, '\n');
}
+// Convert an inline list to HTML. Returns 0 on success, and sets result.
+static void inlines_to_html(strbuf *html, node_inl* ils)
+{
+ strbuf scrap = GH_BUF_INIT;
+
+ while(ils != NULL) {
+ switch(ils->tag) {
+ case INL_STRING:
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ break;
+
+ case INL_LINEBREAK:
+ strbuf_puts(html, "
\n");
+ break;
+
+ case INL_SOFTBREAK:
+ strbuf_putc(html, '\n');
+ break;
+
+ case INL_CODE:
+ strbuf_puts(html, "");
+ escape_html(html, ils->content.literal.data, ils->content.literal.len);
+ strbuf_puts(html, "
");
+ break;
+
+ case INL_RAW_HTML:
+ strbuf_put(html,
+ ils->content.literal.data,
+ ils->content.literal.len);
+ break;
+
+ case INL_LINK:
+ strbuf_puts(html, "content.linkable.url)
+ escape_href(html, ils->content.linkable.url, -1);
+
+ if (ils->content.linkable.title) {
+ strbuf_puts(html, "\" title=\"");
+ escape_html(html, ils->content.linkable.title, -1);
+ }
+
+ strbuf_puts(html, "\">");
+ inlines_to_html(html, ils->content.inlines);
+ strbuf_puts(html, "");
+ break;
+
+ case INL_IMAGE:
+ strbuf_puts(html, "content.linkable.url)
+ escape_href(html, ils->content.linkable.url, -1);
+
+ inlines_to_html(&scrap, ils->content.inlines);
+ strbuf_puts(html, "\" alt=\"");
+ if (scrap.size)
+ escape_html(html, scrap.ptr, scrap.size);
+ strbuf_clear(&scrap);
+
+ if (ils->content.linkable.title) {
+ strbuf_puts(html, "\" title=\"");
+ escape_html(html, ils->content.linkable.title, -1);
+ }
+
+ strbuf_puts(html, "\"/>");
+ break;
+
+ case INL_STRONG:
+ strbuf_puts(html, "");
+ inlines_to_html(html, ils->content.inlines);
+ strbuf_puts(html, "");
+ break;
+
+ case INL_EMPH:
+ strbuf_puts(html, "");
+ inlines_to_html(html, ils->content.inlines);
+ strbuf_puts(html, "");
+ break;
+ }
+ ils = ils->next;
+ }
+}
+
// Convert a node_block list to HTML. Returns 0 on success, and sets result.
-void blocks_to_html(strbuf *html, node_block *b, bool tight)
+static void blocks_to_html(strbuf *html, node_block *b, bool tight)
{
struct ListData *data;
@@ -139,83 +220,7 @@ void blocks_to_html(strbuf *html, node_block *b, bool tight)
}
}
-// Convert an inline list to HTML. Returns 0 on success, and sets result.
-void inlines_to_html(strbuf *html, node_inl* ils)
+void stmd_render_html(strbuf *html, node_block *root)
{
- strbuf scrap = GH_BUF_INIT;
-
- while(ils != NULL) {
- switch(ils->tag) {
- case INL_STRING:
- escape_html(html, ils->content.literal.data, ils->content.literal.len);
- break;
-
- case INL_LINEBREAK:
- strbuf_puts(html, "
\n");
- break;
-
- case INL_SOFTBREAK:
- strbuf_putc(html, '\n');
- break;
-
- case INL_CODE:
- strbuf_puts(html, "");
- escape_html(html, ils->content.literal.data, ils->content.literal.len);
- strbuf_puts(html, "
");
- break;
-
- case INL_RAW_HTML:
- strbuf_put(html,
- ils->content.literal.data,
- ils->content.literal.len);
- break;
-
- case INL_LINK:
- strbuf_puts(html, "content.linkable.url)
- escape_href(html, ils->content.linkable.url, -1);
-
- if (ils->content.linkable.title) {
- strbuf_puts(html, "\" title=\"");
- escape_html(html, ils->content.linkable.title, -1);
- }
-
- strbuf_puts(html, "\">");
- inlines_to_html(html, ils->content.inlines);
- strbuf_puts(html, "");
- break;
-
- case INL_IMAGE:
- strbuf_puts(html, "content.linkable.url)
- escape_href(html, ils->content.linkable.url, -1);
-
- inlines_to_html(&scrap, ils->content.inlines);
- strbuf_puts(html, "\" alt=\"");
- if (scrap.size)
- escape_html(html, scrap.ptr, scrap.size);
- strbuf_clear(&scrap);
-
- if (ils->content.linkable.title) {
- strbuf_puts(html, "\" title=\"");
- escape_html(html, ils->content.linkable.title, -1);
- }
-
- strbuf_puts(html, "\"/>");
- break;
-
- case INL_STRONG:
- strbuf_puts(html, "");
- inlines_to_html(html, ils->content.inlines);
- strbuf_puts(html, "");
- break;
-
- case INL_EMPH:
- strbuf_puts(html, "");
- inlines_to_html(html, ils->content.inlines);
- strbuf_puts(html, "");
- break;
- }
- ils = ils->next;
- }
+ blocks_to_html(html, root, false);
}
diff --git a/src/inlines.c b/src/inlines.c
index cd2d124..145825c 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -8,6 +8,7 @@
#include "html/houdini.h"
#include "utf8.h"
#include "scanners.h"
+#include "inlines.h"
typedef struct Subject {
chunk input;
diff --git a/src/main.c b/src/main.c
index 90bb16d..76a0e12 100644
--- a/src/main.c
+++ b/src/main.c
@@ -17,9 +17,9 @@ static void print_document(node_block *document, bool ast)
strbuf html = GH_BUF_INIT;
if (ast) {
- print_blocks(document, 0);
+ stmd_debug_print(document);
} else {
- blocks_to_html(&html, document, false);
+ stmd_render_html(&html, document);
printf("%s", html.ptr);
strbuf_free(&html);
}
@@ -54,7 +54,7 @@ int main(int argc, char *argv[])
if (numfps == 0) {
document = stmd_parse_file(stdin);
print_document(document, ast);
- free_blocks(document);
+ stmd_free_nodes(document);
} else {
for (i = 0; i < numfps; i++) {
FILE *fp = fopen(argv[files[i]], "r");
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
document = stmd_parse_file(fp);
print_document(document, ast);
- free_blocks(document);
+ stmd_free_nodes(document);
fclose(fp);
}
}
diff --git a/src/print.c b/src/print.c
index 36140a8..83f8daa 100644
--- a/src/print.c
+++ b/src/print.c
@@ -32,14 +32,69 @@ static void print_str(const unsigned char *s, int len)
putchar('"');
}
+// Prettyprint an inline list, for debugging.
+static void print_inlines(node_inl* ils, int indent)
+{
+ while(ils != NULL) {
+ for (int i=0; i < indent; i++) {
+ putchar(' ');
+ }
+ switch(ils->tag) {
+ case INL_STRING:
+ printf("str ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case INL_LINEBREAK:
+ printf("linebreak\n");
+ break;
+ case INL_SOFTBREAK:
+ printf("softbreak\n");
+ break;
+ case INL_CODE:
+ printf("code ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case INL_RAW_HTML:
+ printf("html ");
+ print_str(ils->content.literal.data, ils->content.literal.len);
+ putchar('\n');
+ break;
+ case INL_LINK:
+ case INL_IMAGE:
+ printf("%s url=", ils->tag == INL_LINK ? "link" : "image");
+
+ if (ils->content.linkable.url)
+ print_str(ils->content.linkable.url, -1);
+
+ if (ils->content.linkable.title) {
+ printf(" title=");
+ print_str(ils->content.linkable.title, -1);
+ }
+ putchar('\n');
+ print_inlines(ils->content.linkable.label, indent + 2);
+ break;
+ case INL_STRONG:
+ printf("strong\n");
+ print_inlines(ils->content.linkable.label, indent + 2);
+ break;
+ case INL_EMPH:
+ printf("emph\n");
+ print_inlines(ils->content.linkable.label, indent + 2);
+ break;
+ }
+ ils = ils->next;
+ }
+}
+
// Functions to pretty-print inline and node_block lists, for debugging.
// Prettyprint an inline list, for debugging.
-extern void print_blocks(node_block* b, int indent)
+static void print_blocks(node_block* b, int indent)
{
struct ListData *data;
while(b != NULL) {
- // printf("%3d %3d %3d| ", b->start_line, b->start_column, b->end_line);
for (int i=0; i < indent; i++) {
putchar(' ');
}
@@ -115,58 +170,7 @@ extern void print_blocks(node_block* b, int indent)
}
}
-// Prettyprint an inline list, for debugging.
-extern void print_inlines(node_inl* ils, int indent)
+void stmd_debug_print(node_block *root)
{
- while(ils != NULL) {
- for (int i=0; i < indent; i++) {
- putchar(' ');
- }
- switch(ils->tag) {
- case INL_STRING:
- printf("str ");
- print_str(ils->content.literal.data, ils->content.literal.len);
- putchar('\n');
- break;
- case INL_LINEBREAK:
- printf("linebreak\n");
- break;
- case INL_SOFTBREAK:
- printf("softbreak\n");
- break;
- case INL_CODE:
- printf("code ");
- print_str(ils->content.literal.data, ils->content.literal.len);
- putchar('\n');
- break;
- case INL_RAW_HTML:
- printf("html ");
- print_str(ils->content.literal.data, ils->content.literal.len);
- putchar('\n');
- break;
- case INL_LINK:
- case INL_IMAGE:
- printf("%s url=", ils->tag == INL_LINK ? "link" : "image");
-
- if (ils->content.linkable.url)
- print_str(ils->content.linkable.url, -1);
-
- if (ils->content.linkable.title) {
- printf(" title=");
- print_str(ils->content.linkable.title, -1);
- }
- putchar('\n');
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- case INL_STRONG:
- printf("strong\n");
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- case INL_EMPH:
- printf("emph\n");
- print_inlines(ils->content.linkable.label, indent + 2);
- break;
- }
- ils = ils->next;
- }
+ print_blocks(root, 0);
}
diff --git a/src/references.c b/src/references.c
index 300bbcc..3e54b48 100644
--- a/src/references.c
+++ b/src/references.c
@@ -1,6 +1,7 @@
#include "stmd.h"
#include "utf8.h"
#include "references.h"
+#include "inlines.h"
static unsigned int
refhash(const unsigned char *link_ref)
diff --git a/src/stmd.h b/src/stmd.h
index 4e21e6c..c6473a6 100644
--- a/src/stmd.h
+++ b/src/stmd.h
@@ -104,28 +104,12 @@ struct node_block {
typedef struct node_block node_block;
-node_inl* parse_inlines(strbuf *input, reference_map *refmap);
-void free_inlines(node_inl* e);
+node_block *stmd_parse_document(const unsigned char *buffer, size_t len);
+node_block *stmd_parse_file(FILE *f);
-int parse_reference_inline(strbuf *input, reference_map *refmap);
-void unescape_buffer(strbuf *buf);
+void stmd_free_nodes(node_block *e);
-extern node_block* make_document();
-extern node_block* add_child(node_block* parent,
- int block_type, int start_line, int start_column);
-void free_blocks(node_block* e);
-
-extern node_block *stmd_parse_document(const unsigned char *buffer, size_t len);
-extern node_block *stmd_parse_file(FILE *f);
-
-void print_inlines(node_inl* ils, int indent);
-void print_blocks(node_block* blk, int indent);
-
-void blocks_to_html(strbuf *html, node_block *b, bool tight);
-void inlines_to_html(strbuf *html, node_inl *b);
-
-unsigned char *clean_url(chunk *url);
-unsigned char *clean_autolink(chunk *url, int is_email);
-unsigned char *clean_title(chunk *title);
+void stmd_debug_print(node_block *root);
+void stmd_render_html(strbuf *html, node_block *root);
#endif
--
cgit v1.2.3
From 9c08b31793f269e4b5902908282034618ee66eef Mon Sep 17 00:00:00 2001
From: Alex Kocharin
Date: Tue, 16 Sep 2014 00:44:52 +0400
Subject: typo fix
---
spec.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spec.txt b/spec.txt
index 4a9e9fd..40d04f2 100644
--- a/spec.txt
+++ b/spec.txt
@@ -4030,7 +4030,7 @@ for efficient parsing strategies that do not backtrack:
(a) it is not part of a sequence of four or more unescaped `_`s,
(b) it is not followed by whitespace,
- (c) is is not preceded by an ASCII alphanumeric character, and
+ (c) it is not preceded by an ASCII alphanumeric character, and
(d) either it is not followed by a `_` character or it is
followed immediately by strong emphasis.
--
cgit v1.2.3
From 3aa56049d4b52b55a2313e51698090ee81e10036 Mon Sep 17 00:00:00 2001
From: Jordan Milne
Date: Fri, 12 Sep 2014 04:42:30 -0300
Subject: Better handle trailing backslashes in ATX-style headers
Previously something like '# `\' would hang the parser while it
waited for an extra character that wasn't there.
---
src/blocks.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/blocks.c b/src/blocks.c
index 2ac7032..5b38116 100644
--- a/src/blocks.c
+++ b/src/blocks.c
@@ -420,17 +420,17 @@ extern node_block *stmd_parse_document(const unsigned char *buffer, size_t len)
static void chop_trailing_hashtags(chunk *ch)
{
- int n;
+ int n, orig_n;
chunk_rtrim(ch);
- n = ch->len - 1;
+ orig_n = n = ch->len - 1;
// if string ends in #s, remove these:
while (n >= 0 && peek_at(ch, n) == '#')
n--;
// the last # was escaped, so we include it.
- if (n >= 0 && peek_at(ch, n) == '\\')
+ if (n != orig_n && n >= 0 && peek_at(ch, n) == '\\')
n++;
ch->len = n + 1;
--
cgit v1.2.3
From f22e1f2536cc70e1f989e457079f1bad252c887a Mon Sep 17 00:00:00 2001
From: Vicent Marti
Date: Thu, 18 Sep 2014 00:23:23 +0200
Subject: Add missing header
---
src/inlines.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 src/inlines.h
diff --git a/src/inlines.h b/src/inlines.h
new file mode 100644
index 0000000..8c6e2cb
--- /dev/null
+++ b/src/inlines.h
@@ -0,0 +1,13 @@
+#ifndef _INLINES_H_
+#define _INLINES_H_
+
+unsigned char *clean_url(chunk *url);
+unsigned char *clean_autolink(chunk *url, int is_email);
+unsigned char *clean_title(chunk *title);
+
+node_inl* parse_inlines(strbuf *input, reference_map *refmap);
+void free_inlines(node_inl* e);
+
+int parse_reference_inline(strbuf *input, reference_map *refmap);
+
+#endif
--
cgit v1.2.3
From 2943b3850c5cb9e4561c3d109b4513a123bf4db7 Mon Sep 17 00:00:00 2001
From: Jordan Milne
Date: Thu, 18 Sep 2014 17:21:12 -0300
Subject: Use a lookup table for subject_find_special_char
---
src/inlines.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/inlines.c b/src/inlines.c
index 145825c..71d75e9 100644
--- a/src/inlines.c
+++ b/src/inlines.c
@@ -768,13 +768,29 @@ node_inl *parse_chunk_inlines(chunk *chunk, reference_map *refmap)
static int subject_find_special_char(subject *subj)
{
- static const char CHARS[] = "\n\\`&_*[]pos + 1;
while (n < subj->input.len) {
- if (memchr(CHARS, subj->input.data[n], CHARS_SIZE))
+ if (SPECIAL_CHARS[subj->input.data[n]])
return n;
n++;
}
--
cgit v1.2.3
From 507d8d3a09f6704e8c1f21e5a5df2e4e014e6779 Mon Sep 17 00:00:00 2001
From: Jordan Milne
Date: Thu, 18 Sep 2014 09:26:05 -0300
Subject: Fix memory leak when rendering images as HTML
---
src/html/html.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/html/html.c b/src/html/html.c
index 6f3bc76..ab6fc35 100644
--- a/src/html/html.c
+++ b/src/html/html.c
@@ -111,6 +111,8 @@ static void inlines_to_html(strbuf *html, node_inl* ils)
}
ils = ils->next;
}
+
+ strbuf_free(&scrap);
}
// Convert a node_block list to HTML. Returns 0 on success, and sets result.
--
cgit v1.2.3
From c4b76cf93c8c54b6a33bab82056dc542c6630d92 Mon Sep 17 00:00:00 2001
From: John MacFarlane
Date: Fri, 19 Sep 2014 18:11:33 -0700
Subject: spec: Fixed date, version.
Closes #133.
---
spec.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/spec.txt b/spec.txt
index 040c060..fce8792 100644
--- a/spec.txt
+++ b/spec.txt
@@ -2,8 +2,8 @@
title: CommonMark Spec
author:
- John MacFarlane
-version: 1
-date: 2014-09-06
+version: 2
+date: 2014-09-19
...
# Introduction
--
cgit v1.2.3
From e752b9776d434f63768c50e4c73c533a43529052 Mon Sep 17 00:00:00 2001
From: John MacFarlane
Date: Wed, 24 Sep 2014 22:22:51 -0700
Subject: Makefile: Use ?= so variables can be set on command line.
---
Makefile | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 11e2141..f5f408e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
-CFLAGS=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
-LDFLAGS=-g -O3 -Wall -Werror
-SRCDIR=src
-DATADIR=data
+CFLAGS?=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
+LDFLAGS?=-g -O3 -Wall -Werror
+SRCDIR?=src
+DATADIR?=data
-PROG=./stmd
+PROG?=./stmd
.PHONY: all oldtests test spec benchjs testjs
all: $(SRCDIR)/case_fold_switch.inc $(PROG)
--
cgit v1.2.3
From c006aececef112f61dd44cad43f0596221f29700 Mon Sep 17 00:00:00 2001
From: John MacFarlane
Date: Wed, 24 Sep 2014 22:47:47 -0700
Subject: Suppress 'missing field initializer' warnings
from gperf generated header.
---
Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index f5f408e..671d30d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS?=-g -O3 -Wall -Wextra -std=c99 -Isrc $(OPTFLAGS)
+CFLAGS?=-g -O3 -Wall -Wextra -std=c99 -Isrc -Wno-missing-field-initializers $(OPTFLAGS)
LDFLAGS?=-g -O3 -Wall -Werror
SRCDIR?=src
DATADIR?=data
@@ -42,6 +42,7 @@ benchjs:
node js/bench.js ${BENCHINP}
HTML_OBJ=$(SRCDIR)/html/html.o $(SRCDIR)/html/houdini_href_e.o $(SRCDIR)/html/houdini_html_e.o $(SRCDIR)/html/houdini_html_u.o
+
STMD_OBJ=$(SRCDIR)/inlines.o $(SRCDIR)/buffer.o $(SRCDIR)/blocks.o $(SRCDIR)/scanners.c $(SRCDIR)/print.o $(SRCDIR)/utf8.o $(SRCDIR)/references.c
$(PROG): $(SRCDIR)/html/html_unescape.h $(SRCDIR)/case_fold_switch.inc $(HTML_OBJ) $(STMD_OBJ) $(SRCDIR)/main.c
--
cgit v1.2.3