From fac6e78e4235414393b828646106071de57f5a51 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Thu, 25 Jun 2009 22:59:47 +0000 Subject: List-style shorthand parser svn path=/trunk/libcss/; revision=7994 --- src/parse/properties/generated_list.c | 173 ++++++++++++++++++++++++++++++++++ src/parse/properties/properties.c | 1 + src/parse/properties/properties.h | 3 + src/parse/propstrings.c | 1 + src/parse/propstrings.h | 16 ++-- 5 files changed, 186 insertions(+), 8 deletions(-) (limited to 'src/parse') diff --git a/src/parse/properties/generated_list.c b/src/parse/properties/generated_list.c index 0ba0618..189aa55 100644 --- a/src/parse/properties/generated_list.c +++ b/src/parse/properties/generated_list.c @@ -5,6 +5,7 @@ * Copyright 2009 John-Mark Bell */ +#include #include #include "bytecode/bytecode.h" @@ -172,6 +173,178 @@ css_error parse_counter_reset(css_language *c, CSS_PROP_COUNTER_RESET, result); } +/** + * Parse list-style + * + * \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_list_style(css_language *c, + const parserutils_vector *vector, int *ctx, + css_style **result) +{ + int orig_ctx = *ctx; + int prev_ctx; + const css_token *token; + css_style *image = NULL; + css_style *position = NULL; + css_style *type = NULL; + css_style *ret = NULL; + uint32_t required_size; + css_error error; + + /* Firstly, handle 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, + 3 * sizeof(uint32_t), &ret); + if (error != CSS_OK) { + *ctx = orig_ctx; + return error; + } + + bytecode = (uint32_t *) ret->bytecode; + + *(bytecode++) = buildOPV(CSS_PROP_LIST_STYLE_IMAGE, + FLAG_INHERIT, 0); + *(bytecode++) = buildOPV(CSS_PROP_LIST_STYLE_POSITION, + FLAG_INHERIT, 0); + *(bytecode++) = buildOPV(CSS_PROP_LIST_STYLE_TYPE, + 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 parse the various longhand properties */ + do { + prev_ctx = *ctx; + error = CSS_OK; + + if (image == NULL && (error = parse_list_style_image(c, vector, + ctx, &image)) == CSS_OK) { + } else if (position == NULL && + (error = parse_list_style_position(c, vector, + ctx, &position)) == CSS_OK) { + } else if (type == NULL && + (error = parse_list_style_type(c, vector, ctx, + &type)) == CSS_OK) { + } + + if (error == CSS_OK) { + consumeWhitespace(vector, ctx); + + token = parserutils_vector_peek(vector, *ctx); + } else { + /* Forcibly cause loop to exit */ + token = NULL; + } + } while (*ctx != prev_ctx && token != NULL); + + /* Calculate the required size of the resultant style, + * defaulting the unspecified properties to their initial values */ + required_size = 0; + + if (image) + required_size += image->length; + else + required_size += sizeof(uint32_t); + + if (position) + required_size += position->length; + else + required_size += sizeof(uint32_t); + + if (type) + required_size += type->length; + else + required_size += sizeof(uint32_t); + + /* Create and populate it */ + error = css_stylesheet_style_create(c->sheet, required_size, &ret); + if (error != CSS_OK) + goto cleanup; + + required_size = 0; + + if (image) { + memcpy(((uint8_t *) ret->bytecode) + required_size, + image->bytecode, image->length); + required_size += image->length; + } else { + void *bc = ((uint8_t *) ret->bytecode) + required_size; + + *((uint32_t *) bc) = buildOPV(CSS_PROP_LIST_STYLE_IMAGE, + 0, LIST_STYLE_IMAGE_NONE); + required_size += sizeof(uint32_t); + } + + if (position) { + memcpy(((uint8_t *) ret->bytecode) + required_size, + position->bytecode, position->length); + required_size += position->length; + } else { + void *bc = ((uint8_t *) ret->bytecode) + required_size; + + *((uint32_t *) bc) = buildOPV(CSS_PROP_LIST_STYLE_POSITION, + 0, LIST_STYLE_POSITION_OUTSIDE); + required_size += sizeof(uint32_t); + } + + if (type) { + memcpy(((uint8_t *) ret->bytecode) + required_size, + type->bytecode, type->length); + required_size += type->length; + } else { + void *bc = ((uint8_t *) ret->bytecode) + required_size; + + *((uint32_t *) bc) = buildOPV(CSS_PROP_LIST_STYLE_TYPE, + 0, LIST_STYLE_TYPE_DISC); + required_size += sizeof(uint32_t); + } + + 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 (image) + css_stylesheet_style_destroy(c->sheet, image); + if (position) + css_stylesheet_style_destroy(c->sheet, position); + if (type) + css_stylesheet_style_destroy(c->sheet, type); + if (ret) + css_stylesheet_style_destroy(c->sheet, ret); + + if (error != CSS_OK) + *ctx = orig_ctx; + + return error; +} + /** * Parse list-style-image * diff --git a/src/parse/properties/properties.c b/src/parse/properties/properties.c index 6e7177b..0fd5747 100644 --- a/src/parse/properties/properties.c +++ b/src/parse/properties/properties.c @@ -68,6 +68,7 @@ const css_prop_handler property_handlers[LAST_PROP + 1 - FIRST_PROP] = parse_left, parse_letter_spacing, parse_line_height, + parse_list_style, parse_list_style_image, parse_list_style_position, parse_list_style_type, diff --git a/src/parse/properties/properties.h b/src/parse/properties/properties.h index 9854aed..976766d 100644 --- a/src/parse/properties/properties.h +++ b/src/parse/properties/properties.h @@ -190,6 +190,9 @@ css_error parse_letter_spacing(css_language *c, css_error parse_line_height(css_language *c, const parserutils_vector *vector, int *ctx, css_style **result); +css_error parse_list_style(css_language *c, + const parserutils_vector *vector, int *ctx, + css_style **result); css_error parse_list_style_image(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 e1ef19e..9e26271 100644 --- a/src/parse/propstrings.c +++ b/src/parse/propstrings.c @@ -98,6 +98,7 @@ const stringmap_entry stringmap[LAST_KNOWN] = { { "left", SLEN("left") }, { "letter-spacing", SLEN("letter-spacing") }, { "line-height", SLEN("line-height") }, + { "list-style", SLEN("list-style") }, { "list-style-image", SLEN("list-style-image") }, { "list-style-position", SLEN("list-style-position") }, { "list-style-type", SLEN("list-style-type") }, diff --git a/src/parse/propstrings.h b/src/parse/propstrings.h index fd446ee..68b4b53 100644 --- a/src/parse/propstrings.h +++ b/src/parse/propstrings.h @@ -43,14 +43,14 @@ enum { CLIP, COLOR, CONTENT, COUNTER_INCREMENT, COUNTER_RESET, CUE, CUE_AFTER, CUE_BEFORE, CURSOR, DIRECTION, DISPLAY, ELEVATION, EMPTY_CELLS, FLOAT, FONT, FONT_FAMILY, FONT_SIZE, FONT_STYLE, FONT_VARIANT, FONT_WEIGHT, - HEIGHT, LEFT, LETTER_SPACING, LINE_HEIGHT, LIST_STYLE_IMAGE, - LIST_STYLE_POSITION, LIST_STYLE_TYPE, MARGIN_BOTTOM, MARGIN_LEFT, - 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, - PAUSE_AFTER, PAUSE_BEFORE, PITCH_RANGE, PITCH, PLAY_DURING, POSITION, - QUOTES, RICHNESS, RIGHT, SPEAK_HEADER, SPEAK_NUMERAL, + HEIGHT, LEFT, LETTER_SPACING, LINE_HEIGHT, LIST_STYLE, + LIST_STYLE_IMAGE, LIST_STYLE_POSITION, LIST_STYLE_TYPE, MARGIN_BOTTOM, + MARGIN_LEFT, 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, 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, -- cgit v1.2.3