diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2013-10-05 21:26:09 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2013-10-05 21:26:09 -0700 |
commit | e39dea5833abe29b7f6b9ba5d55f93b553a7cded (patch) | |
tree | 5e87f46369e075e8a47c8a5b97958e6cf934db63 /hc.c | |
parent | e022ebd1f2b414837b60f434e6db26e2c999207a (diff) | |
download | hc-e39dea5833abe29b7f6b9ba5d55f93b553a7cded.tar.gz hc-e39dea5833abe29b7f6b9ba5d55f93b553a7cded.tar.bz2 hc-e39dea5833abe29b7f6b9ba5d55f93b553a7cded.zip |
Attribute filtering implemented.
Diffstat (limited to 'hc.c')
-rw-r--r-- | hc.c | 83 |
1 files changed, 79 insertions, 4 deletions
@@ -4,7 +4,6 @@ #include "hc.h" #include "wl.h" - static allowed_el_t *allowed_el[tok_max]; static const token_t blank; @@ -18,7 +17,7 @@ static void bail() static token_t mktok(toktype_t type, char *text) { - token_t tok = { 0, 0, 0, 0 }; + token_t tok = { 0, 0, 0, 0, 0 }; tok.type = type; tok.lexeme = strdup(text); return tok; @@ -38,7 +37,12 @@ static token_t gettok(void) { if (null(pushback)) { int type = yylex(); - return mktok(type, yytext); + token_t tok = mktok(type, yytext); + if (type >= tok_el_unknown && type < tok_at_unknown) + tok.is_el = 1; + if (type >= tok_at_unknown && type < tok_max) + tok.is_at = 1; + return tok; } else { token_t tok = pushback; pushback = blank; @@ -102,6 +106,77 @@ static token_t printuntil(int type) return tok; } +static int allowed_attr(token_t el, token_t at) +{ + allowed_el_t *ael = allowed_el[el.type]; + int i; + + if (!ael || !ael->attr) + return 0; + + for (i = 0; ael->attr[i] != tok_eof; i++) + if (ael->attr[i] == at.type) + return 1; + + return 0; +} + +static void parse_attr(token_t el) +{ + for (;;) { + token_t ws0 = optmatch(tok_wsp); + token_t end = optmatch('/'); + token_t close = optmatch('>'); + + if (!null(end) && null(close)) + bail(); + + if (!null(close)) { + deltok(ws0); + deltok(printtok(end)); + deltok(printtok(close)); + break; + } + + if (null(ws0)) { + bail(); + } else { + token_t at = gettok(); + token_t equal = optmatch('='); + int allowed = allowed_attr(el, at); + + if (!at.is_at) + bail(); + + if (allowed) { + printtok(ws0); + printtok(at); + } + + if (!null(equal)) { + token_t val = gettok(); + + if (!val.is_el && !val.is_at && + val.type != tok_text && val.type != tok_wsp) + bail(); + + if (allowed) { + printtok(equal); + printtok(val); + } + deltok(val); + } + + deltok(equal); + deltok(at); + } + + deltok(ws0); + deltok(end); + deltok(close); + } +} + static void parse_element(token_t in) { token_t end = optmatch('/'); @@ -126,7 +201,7 @@ static void parse_element(token_t in) printtok(in); printtok(end); printtok(name); - deltok(printuntil('>')); + parse_attr(name); } else { deltok(lookfor('>')); } |