struct scanner_token * skip_scanner_tokens(struct scanner *scanner, int skipto, int precedence) { struct scanner_token *token = get_scanner_token(scanner); /* Skip tokens while handling some basic precedens of special chars * so we don't skip to long. */ while (token) { if (token->type == skipto || token->precedence > precedence) break; token = get_next_scanner_token(scanner); } return (token && token->type == skipto) ? get_next_scanner_token(scanner) : NULL; }
int css_parse_color_value(struct css_property_info *propinfo, union css_property_value *value, struct scanner *scanner) { struct scanner_token *token = get_scanner_token(scanner); assert(propinfo->value_type == CSS_VT_COLOR); if (token->type == CSS_TOKEN_RGB) { /* RGB function */ int shift; token = get_next_scanner_token(scanner); /* First color component is shifted 16, next is shifted 8 and * last is not shifted. */ for (shift = 16; token && shift >= 0; shift -= 8) { /* The first two args are terminated by ',' and the * last one by ')'. */ unsigned char paskynator = shift ? ',' : ')'; const unsigned char *nstring = token->string; int part; /* Are the current and next token valid? */ if ((token->type != CSS_TOKEN_NUMBER && token->type != CSS_TOKEN_PERCENTAGE) || !check_next_scanner_token(scanner, paskynator)) return 0; /* Parse the digit */ part = strtol(token->string, (char **) &nstring, 10); if (token->string == nstring) return 0; /* Adjust percentage values */ if (token->type == CSS_TOKEN_PERCENTAGE) { int_bounds(&part, 0, 100); part *= 255; part /= 100; } /* Adjust color component value and add it */ int_bounds(&part, 0, 255); value->color |= part << shift; /* Paskynate the token arg and separator */ token = skip_css_tokens(scanner, paskynator); } return 1; } /* Just a color value we already know how to parse. */ if (token->type != CSS_TOKEN_IDENT && token->type != CSS_TOKEN_HEX_COLOR) return 0; if (decode_color(token->string, token->length, &value->color) < 0) { return 0; } skip_css_tokens(scanner, token->type); return 1; }