From 6a50bef84ae6a0a67e03ac1356f8d85d15fe09d6 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 19 Jan 2011 23:12:37 +0000 Subject: Merge parser autogeneration and string handling refactor branch r=jmb,kinnison,vince svn path=/trunk/libcss/; revision=11408 --- src/parse/properties/border_style.c | 293 +++++++++++------------------------- 1 file changed, 90 insertions(+), 203 deletions(-) (limited to 'src/parse/properties/border_style.c') diff --git a/src/parse/properties/border_style.c b/src/parse/properties/border_style.c index ed3a7ac..7ee6922 100644 --- a/src/parse/properties/border_style.c +++ b/src/parse/properties/border_style.c @@ -29,236 +29,123 @@ */ css_error parse_border_style(css_language *c, const parserutils_vector *vector, int *ctx, - css_style **result) + css_style *result) { int orig_ctx = *ctx; int prev_ctx; const css_token *token; - css_style *top = NULL; - css_style *right = NULL; - css_style *bottom = NULL; - css_style *left = NULL; - css_style *ret = NULL; - uint32_t num_sides = 0; - uint32_t required_size; + uint16_t side_val[4]; + uint32_t side_count = 0; bool match; css_error error; /* Firstly, handle inherit */ token = parserutils_vector_peek(vector, *ctx); - if (token != NULL && token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[INHERIT], - &match) == lwc_error_ok && match)) { - uint32_t *bytecode; - - error = css_stylesheet_style_create(c->sheet, - 4 * sizeof(uint32_t), &ret); - if (error != CSS_OK) { - *ctx = orig_ctx; + if (token == NULL) + return CSS_INVALID; + + if (is_css_inherit(c, token)) { + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_TOP_STYLE); + if (error != CSS_OK) return error; - } - - bytecode = (uint32_t *) ret->bytecode; - *(bytecode++) = buildOPV(CSS_PROP_BORDER_TOP_STYLE, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_BORDER_RIGHT_STYLE, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_BORDER_BOTTOM_STYLE, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, - FLAG_INHERIT, 0); + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_RIGHT_STYLE); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_BOTTOM_STYLE); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_BORDER_LEFT_STYLE); + if (error == CSS_OK) + parserutils_vector_iterate(vector, ctx); - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + return error; + } /* Attempt to parse up to 4 styles */ do { prev_ctx = *ctx; - error = CSS_OK; - - /* Ensure that we're not about to parse another inherit */ - token = parserutils_vector_peek(vector, *ctx); - if (token != NULL && token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[INHERIT], - &match) == lwc_error_ok && match)) { - error = CSS_INVALID; - goto cleanup; - } - if (top == NULL && - (error = parse_border_side_style(c, vector, - ctx, CSS_PROP_BORDER_TOP_STYLE, &top)) == - CSS_OK) { - num_sides = 1; - } else if (right == NULL && - (error = parse_border_side_style(c, vector, - ctx, CSS_PROP_BORDER_RIGHT_STYLE, &right)) == - CSS_OK) { - num_sides = 2; - } else if (bottom == NULL && - (error = parse_border_side_style(c, vector, - ctx, CSS_PROP_BORDER_BOTTOM_STYLE, &bottom)) == - CSS_OK) { - num_sides = 3; - } else if (left == NULL && - (error = parse_border_side_style(c, vector, - ctx, CSS_PROP_BORDER_LEFT_STYLE, &left)) == - CSS_OK) { - num_sides = 4; + if ((token != NULL) && is_css_inherit(c, token)) { + *ctx = orig_ctx; + return CSS_INVALID; } - if (error == CSS_OK) { - consumeWhitespace(vector, ctx); - - token = parserutils_vector_peek(vector, *ctx); + if (token->type != CSS_TOKEN_IDENT) + break; + + if ((lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_NONE; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[HIDDEN], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_HIDDEN; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[DOTTED], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_DOTTED; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[DASHED], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_DASHED; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[SOLID], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_SOLID; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[LIBCSS_DOUBLE], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_DOUBLE; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[GROOVE], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_GROOVE; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[RIDGE], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_RIDGE; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[INSET], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_INSET; + } else if ((lwc_string_caseless_isequal(token->idata, c->strings[OUTSET], &match) == lwc_error_ok && match)) { + side_val[side_count] = BORDER_STYLE_OUTSET; } else { - /* Forcibly cause loop to exit */ - token = NULL; + break; } - } while (*ctx != prev_ctx && token != NULL); - - if (num_sides == 0) { - error = CSS_INVALID; - goto cleanup; - } - - /* Calculate size of resultant style */ - if (num_sides == 1) { - required_size = 4 * top->length; - } else if (num_sides == 2) { - required_size = 2 * top->length + 2 * right->length; - } else if (num_sides == 3) { - required_size = top->length + 2 * right->length + - bottom->length; - } else { - required_size = top->length + right->length + - bottom->length + left->length; - } - - error = css_stylesheet_style_create(c->sheet, required_size, &ret); - if (error != CSS_OK) - goto cleanup; - required_size = 0; - - if (num_sides == 1) { - uint32_t *opv = ((uint32_t *) top->bytecode); - uint8_t flags = getFlags(*opv); - uint16_t value = getValue(*opv); - - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *opv = buildOPV(CSS_PROP_BORDER_RIGHT_STYLE, flags, value); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *opv = buildOPV(CSS_PROP_BORDER_BOTTOM_STYLE, flags, value); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *opv = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, flags, value); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - } else if (num_sides == 2) { - uint32_t *vopv = ((uint32_t *) top->bytecode); - uint32_t *hopv = ((uint32_t *) right->bytecode); - uint8_t vflags = getFlags(*vopv); - uint8_t hflags = getFlags(*hopv); - uint16_t vvalue = getValue(*vopv); - uint16_t hvalue = getValue(*hopv); - - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - memcpy(((uint8_t *) ret->bytecode) + required_size, - right->bytecode, right->length); - required_size += right->length; - - *vopv = buildOPV(CSS_PROP_BORDER_BOTTOM_STYLE, vflags, vvalue); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *hopv = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, hflags, hvalue); - memcpy(((uint8_t *) ret->bytecode) + required_size, - right->bytecode, right->length); - required_size += right->length; - } else if (num_sides == 3) { - uint32_t *opv = ((uint32_t *) right->bytecode); - uint8_t flags = getFlags(*opv); - uint16_t value = getValue(*opv); - - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - memcpy(((uint8_t *) ret->bytecode) + required_size, - right->bytecode, right->length); - required_size += right->length; - - memcpy(((uint8_t *) ret->bytecode) + required_size, - bottom->bytecode, bottom->length); - required_size += bottom->length; - - *opv = buildOPV(CSS_PROP_BORDER_LEFT_STYLE, flags, value); - memcpy(((uint8_t *) ret->bytecode) + required_size, - right->bytecode, right->length); - required_size += right->length; - } else { - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - memcpy(((uint8_t *) ret->bytecode) + required_size, - right->bytecode, right->length); - required_size += right->length; - - memcpy(((uint8_t *) ret->bytecode) + required_size, - bottom->bytecode, bottom->length); - required_size += bottom->length; + side_count++; + + parserutils_vector_iterate(vector, ctx); + + consumeWhitespace(vector, ctx); - memcpy(((uint8_t *) ret->bytecode) + required_size, - left->bytecode, left->length); - required_size += left->length; + token = parserutils_vector_peek(vector, *ctx); + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + + +#define SIDE_APPEND(OP,NUM) \ + error = css_stylesheet_style_appendOPV(result, (OP), 0, side_val[(NUM)]); \ + if (error != CSS_OK) \ + break + + switch (side_count) { + case 1: + SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 0); + break; + case 2: + SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1); + SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 1); + break; + case 3: + SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1); + SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 2); + SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 1); + break; + case 4: + SIDE_APPEND(CSS_PROP_BORDER_TOP_STYLE, 0); + SIDE_APPEND(CSS_PROP_BORDER_RIGHT_STYLE, 1); + SIDE_APPEND(CSS_PROP_BORDER_BOTTOM_STYLE, 2); + SIDE_APPEND(CSS_PROP_BORDER_LEFT_STYLE, 3); + break; + + default: + error = CSS_INVALID; + break; } - 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 (top) - css_stylesheet_style_destroy(c->sheet, top, error == CSS_OK); - if (right) - css_stylesheet_style_destroy(c->sheet, right, error == CSS_OK); - if (bottom) - css_stylesheet_style_destroy(c->sheet, bottom, error == CSS_OK); - if (left) - css_stylesheet_style_destroy(c->sheet, left, error == CSS_OK); - if (ret) - css_stylesheet_style_destroy(c->sheet, ret, error == CSS_OK); - if (error != CSS_OK) *ctx = orig_ctx; -- cgit v1.2.3