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/cue.c | 284 ++++++--------------------------------------- 1 file changed, 36 insertions(+), 248 deletions(-) (limited to 'src/parse/properties/cue.c') diff --git a/src/parse/properties/cue.c b/src/parse/properties/cue.c index 982405f..096c121 100644 --- a/src/parse/properties/cue.c +++ b/src/parse/properties/cue.c @@ -13,134 +13,6 @@ #include "parse/properties/properties.h" #include "parse/properties/utils.h" -/** - * Common parser for cue-after and cue-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. - */ -static css_error parse_cue_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; - uint32_t required_size; - lwc_string *uri = NULL; - bool match; - - /* URI | IDENT (none, inherit) */ - token = parserutils_vector_iterate(vector, ctx); - if (token == NULL || (token->type != CSS_TOKEN_IDENT && - token->type != CSS_TOKEN_URI)) { - *ctx = orig_ctx; - return CSS_INVALID; - } - - if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[INHERIT], - &match) == lwc_error_ok && match)) { - flags |= FLAG_INHERIT; - } else if (token->type == CSS_TOKEN_IDENT && - (lwc_string_caseless_isequal( - token->idata, c->strings[NONE], - &match) == lwc_error_ok && match)) { - value = CUE_AFTER_NONE; - } else if (token->type == CSS_TOKEN_URI) { - value = CUE_AFTER_URI; - - error = c->sheet->resolve(c->sheet->resolve_pw, - c->sheet->url, - token->idata, &uri); - if (error != CSS_OK) { - *ctx = orig_ctx; - return error; - } - } else { - *ctx = orig_ctx; - return CSS_INVALID; - } - - opv = buildOPV(op, flags, value); - - required_size = sizeof(opv); - if ((flags & FLAG_INHERIT) == false && value == CUE_AFTER_URI) - required_size += sizeof(lwc_string *); - - /* 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 == CUE_AFTER_URI) { - /* Don't ref URI -- we want to pass ownership to the bytecode */ - memcpy((uint8_t *) (*result)->bytecode + sizeof(opv), - &uri, sizeof(lwc_string *)); - } - - return CSS_OK; -} - -/** - * Parse cue-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_cue_after(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_cue_common(c, vector, ctx, CSS_PROP_CUE_AFTER, result); -} - -/** - * Parse cue-before - * - * \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_before(css_language *c, - const parserutils_vector *vector, int *ctx, - css_style **result) -{ - return parse_cue_common(c, vector, ctx, CSS_PROP_CUE_BEFORE, result); -} - /** * Parse cue shorthand * @@ -157,138 +29,54 @@ css_error parse_cue_before(css_language *c, */ css_error parse_cue(css_language *c, const parserutils_vector *vector, int *ctx, - css_style **result) + 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; - bool match; css_error error; + const css_token *first_token; + const css_token *token; - /* Deal with 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, - 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; + /* one or two tokens follow: + * if one emit for both BEFORE and AFTER + * if two first is before second is after + * tokens are either IDENT:none or URI + */ - return CSS_OK; - } else if (token == NULL) { - /* No tokens -- clearly garbage */ - *ctx = orig_ctx; - return CSS_INVALID; - } + first_token = parserutils_vector_peek(vector, *ctx); - /* Attempt to read 1 or 2 cues */ - do { - prev_ctx = *ctx; - error = CSS_OK; + error = parse_cue_before(c, vector, ctx, result); + if (error == CSS_OK) { + /* first token parsed */ + + consumeWhitespace(vector, ctx); - /* 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 (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); + if (token == NULL) { + /* no second token, re-parse the first */ + *ctx = orig_ctx; + error = parse_cue_after(c, vector, ctx, result); } else { - token = NULL; + /* second token - might be useful */ + if (is_css_inherit(c, token)) { + /* another inherit which is bogus */ + error = CSS_INVALID; + } else { + error = parse_cue_after(c, vector, ctx, result); + if (error == CSS_OK) { + /* second token parsed */ + if (is_css_inherit(c, first_token)) { + /* valid second token after inherit */ + error = CSS_INVALID; + } + } else { + /* second token appears to be junk re-try with first */ + *ctx = orig_ctx; + error = parse_cue_after(c, vector, ctx, result); + } + } } - } 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, error == CSS_OK); - if (after) - css_stylesheet_style_destroy(c->sheet, after, 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