diff options
-rw-r--r-- | src/parse/properties/utils.c | 89 | ||||
-rw-r--r-- | test/dump.h | 29 |
2 files changed, 84 insertions, 34 deletions
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c index fe5ee6b..fa8ffbe 100644 --- a/src/parse/properties/utils.c +++ b/src/parse/properties/utils.c @@ -1362,16 +1362,17 @@ cleanup: static css_error css__parse_calc_sum(css_language *c, const parserutils_vector *vector, int *ctx, - css_style *result); + parserutils_buffer *result); static css_error css__parse_calc_number( const parserutils_vector *vector, int *ctx, - css_style *result) + parserutils_buffer *result) { const css_token *token; css_fixed num; size_t consumed; + css_code_t push = CALC_PUSH_NUMBER; /* Consume the number token */ token = parserutils_vector_iterate(vector, ctx); @@ -1386,13 +1387,18 @@ css__parse_calc_number( return CSS_INVALID; } - return css__stylesheet_style_vappend(result, 2, (css_code_t) CALC_PUSH_NUMBER, (css_code_t)num); + return css_error_from_parserutils_error( + parserutils_buffer_appendv(result, 2, + &push, sizeof(push), + &num, sizeof(num) + ) + ); } static css_error css__parse_calc_value(css_language *c, const parserutils_vector *vector, int *ctx, - css_style *result) + parserutils_buffer *result) { css_error error; int orig_ctx = *ctx; @@ -1426,6 +1432,7 @@ css__parse_calc_value(css_language *c, { css_fixed length = 0; uint32_t unit = 0; + css_code_t push = CALC_PUSH_VALUE; *ctx = orig_ctx; error = css__parse_unit_specifier(c, vector, ctx, UNIT_CALC_NUMBER, &length, &unit); @@ -1434,7 +1441,14 @@ css__parse_calc_value(css_language *c, return error; } - error = css__stylesheet_style_vappend(result, 3, (css_code_t) CALC_PUSH_VALUE, length, unit); + error = css_error_from_parserutils_error( + parserutils_buffer_appendv(result, 3, + &push, sizeof(push), + &length, sizeof(length), + &unit, sizeof(unit) + ) + ); + } break; @@ -1455,12 +1469,11 @@ css__parse_calc_value(css_language *c, static css_error css__parse_calc_product(css_language *c, const parserutils_vector *vector, int *ctx, - css_style *result) + parserutils_buffer *result) { css_error error = CSS_OK; const css_token *token; - bool multiplication; - + css_code_t operator; /* First parse a value */ error = css__parse_calc_value(c, vector, ctx, result); @@ -1480,9 +1493,9 @@ css__parse_calc_product(css_language *c, tokenIsChar(token, '-')) break; else if (tokenIsChar(token, '*')) - multiplication = true; + operator = CALC_MULTIPLY; else if (tokenIsChar(token, '/')) - multiplication = false; + operator = CALC_DIVIDE; else { error = CSS_INVALID; break; @@ -1492,7 +1505,7 @@ css__parse_calc_product(css_language *c, consumeWhitespace(vector, ctx); - if (multiplication) { + if (operator == CALC_MULTIPLY) { /* parse another value */ error = css__parse_calc_value(c, vector, ctx, result); } else { @@ -1502,8 +1515,9 @@ css__parse_calc_product(css_language *c, break; /* emit the multiplication/division operator */ - error = css__stylesheet_style_append(result, - (css_code_t) (multiplication ? CALC_MULTIPLY : CALC_DIVIDE)); + error = css_error_from_parserutils_error( + parserutils_buffer_append(result, (const uint8_t *)&operator, sizeof(operator)) + ); } while (1); /* We've fallen off, either we had an error or we're left with ')' */ return error; @@ -1513,12 +1527,11 @@ css__parse_calc_product(css_language *c, css_error css__parse_calc_sum(css_language *c, const parserutils_vector *vector, int *ctx, - css_style *result) + parserutils_buffer *result) { css_error error = CSS_OK; const css_token *token; - bool addition; - + css_code_t operator; /* First parse a product */ error = css__parse_calc_product(c, vector, ctx, result); @@ -1535,9 +1548,9 @@ css__parse_calc_sum(css_language *c, } else if (tokenIsChar(token, ')')) break; else if (tokenIsChar(token, '+')) - addition = true; + operator = CALC_ADD; else if (tokenIsChar(token, '-')) - addition = false; + operator = CALC_SUBTRACT; else { error = CSS_INVALID; break; @@ -1552,7 +1565,9 @@ css__parse_calc_sum(css_language *c, break; /* emit the addition/subtraction operator */ - error = css__stylesheet_style_append(result, (css_code_t) (addition ? CALC_ADD : CALC_SUBTRACT)); + error = css_error_from_parserutils_error( + parserutils_buffer_append(result, (const uint8_t *)&operator, sizeof(operator)) + ); } while (1); /* We've fallen off, either we had an error or we're left with ')' */ return error; @@ -1569,6 +1584,10 @@ css_error css__parse_calc(css_language *c, const css_token *token; css_error error = CSS_OK; css_style *calc_style = NULL; + parserutils_buffer *calc_buffer = NULL; + lwc_string *calc_expr = NULL; + uint32_t expr_index = 0; + css_code_t finish = CALC_FINISH; consumeWhitespace(vector, ctx); @@ -1578,6 +1597,12 @@ css_error css__parse_calc(css_language *c, return CSS_INVALID; } + if (parserutils_buffer_create(&calc_buffer) != PARSERUTILS_OK) { + /* Since &calc_buffer is valid, the only error case is NONMEM */ + *ctx = orig_ctx; + return CSS_NOMEM; + } + error = css__stylesheet_style_create(c->sheet, &calc_style); if (error != CSS_OK) goto cleanup; @@ -1585,12 +1610,12 @@ css_error css__parse_calc(css_language *c, error = css__stylesheet_style_append(calc_style, property); if (error != CSS_OK) goto cleanup; - + error = css__stylesheet_style_append(calc_style, (css_code_t) unit); if (error != CSS_OK) goto cleanup; - error = css__parse_calc_sum(c, vector, ctx, calc_style); + error = css__parse_calc_sum(c, vector, ctx, calc_buffer); if (error != CSS_OK) goto cleanup; @@ -1602,17 +1627,35 @@ css_error css__parse_calc(css_language *c, goto cleanup; } + /* Append the indicator that the calc is finished */ + error = css_error_from_parserutils_error( + parserutils_buffer_append(calc_buffer, (const uint8_t *)&finish, sizeof(finish)) + ); + if (error != CSS_OK) + goto cleanup; + /* Swallow that close paren */ parserutils_vector_iterate(vector, ctx); - /* Append the indicator that the calc is finished */ - error = css__stylesheet_style_append(calc_style, (css_code_t) CALC_FINISH); + /* Create the lwc string representing the calculation and store it in */ + error = css_error_from_lwc_error( + lwc_intern_string((const char *)calc_buffer->data, calc_buffer->length, &calc_expr) + ); if (error != CSS_OK) goto cleanup; + /* This always takes ownership of calc_expr, so we should not use after this */ + error = css__stylesheet_string_add(calc_style->sheet, calc_expr, &expr_index); + if (error != CSS_OK) + goto cleanup; + + css__stylesheet_style_append(calc_style, (css_code_t) expr_index); + error = css__stylesheet_merge_style(result, calc_style); cleanup: css__stylesheet_style_destroy(calc_style); + parserutils_buffer_destroy(calc_buffer); + /* We do not need to clean up calc_expr, it will never leak */ if (error != CSS_OK) { *ctx = orig_ctx; } diff --git a/test/dump.h b/test/dump.h index a1fdd1f..eac0a9f 100644 --- a/test/dump.h +++ b/test/dump.h @@ -803,15 +803,23 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t depth) } else if (getFlagValue(opv) == FLAG_VALUE_UNSET) { *ptr += sprintf(*ptr, "unset"); } else if (isCalc(opv)) { + lwc_string *calc_expr = NULL; + const uint8_t *codeptr = NULL; + css_code_t calc_opcode; + uint32_t unit, snum; /* First entry is a unit */ - uint32_t unit = *((uint32_t *)bytecode); + unit = *((uint32_t *)bytecode); ADVANCE(sizeof(unit)); + /* Second entry is an lwc_string of the expression */ + snum = *((uint32_t *)bytecode); + ADVANCE(sizeof(snum)); + css__stylesheet_string_get(style->sheet, snum, &calc_expr); + codeptr = (const uint8_t *)lwc_string_data(calc_expr); *ptr += sprintf(*ptr, "/* -> "); dump_unit(0, unit, ptr); *ptr += sprintf(*ptr, " */ calc("); - css_code_t calc_opcode; - while ((calc_opcode = *((css_code_t *)bytecode)) != CALC_FINISH) { - ADVANCE(sizeof(calc_opcode)); + while ((calc_opcode = *((css_code_t *)codeptr)) != CALC_FINISH) { + codeptr += sizeof(calc_opcode); switch (calc_opcode) { case CALC_ADD: *ptr += sprintf(*ptr, "+ "); @@ -826,17 +834,17 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t depth) *ptr += sprintf(*ptr, "/ "); break; case CALC_PUSH_VALUE: { - css_fixed num = *((css_fixed *)bytecode); - ADVANCE(sizeof(num)); - uint32_t unit = *((uint32_t *)bytecode); - ADVANCE(sizeof(unit)); + css_fixed num = *((css_fixed *)codeptr); + codeptr += sizeof(num); + uint32_t unit = *((uint32_t *)codeptr); + codeptr += sizeof(unit); dump_unit(num, unit, ptr); *ptr += sprintf(*ptr, " "); break; } case CALC_PUSH_NUMBER: { - css_fixed num = *((css_fixed *)bytecode); - ADVANCE(sizeof(num)); + css_fixed num = *((css_fixed *)codeptr); + codeptr += sizeof(num); dump_number(num, ptr); *ptr += sprintf(*ptr, " "); break; @@ -846,7 +854,6 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t depth) break; } } - ADVANCE(sizeof(calc_opcode)); *ptr += sprintf(*ptr, "=)"); } else { value = getValue(opv); |