diff options
author | Vincent Sanders <vince@netsurf-browser.org> | 2011-01-19 23:12:37 +0000 |
---|---|---|
committer | Vincent Sanders <vince@netsurf-browser.org> | 2011-01-19 23:12:37 +0000 |
commit | 6a50bef84ae6a0a67e03ac1356f8d85d15fe09d6 (patch) | |
tree | 01f78f04b22517899f603787f6005f70b359271e /src/parse/properties/padding.c | |
parent | 63c21aca7c77b1d37cb64ad2b1fa76d6b0b92f48 (diff) | |
download | libcss-6a50bef84ae6a0a67e03ac1356f8d85d15fe09d6.tar.gz libcss-6a50bef84ae6a0a67e03ac1356f8d85d15fe09d6.tar.bz2 |
Merge parser autogeneration and string handling refactor branch r=jmb,kinnison,vince
svn path=/trunk/libcss/; revision=11408
Diffstat (limited to 'src/parse/properties/padding.c')
-rw-r--r-- | src/parse/properties/padding.c | 274 |
1 files changed, 79 insertions, 195 deletions
diff --git a/src/parse/properties/padding.c b/src/parse/properties/padding.c index 753b530..263906d 100644 --- a/src/parse/properties/padding.c +++ b/src/parse/properties/padding.c @@ -29,92 +29,66 @@ */ css_error parse_padding(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; - bool match; + css_fixed side_length[4]; + uint32_t side_unit[4]; + uint32_t side_count = 0; 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_PADDING_TOP); + if (error != CSS_OK) return error; - } - - bytecode = (uint32_t *) ret->bytecode; - *(bytecode++) = buildOPV(CSS_PROP_PADDING_TOP, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_PADDING_RIGHT, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_PADDING_BOTTOM, - FLAG_INHERIT, 0); - *(bytecode++) = buildOPV(CSS_PROP_PADDING_LEFT, - FLAG_INHERIT, 0); + error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_RIGHT); + if (error != CSS_OK) + return error; - parserutils_vector_iterate(vector, ctx); + error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_BOTTOM); + if (error != CSS_OK) + return error; - *result = ret; + error = css_stylesheet_style_inherit(result, CSS_PROP_PADDING_LEFT); + 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 widths */ 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_padding_side(c, vector, ctx, - CSS_PROP_PADDING_TOP, &top)) == CSS_OK) { - num_sides = 1; - } else if (right == NULL && - (error = parse_padding_side(c, vector, ctx, - CSS_PROP_PADDING_RIGHT, &right)) == CSS_OK) { - num_sides = 2; - } else if (bottom == NULL && - (error = parse_padding_side(c, vector, ctx, - CSS_PROP_PADDING_BOTTOM, &bottom)) == CSS_OK) { - num_sides = 3; - } else if (left == NULL && - (error = parse_padding_side(c, vector, ctx, - CSS_PROP_PADDING_LEFT, &left)) == CSS_OK) { - num_sides = 4; + if ((token != NULL) && is_css_inherit(c, token)) { + *ctx = orig_ctx; + return CSS_INVALID; } + error = parse_unit_specifier(c, vector, ctx, UNIT_PX, &side_length[side_count], &side_unit[side_count]); if (error == CSS_OK) { + if (side_unit[side_count] & UNIT_ANGLE || + side_unit[side_count] & UNIT_TIME || + side_unit[side_count] & UNIT_FREQ) { + *ctx = orig_ctx; + return CSS_INVALID; + } + + if (side_length[side_count] < 0) { + *ctx = orig_ctx; + return CSS_INVALID; + } + + side_count++; + consumeWhitespace(vector, ctx); token = parserutils_vector_peek(vector, *ctx); @@ -122,139 +96,49 @@ css_error parse_padding(css_language *c, /* Forcibly cause loop to exit */ token = NULL; } - } while (*ctx != prev_ctx && token != NULL); - - if (num_sides == 0) { + } while ((*ctx != prev_ctx) && (token != NULL) && (side_count < 4)); + +#define SIDE_APPEND(OP,NUM) \ + error = css_stylesheet_style_appendOPV(result, (OP), 0, PADDING_SET); \ + if (error != CSS_OK) \ + break; \ + error = css_stylesheet_style_append(result, side_length[(NUM)]); \ + if (error != CSS_OK) \ + break; \ + error = css_stylesheet_style_append(result, side_unit[(NUM)]); \ + if (error != CSS_OK) \ + break; + + switch (side_count) { + case 1: + SIDE_APPEND(CSS_PROP_PADDING_TOP, 0); + SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 0); + SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 0); + SIDE_APPEND(CSS_PROP_PADDING_LEFT, 0); + break; + case 2: + SIDE_APPEND(CSS_PROP_PADDING_TOP, 0); + SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 1); + SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 0); + SIDE_APPEND(CSS_PROP_PADDING_LEFT, 1); + break; + case 3: + SIDE_APPEND(CSS_PROP_PADDING_TOP, 0); + SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 1); + SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 2); + SIDE_APPEND(CSS_PROP_PADDING_LEFT, 1); + break; + case 4: + SIDE_APPEND(CSS_PROP_PADDING_TOP, 0); + SIDE_APPEND(CSS_PROP_PADDING_RIGHT, 1); + SIDE_APPEND(CSS_PROP_PADDING_BOTTOM, 2); + SIDE_APPEND(CSS_PROP_PADDING_LEFT, 3); + break; + default: 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; + break; } - 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_PADDING_RIGHT, flags, value); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *opv = buildOPV(CSS_PROP_PADDING_BOTTOM, flags, value); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *opv = buildOPV(CSS_PROP_PADDING_LEFT, 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_PADDING_BOTTOM, vflags, vvalue); - memcpy(((uint8_t *) ret->bytecode) + required_size, - top->bytecode, top->length); - required_size += top->length; - - *hopv = buildOPV(CSS_PROP_PADDING_LEFT, 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_PADDING_LEFT, 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; - - memcpy(((uint8_t *) ret->bytecode) + required_size, - left->bytecode, left->length); - required_size += left->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 (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; |