summaryrefslogtreecommitdiffstats
path: root/hc.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2013-10-05 21:26:09 -0700
committerKaz Kylheku <kaz@kylheku.com>2013-10-05 21:26:09 -0700
commite39dea5833abe29b7f6b9ba5d55f93b553a7cded (patch)
tree5e87f46369e075e8a47c8a5b97958e6cf934db63 /hc.c
parente022ebd1f2b414837b60f434e6db26e2c999207a (diff)
downloadhc-e39dea5833abe29b7f6b9ba5d55f93b553a7cded.tar.gz
hc-e39dea5833abe29b7f6b9ba5d55f93b553a7cded.tar.bz2
hc-e39dea5833abe29b7f6b9ba5d55f93b553a7cded.zip
Attribute filtering implemented.
Diffstat (limited to 'hc.c')
-rw-r--r--hc.c83
1 files changed, 79 insertions, 4 deletions
diff --git a/hc.c b/hc.c
index 3efb28a..1d85315 100644
--- a/hc.c
+++ b/hc.c
@@ -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('>'));
}