Skip to content

Commit 0fada08

Browse files
committed
Add tag_lookup
tag_lookup is for checking read tags to make sure they are legal html.
1 parent 4ab0651 commit 0fada08

2 files changed

Lines changed: 177 additions & 0 deletions

File tree

include/html_parser_tag_lookup.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef __TAG_LOOKUP_INCLUDED__
2+
#define __TAG_LOOKUP_INCLUDED__
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#include "html_parser_types.h"
9+
10+
#define T Lookup_T
11+
typedef struct T *T;
12+
13+
extern T Tag_lookup_init(void);
14+
extern Tag_E Tag_lookup_tag(T *t, const char *name);
15+
extern const char *Tag_type_rep(Tag_E t);
16+
17+
extern void Tag_lookup_free(T *t);
18+
19+
#undef T
20+
#ifdef __cplusplus
21+
}
22+
#endif
23+
#endif /* __TAG_LOOKUP_INCLUDED__ */

src/html_parser_tag_lookup.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#include <stdio.h>
2+
#include <stddef.h>
3+
#include <string.h>
4+
5+
#include "html_parser_types.h"
6+
#include "html_parser_mem.h"
7+
#include "html_parser_assert.h"
8+
#include "html_parser_set.h"
9+
#include "html_parser_text.h"
10+
#include "html_parser_tag_lookup.h"
11+
12+
#define T Lookup_T
13+
14+
#define ARRAY_SIZE(x) ((sizeof x) / (sizeof *x))
15+
16+
/* static function prototypes */
17+
static int string_cmp(const void *str1, const void *str2);
18+
static unsigned string_hash(const void *str);
19+
20+
struct T{
21+
Set_T opt_set;
22+
Set_T void_set;
23+
Set_T strict_set;
24+
};
25+
26+
static char *opt_void_names[] = {
27+
28+
"html", "head", "body", "li", "option", "p", "tbody", "td",
29+
"tfoot", "th", "thead", "tr" , NULL
30+
31+
};
32+
33+
static char *void_names[] = {
34+
35+
"area", "br", "base", "col", "frame", "hr", "img", "input",
36+
"link", "meta", "param" , NULL
37+
38+
};
39+
40+
static char *strict_names[] = {
41+
42+
"a", "abbr", "acronym", "address", "b", "bdo", "big",
43+
"blockquote", "button", "caption", "center", "cite", "code",
44+
"del", "dfn", "div", "dl", "dt", "em", "fieldset", "form",
45+
"frameset", "h1", "h2", "h3", "h4", "h5", "h6", "i", "ins",
46+
"kbd", "label", "legend", "map", "noframes", "noscript",
47+
"object", "ol", "optgroup", "pre", "q", "samp", "script",
48+
"select", "small", "span", "strike", "strong", "style", "sub",
49+
"sup", "table", "textarea", "title", "tt", "ul", "var", NULL
50+
51+
};
52+
53+
T Tag_lookup_init(void)
54+
{
55+
T nametbl;
56+
57+
NEW(nametbl);
58+
59+
nametbl->opt_set = Set_new(ARRAY_SIZE(opt_void_names), string_cmp, string_hash);
60+
nametbl->void_set = Set_new(ARRAY_SIZE(void_names), string_cmp, string_hash);
61+
nametbl->strict_set = Set_new(ARRAY_SIZE(strict_names), string_cmp, string_hash);
62+
63+
for (int i = 0; opt_void_names[i] != NULL; i++)
64+
Set_put(nametbl->opt_set, opt_void_names[i]);
65+
66+
for (int i = 0; void_names[i] != NULL; i++)
67+
Set_put(nametbl->void_set, void_names[i]);
68+
69+
for (int i = 0; strict_names[i] != NULL; i++)
70+
Set_put(nametbl->strict_set, strict_names[i]);
71+
72+
return nametbl;
73+
}
74+
75+
void Tag_lookup_free(T *t)
76+
{
77+
assert(t && *t);
78+
79+
Set_free(&(*t)->opt_set);
80+
Set_free(&(*t)->void_set);
81+
Set_free(&(*t)->strict_set);
82+
83+
FREE(*t);
84+
}
85+
86+
Tag_E Tag_lookup_tag(T *t, const char *name)
87+
{
88+
assert(t && *t);
89+
assert(name);
90+
91+
assert((*t)->opt_set);
92+
assert((*t)->void_set);
93+
assert((*t)->strict_set);
94+
95+
if (Set_member((*t)->opt_set, name)) return T_OPTNL;
96+
if (Set_member((*t)->void_set, name)) return T_VOID;
97+
if (Set_member((*t)->strict_set, name)) return T_STRCT;
98+
99+
return T_UNKWN;
100+
}
101+
102+
static int string_cmp(const void *str1, const void *str2)
103+
{
104+
return strcmp((const char *) str1, (const char *) str2);
105+
}
106+
107+
/* one-at-a-time hash:
108+
* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
109+
*/
110+
static unsigned string_hash(const void *str)
111+
{
112+
int len = strlen((const char *) str);
113+
unsigned char *p = (unsigned char *) str;
114+
unsigned h = 0;
115+
int i;
116+
117+
for ( i = 0; i < len; i++ ) {
118+
h += p[i];
119+
h += ( h << 10 );
120+
h ^= ( h >> 6 );
121+
}
122+
123+
h += ( h << 3 );
124+
h ^= ( h >> 11 );
125+
h += ( h << 15 );
126+
127+
return h;
128+
}
129+
130+
const char *Tag_type_rep(Tag_E t)
131+
{
132+
Text_T rep = Text_box("", 0);
133+
134+
if (t & T_YATTR)
135+
rep = Text_cat(rep, Text_put("T_YATTR | "));
136+
if (t & T_NATTR)
137+
rep = Text_cat(rep, Text_put("T_NATTR | "));
138+
if (t & T_OPTNL)
139+
rep = Text_cat(rep, Text_put("T_OPTNL | "));
140+
if (t & T_STRCT)
141+
rep = Text_cat(rep, Text_put("T_STRCT | "));
142+
if (t & T_VOID)
143+
rep = Text_cat(rep, Text_put("T_VOID | "));
144+
if (t & T_CMMNT)
145+
rep = Text_cat(rep, Text_put("T_CMMNT | "));
146+
if (t & T_INSTR)
147+
rep = Text_cat(rep, Text_put("T_INSTR | "));
148+
if (t & T_CLOSE)
149+
rep = Text_cat(rep, Text_put("T_CLOSE | "));
150+
if (t & T_UNKWN)
151+
rep = Text_cat(rep, Text_put("T_UNKWN | "));
152+
153+
return Text_get(NULL, -1, Text_sub(rep, 1, -3));
154+
}

0 commit comments

Comments
 (0)