diff options
-rw-r--r-- | src/parse/css21.c | 46 | ||||
-rw-r--r-- | src/parse/parse.c | 25 | ||||
-rw-r--r-- | src/parse/parse.h | 3 |
3 files changed, 61 insertions, 13 deletions
diff --git a/src/parse/css21.c b/src/parse/css21.c index 24ed6e0..7a8d6b4 100644 --- a/src/parse/css21.c +++ b/src/parse/css21.c @@ -17,6 +17,22 @@ #include "utils/parserutilserror.h" #include "utils/utils.h" +enum { + CHARSET, IMPORT, MEDIA, PAGE, + + LAST_KNOWN +}; + +static struct { + const char *ptr; + size_t len; +} stringmap[] = { + { "charset", SLEN("charset") }, + { "import", SLEN("import") }, + { "media", SLEN("media") }, + { "page", SLEN("page") }, +}; + /** * Context for a CSS 2.1 parser */ @@ -33,6 +49,8 @@ struct css_css21 { HAD_RULE, } state; /**< State flag, for at-rule handling */ + const uint8_t *strings[LAST_KNOWN]; /**< Interned strings */ + css_alloc alloc; /**< Memory (de)allocation function */ void *pw; /**< Client's private data */ }; @@ -92,6 +110,17 @@ css_css21 *css_css21_create(css_stylesheet *sheet, css_parser *parser, return NULL; } + for (int i = 0; i < LAST_KNOWN; i++) { + css21->strings[i] = css_parser_dict_add(parser, + (const uint8_t *) stringmap[i].ptr, + stringmap[i].len); + if (css21->strings[i] == NULL) { + parserutils_stack_destroy(css21->context); + alloc(css21, 0, pw); + return NULL; + } + } + params.event_handler.handler = css21_handle_event; params.event_handler.pw = css21; error = css_parser_setopt(parser, CSS_PARSER_EVENT_HANDLER, ¶ms); @@ -284,10 +313,7 @@ css_error handleStartAtRule(css_css21 *c, const parserutils_vector *vector) * there is one */ assert(atkeyword != NULL && atkeyword->type == CSS_TOKEN_ATKEYWORD); - /** \todo Erm. Strings are interned now. Stop looking at their data */ - if (atkeyword->data.len == SLEN("charset") && - strncasecmp((const char *) atkeyword->data.ptr, - "charset", SLEN("charset")) == 0) { + if (atkeyword->lower.ptr == c->strings[CHARSET]) { if (c->state == BEFORE_CHARSET) { /* any0 = STRING */ if (any == 0) @@ -305,18 +331,12 @@ css_error handleStartAtRule(css_css21 *c, const parserutils_vector *vector) } else { return CSS_INVALID; } - } else if (atkeyword->data.len == SLEN("import") && - strncasecmp((const char *) atkeyword->data.ptr, - "import", SLEN("import")) == 0) { + } else if (atkeyword->data.ptr == c->strings[IMPORT]) { /** \todo any0 = (STRING | URI) ws * (IDENT ws (',' ws IDENT ws)* )? */ - } else if (atkeyword->data.len == SLEN("media") && - strncasecmp((const char *) atkeyword->data.ptr, - "media", SLEN("media")) == 0) { + } else if (atkeyword->data.ptr == c->strings[MEDIA]) { /** \todo any0 = IDENT ws (',' ws IDENT ws)* */ - } else if (atkeyword->data.len == SLEN("page") && - strncasecmp((const char *) atkeyword->data.ptr, - "page", SLEN("page")) == 0) { + } else if (atkeyword->data.ptr == c->strings[PAGE]) { /** \todo any0 = (':' IDENT)? ws */ } else { return CSS_INVALID; diff --git a/src/parse/parse.c b/src/parse/parse.c index 533d822..1095c26 100644 --- a/src/parse/parse.c +++ b/src/parse/parse.c @@ -403,6 +403,31 @@ const char *css_parser_read_charset(css_parser *parser, return parserutils_inputstream_read_charset(parser->stream, source); } +/** + * Add an entry to the parser dictionary + * + * \param parser The parser instance + * \param ptr Pointer to data + * \param len Length, in bytes, of data + * \return Pointer to data in dictionary, or NULL on memory exhaustion + */ +const uint8_t *css_parser_dict_add(css_parser *parser, const uint8_t *ptr, + size_t len) +{ + const parserutils_dict_entry *interned; + parserutils_error perror; + + if (parser == NULL || ptr == NULL || len == 0) + return NULL; + + perror = parserutils_dict_insert(parser->dictionary, ptr, len, + &interned); + if (perror != PARSERUTILS_OK) + return NULL; + + return interned->data; +} + /****************************************************************************** * Helper functions * ******************************************************************************/ diff --git a/src/parse/parse.h b/src/parse/parse.h index ec88347..7d7f56d 100644 --- a/src/parse/parse.h +++ b/src/parse/parse.h @@ -70,5 +70,8 @@ css_error css_parser_completed(css_parser *parser); const char *css_parser_read_charset(css_parser *parser, css_charset_source *source); +const uint8_t *css_parser_dict_add(css_parser *parser, + const uint8_t *ptr, size_t len); + #endif |