diff options
Diffstat (limited to 'src/parse')
-rw-r--r-- | src/parse/properties/aural.c | 473 | ||||
-rw-r--r-- | src/parse/properties/properties.c | 2 | ||||
-rw-r--r-- | src/parse/properties/properties.h | 6 | ||||
-rw-r--r-- | src/parse/propstrings.c | 2 | ||||
-rw-r--r-- | src/parse/propstrings.h | 16 |
5 files changed, 379 insertions, 120 deletions
diff --git a/src/parse/properties/aural.c b/src/parse/properties/aural.c index c2ddb82..0c4f365 100644 --- a/src/parse/properties/aural.c +++ b/src/parse/properties/aural.c @@ -5,6 +5,7 @@ * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org> */ +#include <assert.h> #include <string.h> #include "bytecode/bytecode.h" @@ -15,6 +16,9 @@ static css_error parse_cue_common(css_language *c, const parserutils_vector *vector, int *ctx, uint16_t op, css_style **result); +static css_error parse_pause_common(css_language *c, + const parserutils_vector *vector, int *ctx, + uint16_t op, css_style **result); /** * Parse azimuth @@ -204,6 +208,148 @@ css_error parse_azimuth(css_language *c, } /** + * Parse cue shorthand + * + * \param c Parsing context + * \param vector Vector of tokens to process + * \param ctx Pointer to vector iteration context + * \param result Pointer to location to receive resulting style + * \return CSS_OK on success, + * CSS_NOMEM on memory exhaustion, + * CSS_INVALID if the input is not valid + * + * Post condition: \a *ctx is updated with the next token to process + * If the input is invalid, then \a *ctx remains unchanged. + */ +css_error parse_cue(css_language *c, + const parserutils_vector *vector, int *ctx, + css_style **result) +{ + int orig_ctx = *ctx; + const css_token *token; + css_style *before = NULL; + css_style *after = NULL; + css_style *ret = NULL; + int num_read = 0; + int prev_ctx; + uint32_t required_size; + css_error error; + + /* Deal with inherit */ + token = parserutils_vector_peek(vector, *ctx); + if (token != NULL && token->type == CSS_TOKEN_IDENT && + token->ilower == c->strings[INHERIT]) { + uint32_t *bytecode; + + error = css_stylesheet_style_create(c->sheet, + 2 * sizeof(uint32_t), &ret); + if (error != CSS_OK) { + *ctx = orig_ctx; + return error; + } + + bytecode = (uint32_t *) ret->bytecode; + + *(bytecode++) = buildOPV(CSS_PROP_CUE_BEFORE, FLAG_INHERIT, 0); + *(bytecode++) = buildOPV(CSS_PROP_CUE_AFTER, FLAG_INHERIT, 0); + + parserutils_vector_iterate(vector, ctx); + + *result = ret; + + return CSS_OK; + } else if (token == NULL) { + /* No tokens -- clearly garbage */ + *ctx = orig_ctx; + return CSS_INVALID; + } + + /* Attempt to read 1 or 2 cues */ + do { + prev_ctx = *ctx; + error = CSS_OK; + + if (before == NULL && (error = parse_cue_before(c, vector, ctx, + &before)) == CSS_OK) { + num_read = 1; + } else if (after == NULL && + (error = parse_cue_after(c, vector, ctx, + &after)) == CSS_OK) { + num_read = 2; + } + + if (error == CSS_OK) { + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, *ctx); + } else { + token = NULL; + } + } while (*ctx != prev_ctx && token != NULL); + + if (num_read == 0) { + error = CSS_INVALID; + goto cleanup; + } + + /* Calculate size of resultant style */ + if (num_read == 1) + required_size = 2 * before->length; + else + required_size = before->length + after->length; + + error = css_stylesheet_style_create(c->sheet, required_size, &ret); + if (error != CSS_OK) + goto cleanup; + + required_size = 0; + + if (num_read == 1) { + uint32_t *opv = ((uint32_t *) before->bytecode); + uint8_t flags = getFlags(*opv); + uint16_t value = getValue(*opv); + + memcpy(((uint8_t *) ret->bytecode) + required_size, + before->bytecode, before->length); + required_size += before->length; + + *opv = buildOPV(CSS_PROP_CUE_AFTER, flags, value); + memcpy(((uint8_t *) ret->bytecode) + required_size, + before->bytecode, before->length); + required_size += before->length; + } else { + memcpy(((uint8_t *) ret->bytecode) + required_size, + before->bytecode, before->length); + required_size += before->length; + + memcpy(((uint8_t *) ret->bytecode) + required_size, + after->bytecode, after->length); + required_size += after->length; + } + + assert(required_size == ret->length); + + /* Write the result */ + *result = ret; + /* Invalidate ret so that cleanup doesn't destroy it */ + ret = NULL; + + /* Clean up after ourselves */ +cleanup: + if (before) + css_stylesheet_style_destroy(c->sheet, before); + if (after) + css_stylesheet_style_destroy(c->sheet, after); + if (ret) + css_stylesheet_style_destroy(c->sheet, ret); + + if (error != CSS_OK) + *ctx = orig_ctx; + + return error; +} + +/** * Parse cue-after * * \param c Parsing context @@ -364,7 +510,7 @@ css_error parse_elevation(css_language *c, } /** - * Parse pause-after + * Parse pause shorthand * * \param c Parsing context * \param vector Vector of tokens to process @@ -377,76 +523,155 @@ css_error parse_elevation(css_language *c, * Post condition: \a *ctx is updated with the next token to process * If the input is invalid, then \a *ctx remains unchanged. */ -css_error parse_pause_after(css_language *c, +css_error parse_pause(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result) { int orig_ctx = *ctx; - css_error error; const css_token *token; - uint8_t flags = 0; - uint16_t value = 0; - uint32_t opv; - css_fixed length = 0; - uint32_t unit = 0; + css_style *before = NULL; + css_style *after = NULL; + css_style *ret = NULL; + int num_read = 0; + int prev_ctx; uint32_t required_size; + css_error error; - /* time | percentage | IDENT(inherit) */ + /* Deal with inherit */ token = parserutils_vector_peek(vector, *ctx); - if (token == NULL) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - if (token->type == CSS_TOKEN_IDENT && + if (token != NULL && token->type == CSS_TOKEN_IDENT && token->ilower == c->strings[INHERIT]) { - parserutils_vector_iterate(vector, ctx); - flags = FLAG_INHERIT; - } else { - error = parse_unit_specifier(c, vector, ctx, UNIT_S, - &length, &unit); + uint32_t *bytecode; + + error = css_stylesheet_style_create(c->sheet, + 2 * sizeof(uint32_t), &ret); if (error != CSS_OK) { *ctx = orig_ctx; return error; } - if ((unit & UNIT_TIME) == false && (unit & UNIT_PCT) == false) { - *ctx = orig_ctx; - return CSS_INVALID; + bytecode = (uint32_t *) ret->bytecode; + + *(bytecode++) = buildOPV(CSS_PROP_PAUSE_BEFORE, + FLAG_INHERIT, 0); + *(bytecode++) = buildOPV(CSS_PROP_PAUSE_AFTER, + FLAG_INHERIT, 0); + + parserutils_vector_iterate(vector, ctx); + + *result = ret; + + return CSS_OK; + } else if (token == NULL) { + /* No tokens -- clearly garbage */ + *ctx = orig_ctx; + return CSS_INVALID; + } + + /* Attempt to read 1 or 2 pauses */ + do { + prev_ctx = *ctx; + error = CSS_OK; + + if (before == NULL && (error = parse_pause_before(c, vector, + ctx, &before)) == CSS_OK) { + num_read = 1; + } else if (after == NULL && + (error = parse_pause_after(c, vector, ctx, + &after)) == CSS_OK) { + num_read = 2; } - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; + if (error == CSS_OK) { + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, *ctx); + } else { + token = NULL; } + } while (*ctx != prev_ctx && token != NULL); - value = PAUSE_AFTER_SET; + if (num_read == 0) { + error = CSS_INVALID; + goto cleanup; } - opv = buildOPV(CSS_PROP_PAUSE_AFTER, flags, value); + /* Calculate size of resultant style */ + if (num_read == 1) + required_size = 2 * before->length; + else + required_size = before->length + after->length; - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == PAUSE_AFTER_SET) - required_size += sizeof(length) + sizeof(unit); + error = css_stylesheet_style_create(c->sheet, required_size, &ret); + if (error != CSS_OK) + goto cleanup; - /* Allocate result */ - error = css_stylesheet_style_create(c->sheet, required_size, result); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } + required_size = 0; - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - if ((flags & FLAG_INHERIT) == false && value == PAUSE_AFTER_SET) { - memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), - &length, sizeof(length)); - memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) + - sizeof(length), &unit, sizeof(unit)); + if (num_read == 1) { + uint32_t *opv = ((uint32_t *) before->bytecode); + uint8_t flags = getFlags(*opv); + uint16_t value = getValue(*opv); + + memcpy(((uint8_t *) ret->bytecode) + required_size, + before->bytecode, before->length); + required_size += before->length; + + *opv = buildOPV(CSS_PROP_PAUSE_AFTER, flags, value); + memcpy(((uint8_t *) ret->bytecode) + required_size, + before->bytecode, before->length); + required_size += before->length; + } else { + memcpy(((uint8_t *) ret->bytecode) + required_size, + before->bytecode, before->length); + required_size += before->length; + + memcpy(((uint8_t *) ret->bytecode) + required_size, + after->bytecode, after->length); + required_size += after->length; } - return CSS_OK; + assert(required_size == ret->length); + + /* Write the result */ + *result = ret; + /* Invalidate ret so that cleanup doesn't destroy it */ + ret = NULL; + + /* Clean up after ourselves */ +cleanup: + if (before) + css_stylesheet_style_destroy(c->sheet, before); + if (after) + css_stylesheet_style_destroy(c->sheet, after); + if (ret) + css_stylesheet_style_destroy(c->sheet, ret); + + if (error != CSS_OK) + *ctx = orig_ctx; + + return error; +} + +/** + * Parse pause-after + * + * \param c Parsing context + * \param vector Vector of tokens to process + * \param ctx Pointer to vector iteration context + * \param result Pointer to location to receive resulting style + * \return CSS_OK on success, + * CSS_NOMEM on memory exhaustion, + * CSS_INVALID if the input is not valid + * + * Post condition: \a *ctx is updated with the next token to process + * If the input is invalid, then \a *ctx remains unchanged. + */ +css_error parse_pause_after(css_language *c, + const parserutils_vector *vector, int *ctx, + css_style **result) +{ + return parse_pause_common(c, vector, ctx, CSS_PROP_PAUSE_AFTER, result); } /** @@ -467,72 +692,8 @@ css_error parse_pause_before(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result) { - int orig_ctx = *ctx; - css_error error; - const css_token *token; - uint8_t flags = 0; - uint16_t value = 0; - uint32_t opv; - css_fixed length = 0; - uint32_t unit = 0; - uint32_t required_size; - - /* time | percentage | IDENT(inherit) */ - token = parserutils_vector_peek(vector, *ctx); - if (token == NULL) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - if (token->type == CSS_TOKEN_IDENT && - token->ilower == c->strings[INHERIT]) { - parserutils_vector_iterate(vector, ctx); - flags = FLAG_INHERIT; - } else { - error = parse_unit_specifier(c, vector, ctx, UNIT_S, - &length, &unit); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - if ((unit & UNIT_TIME) == false && (unit & UNIT_PCT) == false) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - /* Negative values are illegal */ - if (length < 0) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - value = PAUSE_BEFORE_SET; - } - - opv = buildOPV(CSS_PROP_PAUSE_BEFORE, flags, value); - - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == PAUSE_BEFORE_SET) - required_size += sizeof(length) + sizeof(unit); - - /* Allocate result */ - error = css_stylesheet_style_create(c->sheet, required_size, result); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - - /* Copy the bytecode to it */ - memcpy((*result)->bytecode, &opv, sizeof(opv)); - if ((flags & FLAG_INHERIT) == false && value == PAUSE_BEFORE_SET) { - memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), - &length, sizeof(length)); - memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) + - sizeof(length), &unit, sizeof(unit)); - } - - return CSS_OK; + return parse_pause_common(c, vector, ctx, + CSS_PROP_PAUSE_BEFORE, result); } /** @@ -1617,6 +1778,7 @@ css_error parse_volume(css_language *c, * \param c Parsing context * \param vector Vector of tokens to process * \param ctx Pointer to vector iteration context + * \param op Opcode to parse for * \param result Pointer to location to receive resulting style * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion, @@ -1683,3 +1845,90 @@ css_error parse_cue_common(css_language *c, return CSS_OK; } +/** + * Common parser for pause-after and pause-before + * + * \param c Parsing context + * \param vector Vector of tokens to process + * \param ctx Pointer to vector iteration context + * \param op Opcode to parse for + * \param result Pointer to location to receive resulting style + * \return CSS_OK on success, + * CSS_NOMEM on memory exhaustion, + * CSS_INVALID if the input is not valid + * + * Post condition: \a *ctx is updated with the next token to process + * If the input is invalid, then \a *ctx remains unchanged. + */ +css_error parse_pause_common(css_language *c, + const parserutils_vector *vector, int *ctx, + uint16_t op, css_style **result) +{ + int orig_ctx = *ctx; + css_error error; + const css_token *token; + uint8_t flags = 0; + uint16_t value = 0; + uint32_t opv; + css_fixed length = 0; + uint32_t unit = 0; + uint32_t required_size; + + /* time | percentage | IDENT(inherit) */ + token = parserutils_vector_peek(vector, *ctx); + if (token == NULL) { + *ctx = orig_ctx; + return CSS_INVALID; + } + + if (token->type == CSS_TOKEN_IDENT && + token->ilower == c->strings[INHERIT]) { + parserutils_vector_iterate(vector, ctx); + flags = FLAG_INHERIT; + } else { + error = parse_unit_specifier(c, vector, ctx, UNIT_S, + &length, &unit); + if (error != CSS_OK) { + *ctx = orig_ctx; + return error; + } + + if ((unit & UNIT_TIME) == false && (unit & UNIT_PCT) == false) { + *ctx = orig_ctx; + return CSS_INVALID; + } + + /* Negative values are illegal */ + if (length < 0) { + *ctx = orig_ctx; + return CSS_INVALID; + } + + value = PAUSE_AFTER_SET; + } + + opv = buildOPV(op, flags, value); + + required_size = sizeof(opv); + if ((flags & FLAG_INHERIT) == false && value == PAUSE_AFTER_SET) + required_size += sizeof(length) + sizeof(unit); + + /* Allocate result */ + error = css_stylesheet_style_create(c->sheet, required_size, result); + if (error != CSS_OK) { + *ctx = orig_ctx; + return error; + } + + /* Copy the bytecode to it */ + memcpy((*result)->bytecode, &opv, sizeof(opv)); + if ((flags & FLAG_INHERIT) == false && value == PAUSE_AFTER_SET) { + memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv), + &length, sizeof(length)); + memcpy(((uint8_t *) (*result)->bytecode) + sizeof(opv) + + sizeof(length), &unit, sizeof(unit)); + } + + return CSS_OK; +} + diff --git a/src/parse/properties/properties.c b/src/parse/properties/properties.c index de92933..7e54f16 100644 --- a/src/parse/properties/properties.c +++ b/src/parse/properties/properties.c @@ -49,6 +49,7 @@ const css_prop_handler property_handlers[LAST_PROP + 1 - FIRST_PROP] = parse_content, parse_counter_increment, parse_counter_reset, + parse_cue, parse_cue_after, parse_cue_before, parse_cursor, @@ -90,6 +91,7 @@ const css_prop_handler property_handlers[LAST_PROP + 1 - FIRST_PROP] = parse_page_break_after, parse_page_break_before, parse_page_break_inside, + parse_pause, parse_pause_after, parse_pause_before, parse_pitch_range, diff --git a/src/parse/properties/properties.h b/src/parse/properties/properties.h index 78a37d8..f4d0c8b 100644 --- a/src/parse/properties/properties.h +++ b/src/parse/properties/properties.h @@ -133,6 +133,9 @@ css_error parse_counter_increment(css_language *c, css_error parse_counter_reset(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result); +css_error parse_cue(css_language *c, + const parserutils_vector *vector, int *ctx, + css_style **result); css_error parse_cue_after(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result); @@ -256,6 +259,9 @@ css_error parse_page_break_before(css_language *c, css_error parse_page_break_inside(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result); +css_error parse_pause(css_language *c, + const parserutils_vector *vector, int *ctx, + css_style **result); css_error parse_pause_after(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result); diff --git a/src/parse/propstrings.c b/src/parse/propstrings.c index fbe2d66..34c849a 100644 --- a/src/parse/propstrings.c +++ b/src/parse/propstrings.c @@ -79,6 +79,7 @@ const stringmap_entry stringmap[LAST_KNOWN] = { { "content", SLEN("content") }, { "counter-increment", SLEN("counter-increment") }, { "counter-reset", SLEN("counter-reset") }, + { "cue", SLEN("cue") }, { "cue-after", SLEN("cue-after") }, { "cue-before", SLEN("cue-before") }, { "cursor", SLEN("cursor") }, @@ -120,6 +121,7 @@ const stringmap_entry stringmap[LAST_KNOWN] = { { "page-break-after", SLEN("page-break-after") }, { "page-break-before", SLEN("page-break-before") }, { "page-break-inside", SLEN("page-break-inside") }, + { "pause", SLEN("pause") }, { "pause-after", SLEN("pause-after") }, { "pause-before", SLEN("pause-before") }, { "pitch-range", SLEN("pitch-range") }, diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h index 3ea8858..d90803f 100644 --- a/src/parse/propstrings.h +++ b/src/parse/propstrings.h @@ -40,7 +40,7 @@ enum { BORDER_RIGHT_STYLE, BORDER_RIGHT_WIDTH, BORDER_SPACING, BORDER_STYLE, BORDER_TOP, BORDER_TOP_COLOR, BORDER_TOP_STYLE, BORDER_TOP_WIDTH, BORDER_WIDTH, BOTTOM, CAPTION_SIDE, CLEAR, - CLIP, COLOR, CONTENT, COUNTER_INCREMENT, COUNTER_RESET, CUE_AFTER, + CLIP, COLOR, CONTENT, COUNTER_INCREMENT, COUNTER_RESET, CUE, CUE_AFTER, CUE_BEFORE, CURSOR, DIRECTION, DISPLAY, ELEVATION, EMPTY_CELLS, FLOAT, FONT_FAMILY, FONT_SIZE, FONT_STYLE, FONT_VARIANT, FONT_WEIGHT, HEIGHT, LEFT, LETTER_SPACING, LINE_HEIGHT, LIST_STYLE_IMAGE, @@ -48,13 +48,13 @@ enum { MARGIN_RIGHT, MARGIN_TOP, MAX_HEIGHT, MAX_WIDTH, MIN_HEIGHT, MIN_WIDTH, ORPHANS, OUTLINE, OUTLINE_COLOR, OUTLINE_STYLE, OUTLINE_WIDTH, OVERFLOW, PADDING_BOTTOM, PADDING_LEFT, PADDING_RIGHT, PADDING_TOP, - PAGE_BREAK_AFTER, PAGE_BREAK_BEFORE, PAGE_BREAK_INSIDE, PAUSE_AFTER, - PAUSE_BEFORE, PITCH_RANGE, PITCH, PLAY_DURING, POSITION, QUOTES, - RICHNESS, RIGHT, SPEAK_HEADER, SPEAK_NUMERAL, SPEAK_PUNCTUATION, SPEAK, - SPEECH_RATE, STRESS, TABLE_LAYOUT, TEXT_ALIGN, TEXT_DECORATION, - TEXT_INDENT, TEXT_TRANSFORM, TOP, UNICODE_BIDI, VERTICAL_ALIGN, - VISIBILITY, VOICE_FAMILY, VOLUME, WHITE_SPACE, WIDOWS, WIDTH, - WORD_SPACING, Z_INDEX, + PAGE_BREAK_AFTER, PAGE_BREAK_BEFORE, PAGE_BREAK_INSIDE, PAUSE, + PAUSE_AFTER, PAUSE_BEFORE, PITCH_RANGE, PITCH, PLAY_DURING, POSITION, + QUOTES, RICHNESS, RIGHT, SPEAK_HEADER, SPEAK_NUMERAL, + SPEAK_PUNCTUATION, SPEAK, SPEECH_RATE, STRESS, TABLE_LAYOUT, + TEXT_ALIGN, TEXT_DECORATION, TEXT_INDENT, TEXT_TRANSFORM, TOP, + UNICODE_BIDI, VERTICAL_ALIGN, VISIBILITY, VOICE_FAMILY, VOLUME, + WHITE_SPACE, WIDOWS, WIDTH, WORD_SPACING, Z_INDEX, LAST_PROP = Z_INDEX, |