summaryrefslogtreecommitdiff
path: root/css
diff options
context:
space:
mode:
Diffstat (limited to 'css')
-rw-r--r--css/css.c25
-rw-r--r--css/css.h4
-rw-r--r--css/parser.y29
-rw-r--r--css/scanner.l1
4 files changed, 43 insertions, 16 deletions
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)),
&param);
@@ -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, &param);
-
+ if (!param.syntax_error)
+ css_parser_(c->data.css.css->parser, 0, 0, &param);
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 <stdbool.h>
#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,