/* * This file is part of LibCSS. * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * Copyright 2009 John-Mark Bell */ #include #include #include "bytecode/bytecode.h" #include "bytecode/opcodes.h" #include "parse/properties/properties.h" #include "parse/properties/utils.h" /** * Parse quotes * * \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 css__parse_quotes(css_language *c, const parserutils_vector *vector, int *ctx, css_style *result) { int orig_ctx = *ctx; css_error error = CSS_INVALID; const css_token *token; bool match; /* [ STRING STRING ]+ | IDENT(none,inherit) */ token = parserutils_vector_iterate(vector, ctx); if ((token == NULL) || ((token->type != CSS_TOKEN_IDENT) && (token->type != CSS_TOKEN_STRING))) { *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)) { error = css_stylesheet_style_inherit(result, CSS_PROP_QUOTES); } else if ((token->type == CSS_TOKEN_IDENT) && (lwc_string_caseless_isequal(token->idata, c->strings[NONE], &match) == lwc_error_ok && match)) { error = css__stylesheet_style_appendOPV(result, CSS_PROP_QUOTES, 0, QUOTES_NONE); } else if (token->type == CSS_TOKEN_STRING) { bool first = true; /* Macro to output the value marker, awkward because we need to check * first to determine how the value is constructed. */ #define CSS_FIRST_APPEND(CSSVAL) css__stylesheet_style_append(result, first?buildOPV(CSS_PROP_QUOTES, 0, CSSVAL):CSSVAL) /* [ STRING STRING ]+ */ while ((token != NULL) && (token->type == CSS_TOKEN_STRING)) { uint32_t open_snumber; uint32_t close_snumber; error = css__stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &open_snumber); if (error != CSS_OK) break; consumeWhitespace(vector, ctx); token = parserutils_vector_iterate(vector, ctx); if ((token == NULL) || (token->type != CSS_TOKEN_STRING)) { error = CSS_INVALID; break; } error = css__stylesheet_string_add(c->sheet, lwc_string_ref(token->idata), &close_snumber); if (error != CSS_OK) break; consumeWhitespace(vector, ctx); error = CSS_FIRST_APPEND(QUOTES_STRING); if (error != CSS_OK) break; error = css__stylesheet_style_append(result, open_snumber); if (error != CSS_OK) break; error = css__stylesheet_style_append(result, close_snumber); if (error != CSS_OK) break; first = false; token = parserutils_vector_peek(vector, *ctx); if (token == NULL || token->type != CSS_TOKEN_STRING) break; token = parserutils_vector_iterate(vector, ctx); } if (error == CSS_OK) { /* AddTerminator */ error = css__stylesheet_style_append(result, QUOTES_NONE); } } else { error = CSS_INVALID; } if (error != CSS_OK) *ctx = orig_ctx; return error; }