From e3afbca5b4a25d07d3cd32b16ecb0f7401c46109 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Wed, 30 Jul 2008 23:53:26 +0000 Subject: Generate and emit events svn path=/trunk/libcss/; revision=4828 --- src/parse/parse.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parse/parse.h | 28 +++++++++++++++++++ test/parse.c | 38 ++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) diff --git a/src/parse/parse.c b/src/parse/parse.c index 67b2fa8..2083ace 100644 --- a/src/parse/parse.c +++ b/src/parse/parse.c @@ -96,6 +96,9 @@ struct css_parser uint8_t match_char; /**< Close bracket type for parseAny */ + css_parser_event_handler event; /**< Client's event handler */ + void *event_pw; /**< Client data for event handler */ + css_alloc alloc; /**< Memory (de)allocation function */ void *pw; /**< Client-specific private data */ }; @@ -242,6 +245,8 @@ css_parser *css_parser_create(css_stylesheet *sheet, const char *charset, parser->pushback = NULL; parser->parseError = false; parser->match_char = 0; + parser->event = NULL; + parser->event_pw = NULL; parser->alloc = alloc; parser->pw = pw; @@ -289,6 +294,10 @@ css_error css_parser_setopt(css_parser *parser, css_parser_opttype type, case CSS_PARSER_QUIRKS: parser->quirks = params->quirks; break; + case CSS_PARSER_EVENT_HANDLER: + parser->event = params->event_handler.handler; + parser->event_pw = params->event_handler.pw; + break; } return CSS_OK; @@ -596,6 +605,11 @@ css_error parseStart(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) printf("Begin stylesheet\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_START_STYLESHEET, NULL, + parser->event_pw); + } + error = eatWS(parser); if (error != CSS_OK) return error; @@ -620,6 +634,11 @@ css_error parseStart(css_parser *parser) parserutils_vector_dump(parser->tokens, __func__, tprinter); printf("End stylesheet\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_END_STYLESHEET, NULL, + parser->event_pw); + } + parserutils_vector_clear(parser->tokens); return done(parser); @@ -722,6 +741,11 @@ css_error parseRuleset(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) printf("Begin ruleset\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_START_RULESET, NULL, + parser->event_pw); + } + parserutils_vector_clear(parser->tokens); error = getToken(parser, &token); @@ -834,6 +858,9 @@ css_error parseRulesetEnd(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) printf("End ruleset\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_END_RULESET, NULL, parser->event_pw); + } return done(parser); } @@ -901,6 +928,13 @@ css_error parseAtRuleEnd(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) parserutils_vector_dump(parser->tokens, __func__, tprinter); #endif + if (parser->event != NULL) { + if (parser->event(CSS_PARSER_START_ATRULE, + parser->tokens, parser->event_pw) == + false) { + /** \todo parse error */ + } + } error = getToken(parser, &token); if (error != CSS_OK) @@ -940,6 +974,9 @@ css_error parseAtRuleEnd(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) printf("End at-rule\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_END_ATRULE, NULL, parser->event_pw); + } return done(parser); } @@ -962,6 +999,11 @@ css_error parseBlock(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) printf("Begin block\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_START_BLOCK, NULL, + parser->event_pw); + } + parserutils_vector_clear(parser->tokens); if (token->type != CSS_TOKEN_CHAR || token->data.len != 1 || @@ -1010,6 +1052,10 @@ css_error parseBlock(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) printf("End block\n"); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_END_BLOCK, NULL, parser->event_pw); + } + parserutils_vector_clear(parser->tokens); return done(parser); @@ -1054,6 +1100,15 @@ css_error parseBlockContent(css_parser *parser) parserutils_vector_dump(parser->tokens, __func__, tprinter); #endif + if (parser->event != NULL) { + if (parser->event( + CSS_PARSER_BLOCK_CONTENT, + parser->tokens, + parser->event_pw) == + false) { + /** \todo parse error */ + } + } return transition(parser, to, subsequent); @@ -1072,6 +1127,15 @@ css_error parseBlockContent(css_parser *parser) parserutils_vector_dump(parser->tokens, __func__, tprinter); #endif + if (parser->event != NULL) { + if (parser->event( + CSS_PARSER_BLOCK_CONTENT, + parser->tokens, + parser->event_pw) == + false) { + /** \todo parse error */ + } + } return done(parser); } @@ -1086,6 +1150,15 @@ css_error parseBlockContent(css_parser *parser) parserutils_vector_dump(parser->tokens, __func__, tprinter); #endif + if (parser->event != NULL) { + if (parser->event( + CSS_PARSER_BLOCK_CONTENT, + parser->tokens, + parser->event_pw) == + false) { + /** \todo parse error */ + } + } return done(parser); } @@ -1134,6 +1207,11 @@ css_error parseSelector(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) parserutils_vector_dump(parser->tokens, __func__, tprinter); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_SELECTOR, parser->tokens, + parser->event_pw); + } + break; } @@ -1201,6 +1279,10 @@ css_error parseDeclaration(css_parser *parser) #if !defined(NDEBUG) && defined(DEBUG_EVENTS) parserutils_vector_dump(parser->tokens, __func__, tprinter); #endif + if (parser->event != NULL) { + parser->event(CSS_PARSER_DECLARATION, parser->tokens, + parser->event_pw); + } break; } diff --git a/src/parse/parse.h b/src/parse/parse.h index d4ae3c4..c1b6830 100644 --- a/src/parse/parse.h +++ b/src/parse/parse.h @@ -8,16 +8,39 @@ #ifndef css_parse_parse_h_ #define css_parse_parse_h_ +#include + #include #include typedef struct css_parser css_parser; +/** + * Parser event types + */ +typedef enum css_parser_event { + CSS_PARSER_START_STYLESHEET, + CSS_PARSER_END_STYLESHEET, + CSS_PARSER_START_RULESET, + CSS_PARSER_END_RULESET, + CSS_PARSER_START_ATRULE, + CSS_PARSER_END_ATRULE, + CSS_PARSER_START_BLOCK, + CSS_PARSER_END_BLOCK, + CSS_PARSER_BLOCK_CONTENT, + CSS_PARSER_SELECTOR, + CSS_PARSER_DECLARATION, +} css_parser_event; + +typedef bool (*css_parser_event_handler)(css_parser_event type, + const parserutils_vector *tokens, void *pw); + /** * Parser option types */ typedef enum css_parser_opttype { CSS_PARSER_QUIRKS, + CSS_PARSER_EVENT_HANDLER, } css_parser_opttype; /** @@ -25,6 +48,11 @@ typedef enum css_parser_opttype { */ typedef union css_parser_optparams { bool quirks; + + struct { + css_parser_event_handler handler; + void *pw; + } event_handler; } css_parser_optparams; css_parser *css_parser_create(css_stylesheet *sheet, const char *charset, diff --git a/test/parse.c b/test/parse.c index f24aa76..567c8c4 100644 --- a/test/parse.c +++ b/test/parse.c @@ -6,6 +6,7 @@ #include "charset/detect.h" #include "utils/utils.h" +#include "lex/lex.h" #include "parse/parse.h" #include "testutils.h" @@ -17,8 +18,40 @@ static void *myrealloc(void *ptr, size_t len, void *pw) return realloc(ptr, len); } +static bool event_handler(css_parser_event type, + const parserutils_vector *tokens, void *pw) +{ + int32_t ctx = 0; + const css_token *token; + + UNUSED(pw); + + printf("%s%d", tokens != NULL ? " " : "", type); + + if (tokens == NULL) { + printf("\n"); + return true; + } + + do { + token = parserutils_vector_iterate(tokens, &ctx); + if (token == NULL) + break; + + printf("\n %d", token->type); + + if (token->data.ptr != NULL) + printf(" %.*s", token->data.len, token->data.ptr); + } while (token != NULL); + + printf("\n"); + + return true; +} + int main(int argc, char **argv) { + css_parser_optparams params; css_parser *parser; FILE *fp; size_t len, origlen; @@ -38,6 +71,11 @@ int main(int argc, char **argv) "UTF-8", CSS_CHARSET_DICTATED, myrealloc, NULL); assert(parser != NULL); + params.event_handler.handler = event_handler; + params.event_handler.pw = NULL; + assert(css_parser_setopt(parser, CSS_PARSER_EVENT_HANDLER, + ¶ms) == CSS_OK); + fp = fopen(argv[2], "rb"); if (fp == NULL) { printf("Failed opening %s\n", argv[2]); -- cgit v1.2.3