From 13d6923b5e6edf727e00484ae05c22dbfa8e1c7c Mon Sep 17 00:00:00 2001 From: James Bursa Date: Fri, 17 Oct 2003 17:39:29 +0000 Subject: [project @ 2003-10-17 17:39:29 by bursa] Implement :link, ignore stylesheets with syntax errors, parse pseudo classes. svn path=/import/netsurf/; revision=367 --- css/css.c | 25 ++++++++++++++++++++----- css/css.h | 4 ++++ css/parser.y | 29 ++++++++++++++++++----------- css/scanner.l | 1 + 4 files changed, 43 insertions(+), 16 deletions(-) (limited to 'css') diff --git a/css/css.c b/css/css.c index 132bfa4bb..d2f4ef679 100644 --- a/css/css.c +++ b/css/css.c @@ -94,6 +94,7 @@ void css_create(struct content *c) LOG(("content %p", c)); c->data.css.css = xcalloc(1, sizeof(*c->data.css.css)); css_lex_init(&c->data.css.css->lexer); + /*css_parser_Trace(stderr, "css parser: ");*/ c->data.css.css->parser = css_parser_Alloc(malloc); for (i = 0; i != HASH_SIZE; i++) c->data.css.css->rule[i] = 0; @@ -118,14 +119,15 @@ int css_convert(struct content *c, unsigned int width, unsigned int height) { int token; YY_BUFFER_STATE buffer; - struct parse_params param = {0, c, 0}; + struct parse_params param = {0, c, 0, false}; c->data.css.data[c->data.css.length] = c->data.css.data[c->data.css.length + 1] = 0; buffer = css__scan_buffer(c->data.css.data, c->data.css.length + 2, c->data.css.css->lexer); assert(buffer); - while ((token = css_lex(c->data.css.css->lexer))) { + while ((token = css_lex(c->data.css.css->lexer)) && + !param.syntax_error) { css_parser_(c->data.css.css->parser, token, xstrdup(css_get_text(c->data.css.css->lexer)), ¶m); @@ -133,12 +135,20 @@ int css_convert(struct content *c, unsigned int width, unsigned int height) css__delete_buffer(buffer, c->data.css.css->lexer); free(c->data.css.data); - css_parser_(c->data.css.css->parser, 0, 0, ¶m); - + if (!param.syntax_error) + css_parser_(c->data.css.css->parser, 0, 0, ¶m); css_parser_Free(c->data.css.css->parser, free); + + if (param.syntax_error) { + int line = css_get_lineno(c->data.css.css->lexer); + css_lex_destroy(c->data.css.css->lexer); + LOG(("syntax error near line %i", line)); + /*css_destroy(c);*/ + return 1; + } css_lex_destroy(c->data.css.css->lexer); - /*css_dump_stylesheet(c->data.css.css);*/ + css_dump_stylesheet(c->data.css.css); /* complete fetch of any imported stylesheets */ while (c->active != 0) { @@ -428,6 +438,7 @@ bool css_match_rule(struct css_node *rule, xmlNode *element) return false; for (detail = rule->left; detail; detail = detail->next) { + s = 0; match = false; switch (detail->type) { case CSS_NODE_ID: @@ -497,6 +508,9 @@ bool css_match_rule(struct css_node *rule, xmlNode *element) } break; + case CSS_NODE_PSEUDO: + break; + default: assert(0); } @@ -653,6 +667,7 @@ void css_dump_stylesheet(const struct css_stylesheet * stylesheet) case CSS_NODE_ATTRIB_EQ: fprintf(stderr, "[%s=%s]", m->data, m->data2); break; case CSS_NODE_ATTRIB_INC: fprintf(stderr, "[%s~=%s]", m->data, m->data2); break; case CSS_NODE_ATTRIB_DM: fprintf(stderr, "[%s|=%s]", m->data, m->data2); break; + case CSS_NODE_PSEUDO: fprintf(stderr, ":%s", m->data); break; default: fprintf(stderr, "unexpected node"); } } diff --git a/css/css.h b/css/css.h index a897d4d9b..c58da6509 100644 --- a/css/css.h +++ b/css/css.h @@ -8,6 +8,7 @@ #ifndef _NETSURF_CSS_CSS_H_ #define _NETSURF_CSS_CSS_H_ +#include #include "libxml/HTMLparser.h" #include "css_enum.h" @@ -126,6 +127,7 @@ typedef enum { CSS_NODE_DASHMATCH, CSS_NODE_COLON, CSS_NODE_COMMA, + CSS_NODE_DOT, CSS_NODE_PLUS, CSS_NODE_GT, CSS_NODE_PAREN, @@ -137,6 +139,7 @@ typedef enum { CSS_NODE_ATTRIB_EQ, CSS_NODE_ATTRIB_INC, CSS_NODE_ATTRIB_DM, + CSS_NODE_PSEUDO, } css_node_type; typedef enum { @@ -172,6 +175,7 @@ struct parse_params { int ruleset_only; struct content *stylesheet; struct css_node *declaration; + bool syntax_error; }; #endif diff --git a/css/parser.y b/css/parser.y index 0d72a44d7..9fc1d398d 100644 --- a/css/parser.y +++ b/css/parser.y @@ -106,28 +106,30 @@ detail_list(A) ::= LBRAC IDENT(B) EQUALS IDENT(C) RBRAC detail_list(D). detail_list(A) ::= LBRAC IDENT(B) EQUALS STRING(C) RBRAC detail_list(D). { A = css_new_node(CSS_NODE_ATTRIB_EQ, B, 0, 0); A->data2 = css_unquote(C); A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } -detail_list(A) ::= LBRAC IDENT(B) EQUALS NUMBER(C) RBRAC detail_list(D). - { A = css_new_node(CSS_NODE_ATTRIB_EQ, B, 0, 0); A->data2 = C; - A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } detail_list(A) ::= LBRAC IDENT(B) INCLUDES IDENT(C) RBRAC detail_list(D). { A = css_new_node(CSS_NODE_ATTRIB_INC, B, 0, 0); A->data2 = C; A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } detail_list(A) ::= LBRAC IDENT(B) INCLUDES STRING(C) RBRAC detail_list(D). { A = css_new_node(CSS_NODE_ATTRIB_INC, B, 0, 0); A->data2 = css_unquote(C); A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } -detail_list(A) ::= LBRAC IDENT(B) INCLUDES NUMBER(C) RBRAC detail_list(D). - { A = css_new_node(CSS_NODE_ATTRIB_INC, B, 0, 0); A->data2 = C; - A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } detail_list(A) ::= LBRAC IDENT(B) DASHMATCH IDENT(C) RBRAC detail_list(D). { A = css_new_node(CSS_NODE_ATTRIB_DM, B, 0, 0); A->data2 = C; A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } detail_list(A) ::= LBRAC IDENT(B) DASHMATCH STRING(C) RBRAC detail_list(D). { A = css_new_node(CSS_NODE_ATTRIB_DM, B, 0, 0); A->data2 = css_unquote(C); A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } -detail_list(A) ::= LBRAC IDENT(B) DASHMATCH NUMBER(C) RBRAC detail_list(D). - { A = css_new_node(CSS_NODE_ATTRIB_DM, B, 0, 0); A->data2 = C; - A->specificity = 0x100 + (D ? D->specificity : 0); A->next = D; } -/* TODO: pseudo */ +detail_list(A) ::= COLON IDENT(B) detail_list(C). + { if (strcasecmp(B, "link") == 0) { + A = css_new_node(CSS_NODE_ATTRIB, xstrdup("href"), 0, 0); + A->specificity = 0x100 + (C ? C->specificity : 0); A->next = C; + free(B); + } else { + A = css_new_node(CSS_NODE_PSEUDO, B, 0, 0); + A->specificity = 0x100 + (C ? C->specificity : 0); A->next = C; + } } +detail_list(A) ::= COLON FUNCTION(B) IDENT RPAREN detail_list(C). + { A = css_new_node(CSS_NODE_PSEUDO, B, 0, 0); + A->specificity = 0x100 + (C ? C->specificity : 0); A->next = C; } declaration_list(A) ::= . { A = 0; } @@ -187,6 +189,8 @@ any(A) ::= COLON. { A = css_new_node(CSS_NODE_COLON, 0, 0, 0); } any(A) ::= COMMA. { A = css_new_node(CSS_NODE_COMMA, 0, 0, 0); } +any(A) ::= DOT. + { A = css_new_node(CSS_NODE_DOT, 0, 0, 0); } any(A) ::= PLUS. { A = css_new_node(CSS_NODE_PLUS, 0, 0, 0); } any(A) ::= GT. @@ -233,7 +237,10 @@ any(A) ::= LBRAC any_list(B) RBRAC. %destructor any_list_1 { css_free_node($$); } %destructor any { css_free_node($$); } -%left COMMA GT HASH LBRAC PLUS. +%left COLON COMMA GT HASH LBRAC PLUS. +%left DOT. %left EMPTYIDENT. %left IDENT. %left LBRACE. + +%syntax_error { param->syntax_error = true; } diff --git a/css/scanner.l b/css/scanner.l index ccac33c1d..168ca012a 100644 --- a/css/scanner.l +++ b/css/scanner.l @@ -18,6 +18,7 @@ %option reentrant %option never-interactive %option noyywrap +%option yylineno /* see CSS2 Specification, chapter 4 http://www.w3.org/TR/REC-CSS2/syndata.html, -- cgit v1.2.3