Gitweb links:

...log 
http://git.netsurf-browser.org/libcss.git/shortlog/384495b311e287affacd59238b2159fdd8cfff6b
...commit 
http://git.netsurf-browser.org/libcss.git/commit/384495b311e287affacd59238b2159fdd8cfff6b
...tree 
http://git.netsurf-browser.org/libcss.git/tree/384495b311e287affacd59238b2159fdd8cfff6b

The branch, tlsa/calc has been updated
       via  384495b311e287affacd59238b2159fdd8cfff6b (commit)
       via  709b6c7b5db034edb9b7d2f3b989916180dbf1e1 (commit)
      from  e3583052459e8cb7ecabaa25784ce85c5ab7421d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/libcss.git/commit/?id=384495b311e287affacd59238b2159fdd8cfff6b
commit 384495b311e287affacd59238b2159fdd8cfff6b
Author: Daniel Silverstone <[email protected]>
Commit: Michael Drake <Michael Drake [email protected]>

    parse: Tests and fixes for calc() parser.
    
    Co-authored-by: Michael Drake <[email protected]>

diff --git a/src/bytecode/bytecode.h b/src/bytecode/bytecode.h
index 93f01d1..2dff97c 100644
--- a/src/bytecode/bytecode.h
+++ b/src/bytecode/bytecode.h
@@ -24,12 +24,13 @@ enum flag {
 };
 
 enum calc_opcodes {
-       CALC_PUSH_VALUE = 'V',
-       CALC_ADD        = '+',
-       CALC_SUBTRACT   = '-',
-       CALC_MULTIPLY   = '*',
-       CALC_DIVIDE     = '/',
-       CALC_FINISH     = '=',
+       CALC_PUSH_NUMBER = 'N',
+       CALC_PUSH_VALUE  = 'V',
+       CALC_ADD         = '+',
+       CALC_SUBTRACT    = '-',
+       CALC_MULTIPLY    = '*',
+       CALC_DIVIDE      = '/',
+       CALC_FINISH      = '=',
 };
 
 typedef enum unit {
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c
index a0fc786..ddb488f 100644
--- a/src/parse/properties/utils.c
+++ b/src/parse/properties/utils.c
@@ -1365,6 +1365,31 @@ css__parse_calc_sum(css_language *c,
                css_style *result);
 
 static css_error
+css__parse_calc_number(
+               const parserutils_vector *vector, int *ctx,
+               css_style *result)
+{
+       const css_token *token;
+       css_fixed num;
+       size_t consumed;
+
+       /* Consume the number token */
+       token = parserutils_vector_iterate(vector, ctx);
+       if (token == NULL || token->type != CSS_TOKEN_NUMBER) {
+               return CSS_INVALID;
+       }
+
+       num = css__number_from_string((const uint8_t 
*)lwc_string_data(token->idata),
+                               lwc_string_length(token->idata), false, 
&consumed);
+
+       if (consumed != lwc_string_length(token->idata)) {
+               return CSS_INVALID;
+       }
+
+       return css__stylesheet_style_vappend(result, 2, (css_code_t) 
CALC_PUSH_NUMBER, (css_code_t)num);
+}
+
+static css_error
 css__parse_calc_value(css_language *c,
                const parserutils_vector *vector, int *ctx,
                css_style *result)
@@ -1377,6 +1402,7 @@ css__parse_calc_value(css_language *c,
        token = parserutils_vector_peek(vector, *ctx);
        if (tokenIsChar(token, '(')) {
                parserutils_vector_iterate(vector, ctx);
+               consumeWhitespace(vector, ctx);
                error = css__parse_calc_sum(c, vector, ctx, result);
                if (error != CSS_OK) {
                        return error;
@@ -1389,7 +1415,12 @@ css__parse_calc_value(css_language *c,
                /* Consume the close-paren to complete this value */
                parserutils_vector_iterate(vector, ctx);
        } else switch (token->type) {
-       case CSS_TOKEN_NUMBER:    /* Fall through */
+       case CSS_TOKEN_NUMBER:
+               error = css__parse_calc_number(vector, ctx, result);
+               if (error != CSS_OK) {
+                       return error;
+               }
+               break;
        case CSS_TOKEN_DIMENSION: /* Fall through */
        case CSS_TOKEN_PERCENTAGE:
        {
@@ -1412,11 +1443,7 @@ css__parse_calc_value(css_language *c,
                break;
        }
 
-       token = parserutils_vector_peek(vector, *ctx);
-       while (token->type == CSS_TOKEN_S) {
-               parserutils_vector_iterate(vector, ctx);
-               token = parserutils_vector_peek(vector, *ctx);
-       }
+       consumeWhitespace(vector, ctx);
        return error;
 }
 
@@ -1462,14 +1489,15 @@ css__parse_calc_product(css_language *c,
                }
                /* Consume that * or / now */
                parserutils_vector_iterate(vector, ctx);
-               token = parserutils_vector_peek(vector, *ctx);
 
-               while (token->type == CSS_TOKEN_S) {
-                       parserutils_vector_iterate(vector, ctx);
-                       token = parserutils_vector_peek(vector, *ctx);
+               consumeWhitespace(vector, ctx);
+
+               if (multiplication) {
+                       /* parse another value */
+                       error = css__parse_calc_value(c, vector, ctx, result);
+               } else {
+                       error = css__parse_calc_number(vector, ctx, result);
                }
-               /* parse another value */
-               error = css__parse_calc_value(c, vector, ctx, result);
                if (error != CSS_OK)
                        break;
 
@@ -1516,12 +1544,7 @@ css__parse_calc_sum(css_language *c,
                }
                /* Consume that + or - now */
                parserutils_vector_iterate(vector, ctx);
-               token = parserutils_vector_peek(vector, *ctx);
-
-               while (token->type == CSS_TOKEN_S) {
-                       parserutils_vector_iterate(vector, ctx);
-                       token = parserutils_vector_peek(vector, *ctx);
-               }
+               consumeWhitespace(vector, ctx);
 
                /* parse another product */
                error = css__parse_calc_product(c, vector, ctx, result);
@@ -1547,17 +1570,14 @@ css_error css__parse_calc(css_language *c,
        css_error error = CSS_OK;
        css_style *calc_style = NULL;
 
+       consumeWhitespace(vector, ctx);
+
        token = parserutils_vector_peek(vector, *ctx);
        if (token == NULL) {
                *ctx = orig_ctx;
                return CSS_INVALID;
        }
 
-       while (token->type == CSS_TOKEN_S) {
-               parserutils_vector_iterate(vector, ctx);
-               token = parserutils_vector_peek(vector, *ctx);
-       }
-
        error = css__stylesheet_style_create(c->sheet, &calc_style);
        if (error != CSS_OK)
                goto cleanup;
@@ -1574,11 +1594,8 @@ css_error css__parse_calc(css_language *c,
        if (error != CSS_OK)
                goto cleanup;
 
+       consumeWhitespace(vector, ctx);
        token = parserutils_vector_peek(vector, *ctx);
-       while (token->type == CSS_TOKEN_S) {
-               parserutils_vector_iterate(vector, ctx);
-               token = parserutils_vector_peek(vector, *ctx);
-       }
        if (!tokenIsChar(token, ')')) {
                /* If we don't get a close-paren, give up now */
                error = CSS_INVALID;
diff --git a/test/data/parse2/calc.dat b/test/data/parse2/calc.dat
index 95abf6c..e9d176d 100644
--- a/test/data/parse2/calc.dat
+++ b/test/data/parse2/calc.dat
@@ -4,4 +4,154 @@
 #expected
 | *
 |  height: /* -> 0px */ calc(50vh 10px + =)
-#reset
\ No newline at end of file
+#reset
+
+#data
+* { line-height: calc(50vh + 10px)}
+#errors
+#expected
+| *
+|  line-height: /* -> 0any */ calc(50vh 10px + =)
+#reset
+
+#data
+* { line-height: calc( / 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { line-height: calc( + 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { line-height: calc(2 / 2px)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(50vh + 10px)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(50vh 10px + =)
+#reset
+
+#data
+* { z-index: calc(2 * 3)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(2 3 * =)
+#reset
+
+#data
+* { z-index: calc(50vh + 10px / 9)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(50vh 10px 9 / + =)
+#reset
+
+#data
+* { z-index: calc(1 + 2 + 3 + 4)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + 3 + 4 + =)
+#reset
+
+#data
+* { z-index: calc(1 + 2 * 3 + 4)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 3 * + 4 + =)
+#reset
+
+#data
+* { z-index: calc((1 + 2) * (3 + 4))}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + 3 4 + * =)
+#reset
+
+#data
+* { z-index: calc(1 + 2}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc (1 + 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(1)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 =)
+#reset
+
+#data
+* { z-index: calc()}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc((1 + 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(((1 + 2)))}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + =)
+#reset
+
+#data
+* { z-index: calc( ( ( 1 + 2 ) ) )}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + =)
+#reset
+
+#data
+* { z-index: calc( ( 3 / ( 1 + 2 ) ) )}
+#errors
+#expected
+| *
+#reset
diff --git a/test/dump.h b/test/dump.h
index 7ad84d9..71d2801 100644
--- a/test/dump.h
+++ b/test/dump.h
@@ -834,6 +834,13 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t 
depth)
                                        dump_unit(num, unit, ptr);
                                        *ptr += sprintf(*ptr, " ");
                                        break;
+                               case CALC_PUSH_NUMBER: {
+                                       css_fixed num = *((css_fixed 
*)bytecode);
+                                       ADVANCE(sizeof(num));
+                                       dump_number(num, ptr);
+                                       *ptr += sprintf(*ptr, " ");
+                                       break;
+                               }
                                }
                                default:
                                        *ptr += sprintf(*ptr, "??%d ", 
calc_opcode);


commitdiff 
http://git.netsurf-browser.org/libcss.git/commit/?id=709b6c7b5db034edb9b7d2f3b989916180dbf1e1
commit 709b6c7b5db034edb9b7d2f3b989916180dbf1e1
Author: Daniel Silverstone <[email protected]>
Commit: Michael Drake <Michael Drake [email protected]>

    parse: calc() test and fixup.

diff --git a/src/bytecode/bytecode.h b/src/bytecode/bytecode.h
index 2267542..93f01d1 100644
--- a/src/bytecode/bytecode.h
+++ b/src/bytecode/bytecode.h
@@ -23,6 +23,15 @@ enum flag {
        FLAG_INHERIT                    = (1<<1)
 };
 
+enum calc_opcodes {
+       CALC_PUSH_VALUE = 'V',
+       CALC_ADD        = '+',
+       CALC_SUBTRACT   = '-',
+       CALC_MULTIPLY   = '*',
+       CALC_DIVIDE     = '/',
+       CALC_FINISH     = '=',
+};
+
 typedef enum unit {
        UNIT_PX   = 0,
        UNIT_EX   = 1,
@@ -108,6 +117,12 @@ static inline bool isInherit(css_code_t OPV)
        return getFlags(OPV) & 0x2;
 }
 
+static inline bool isCalc(css_code_t OPV)
+{
+       /* Note, this relies on all _CALC values being the same ultimately */
+       return getValue(OPV) == 0x7f;
+}
+
 #endif
 
 
diff --git a/src/parse/properties/css_property_parser_gen.c 
b/src/parse/properties/css_property_parser_gen.c
index 36a1daf..e68ad55 100644
--- a/src/parse/properties/css_property_parser_gen.c
+++ b/src/parse/properties/css_property_parser_gen.c
@@ -310,7 +310,7 @@ void output_calc(FILE *outputf, struct keyval *parseid, 
struct keyval_list *kvli
                kind = ckv->key;
 
        fprintf(outputf,
-               "if ((token->type == CSS_TOKEN_IDENT) && "
+               "if ((token->type == CSS_TOKEN_FUNCTION) && "
                "(lwc_string_caseless_isequal(token->idata, c->strings[CALC], 
&match) == lwc_error_ok && match))"
                " {\n"
                "\t\terror = css__parse_calc(c, vector, ctx, result, 
buildOPV(%s, 0, %s), %s);\n"
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c
index 11b7f72..a0fc786 100644
--- a/src/parse/properties/utils.c
+++ b/src/parse/properties/utils.c
@@ -1373,8 +1373,10 @@ css__parse_calc_value(css_language *c,
        int orig_ctx = *ctx;
        const css_token *token;
 
-       token = parserutils_vector_iterate(vector, ctx);
+       /* On entry, we are already pointing at the value to parse, so peek it 
*/
+       token = parserutils_vector_peek(vector, *ctx);
        if (tokenIsChar(token, '(')) {
+               parserutils_vector_iterate(vector, ctx);
                error = css__parse_calc_sum(c, vector, ctx, result);
                if (error != CSS_OK) {
                        return error;
@@ -1384,7 +1386,8 @@ css__parse_calc_value(css_language *c,
                if (!tokenIsChar(token, ')')) {
                        return CSS_INVALID;
                }
-
+               /* Consume the close-paren to complete this value */
+               parserutils_vector_iterate(vector, ctx);
        } else switch (token->type) {
        case CSS_TOKEN_NUMBER:    /* Fall through */
        case CSS_TOKEN_DIMENSION: /* Fall through */
@@ -1400,7 +1403,7 @@ css__parse_calc_value(css_language *c,
                        return error;
                }
 
-               error = css__stylesheet_style_vappend(result, 3, (css_code_t) 
'V', length, unit);
+               error = css__stylesheet_style_vappend(result, 3, (css_code_t) 
CALC_PUSH_VALUE, length, unit);
        }
                break;
 
@@ -1409,6 +1412,11 @@ css__parse_calc_value(css_language *c,
                break;
        }
 
+       token = parserutils_vector_peek(vector, *ctx);
+       while (token->type == CSS_TOKEN_S) {
+               parserutils_vector_iterate(vector, ctx);
+               token = parserutils_vector_peek(vector, *ctx);
+       }
        return error;
 }
 
@@ -1439,7 +1447,10 @@ css__parse_calc_product(css_language *c,
                if (token == NULL) {
                        error = CSS_INVALID;
                        break;
-               } else if (tokenIsChar(token, ')'))
+               } else if (
+                               tokenIsChar(token, ')') ||
+                               tokenIsChar(token, '+') ||
+                               tokenIsChar(token, '-'))
                        break;
                else if (tokenIsChar(token, '*'))
                        multiplication = true;
@@ -1450,15 +1461,21 @@ css__parse_calc_product(css_language *c,
                        break;
                }
                /* Consume that * or / now */
-               token = parserutils_vector_iterate(vector, ctx);
+               parserutils_vector_iterate(vector, ctx);
+               token = parserutils_vector_peek(vector, *ctx);
 
+               while (token->type == CSS_TOKEN_S) {
+                       parserutils_vector_iterate(vector, ctx);
+                       token = parserutils_vector_peek(vector, *ctx);
+               }
                /* parse another value */
                error = css__parse_calc_value(c, vector, ctx, result);
                if (error != CSS_OK)
                        break;
 
                /* emit the multiplication/division operator */
-               error = css__stylesheet_style_append(result, (css_code_t) 
(multiplication ? '*' : '/'));
+               error = css__stylesheet_style_append(result,
+                                       (css_code_t) (multiplication ? 
CALC_MULTIPLY : CALC_DIVIDE));
        } while (1);
        /* We've fallen off, either we had an error or we're left with ')' */
        return error;
@@ -1498,7 +1515,13 @@ css__parse_calc_sum(css_language *c,
                        break;
                }
                /* Consume that + or - now */
-               token = parserutils_vector_iterate(vector, ctx);
+               parserutils_vector_iterate(vector, ctx);
+               token = parserutils_vector_peek(vector, *ctx);
+
+               while (token->type == CSS_TOKEN_S) {
+                       parserutils_vector_iterate(vector, ctx);
+                       token = parserutils_vector_peek(vector, *ctx);
+               }
 
                /* parse another product */
                error = css__parse_calc_product(c, vector, ctx, result);
@@ -1506,7 +1529,7 @@ css__parse_calc_sum(css_language *c,
                        break;
 
                /* emit the addition/subtraction operator */
-               error = css__stylesheet_style_append(result, (css_code_t) 
(addition ? '+' : '-'));
+               error = css__stylesheet_style_append(result, (css_code_t) 
(addition ? CALC_ADD : CALC_SUBTRACT));
        } while (1);
        /* We've fallen off, either we had an error or we're left with ')' */
        return error;
@@ -1524,16 +1547,15 @@ css_error css__parse_calc(css_language *c,
        css_error error = CSS_OK;
        css_style *calc_style = NULL;
 
-       token = parserutils_vector_iterate(vector, ctx);
+       token = parserutils_vector_peek(vector, *ctx);
        if (token == NULL) {
                *ctx = orig_ctx;
                return CSS_INVALID;
        }
 
-       if (!tokenIsChar(token, '(')) {
-               /* If we don't get an open-paren, give up now */
-               *ctx = orig_ctx;
-               return CSS_INVALID;
+       while (token->type == CSS_TOKEN_S) {
+               parserutils_vector_iterate(vector, ctx);
+               token = parserutils_vector_peek(vector, *ctx);
        }
 
        error = css__stylesheet_style_create(c->sheet, &calc_style);
@@ -1545,27 +1567,33 @@ css_error css__parse_calc(css_language *c,
                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);
        if (error != CSS_OK)
                goto cleanup;
 
-       token = parserutils_vector_iterate(vector, ctx);
+       token = parserutils_vector_peek(vector, *ctx);
+       while (token->type == CSS_TOKEN_S) {
+               parserutils_vector_iterate(vector, ctx);
+               token = parserutils_vector_peek(vector, *ctx);
+       }
        if (!tokenIsChar(token, ')')) {
                /* If we don't get a close-paren, give up now */
                error = CSS_INVALID;
                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) '=');
+       error = css__stylesheet_style_append(calc_style, (css_code_t) 
CALC_FINISH);
        if (error != CSS_OK)
                goto cleanup;
 
-       /* TODO: Once we're OK to do so, merge the style */
-       (void)result;
-       /* error = css__stylesheet_style_merge_style(result, calc_style); */
-
+       error = css__stylesheet_merge_style(result, calc_style);
 cleanup:
        css__stylesheet_style_destroy(calc_style);
        if (error != CSS_OK) {
diff --git a/test/data/parse2/INDEX b/test/data/parse2/INDEX
index 331cf5c..bb2a79b 100644
--- a/test/data/parse2/INDEX
+++ b/test/data/parse2/INDEX
@@ -23,3 +23,4 @@ multicol.dat                  Multi-column layout property 
tests
 flexbox.dat                    Flexbox properties and shorthands tests
 units.dat                      Length unit tests
 dodgy-media-block.dat          Media block with incomplete ruleset
+calc.dat                       calc() tests
diff --git a/test/data/parse2/calc.dat b/test/data/parse2/calc.dat
new file mode 100644
index 0000000..95abf6c
--- /dev/null
+++ b/test/data/parse2/calc.dat
@@ -0,0 +1,7 @@
+#data
+* { height: calc(50vh + 10px)}
+#errors
+#expected
+| *
+|  height: /* -> 0px */ calc(50vh 10px + =)
+#reset
\ No newline at end of file
diff --git a/test/dump.h b/test/dump.h
index d67bb2a..7ad84d9 100644
--- a/test/dump.h
+++ b/test/dump.h
@@ -647,6 +647,12 @@ static void dump_unit(css_fixed val, uint32_t unit, char 
**ptr)
        case UNIT_KHZ:
                *ptr += sprintf(*ptr, "kHz");
                break;
+       case UNIT_CALC_ANY:
+               *ptr += sprintf(*ptr, "any");
+               break;
+       case UNIT_CALC_NUMBER:
+               *ptr += sprintf(*ptr, "number");
+               break;
        }
 }
 
@@ -797,6 +803,45 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t 
depth)
 
                if (isInherit(opv)) {
                        *ptr += sprintf(*ptr, "inherit");
+               } else if (isCalc(opv)) {
+                       /* First entry is a unit */
+                       uint32_t unit = *((uint32_t *)bytecode);
+                       ADVANCE(sizeof(unit));
+                       *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));
+                               switch (calc_opcode) {
+                               case CALC_ADD:
+                                       *ptr += sprintf(*ptr, "+ ");
+                                       break;
+                               case CALC_SUBTRACT:
+                                       *ptr += sprintf(*ptr, "- ");
+                                       break;
+                               case CALC_MULTIPLY:
+                                       *ptr += sprintf(*ptr, "* ");
+                                       break;
+                               case CALC_DIVIDE:
+                                       *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));
+                                       dump_unit(num, unit, ptr);
+                                       *ptr += sprintf(*ptr, " ");
+                                       break;
+                               }
+                               default:
+                                       *ptr += sprintf(*ptr, "??%d ", 
calc_opcode);
+                                       break;
+                               }
+                       }
+                       ADVANCE(sizeof(calc_opcode));
+                       *ptr += sprintf(*ptr, "=)");
                } else {
                        value = getValue(opv);
 


-----------------------------------------------------------------------

Summary of changes:
 src/bytecode/bytecode.h                        |   16 +++
 src/parse/properties/css_property_parser_gen.c |    2 +-
 src/parse/properties/utils.c                   |   93 ++++++++++----
 test/data/parse2/INDEX                         |    1 +
 test/data/parse2/calc.dat                      |  157 ++++++++++++++++++++++++
 test/dump.h                                    |   52 ++++++++
 6 files changed, 296 insertions(+), 25 deletions(-)
 create mode 100644 test/data/parse2/calc.dat

diff --git a/src/bytecode/bytecode.h b/src/bytecode/bytecode.h
index 2267542..2dff97c 100644
--- a/src/bytecode/bytecode.h
+++ b/src/bytecode/bytecode.h
@@ -23,6 +23,16 @@ enum flag {
        FLAG_INHERIT                    = (1<<1)
 };
 
+enum calc_opcodes {
+       CALC_PUSH_NUMBER = 'N',
+       CALC_PUSH_VALUE  = 'V',
+       CALC_ADD         = '+',
+       CALC_SUBTRACT    = '-',
+       CALC_MULTIPLY    = '*',
+       CALC_DIVIDE      = '/',
+       CALC_FINISH      = '=',
+};
+
 typedef enum unit {
        UNIT_PX   = 0,
        UNIT_EX   = 1,
@@ -108,6 +118,12 @@ static inline bool isInherit(css_code_t OPV)
        return getFlags(OPV) & 0x2;
 }
 
+static inline bool isCalc(css_code_t OPV)
+{
+       /* Note, this relies on all _CALC values being the same ultimately */
+       return getValue(OPV) == 0x7f;
+}
+
 #endif
 
 
diff --git a/src/parse/properties/css_property_parser_gen.c 
b/src/parse/properties/css_property_parser_gen.c
index 36a1daf..e68ad55 100644
--- a/src/parse/properties/css_property_parser_gen.c
+++ b/src/parse/properties/css_property_parser_gen.c
@@ -310,7 +310,7 @@ void output_calc(FILE *outputf, struct keyval *parseid, 
struct keyval_list *kvli
                kind = ckv->key;
 
        fprintf(outputf,
-               "if ((token->type == CSS_TOKEN_IDENT) && "
+               "if ((token->type == CSS_TOKEN_FUNCTION) && "
                "(lwc_string_caseless_isequal(token->idata, c->strings[CALC], 
&match) == lwc_error_ok && match))"
                " {\n"
                "\t\terror = css__parse_calc(c, vector, ctx, result, 
buildOPV(%s, 0, %s), %s);\n"
diff --git a/src/parse/properties/utils.c b/src/parse/properties/utils.c
index 11b7f72..ddb488f 100644
--- a/src/parse/properties/utils.c
+++ b/src/parse/properties/utils.c
@@ -1365,6 +1365,31 @@ css__parse_calc_sum(css_language *c,
                css_style *result);
 
 static css_error
+css__parse_calc_number(
+               const parserutils_vector *vector, int *ctx,
+               css_style *result)
+{
+       const css_token *token;
+       css_fixed num;
+       size_t consumed;
+
+       /* Consume the number token */
+       token = parserutils_vector_iterate(vector, ctx);
+       if (token == NULL || token->type != CSS_TOKEN_NUMBER) {
+               return CSS_INVALID;
+       }
+
+       num = css__number_from_string((const uint8_t 
*)lwc_string_data(token->idata),
+                               lwc_string_length(token->idata), false, 
&consumed);
+
+       if (consumed != lwc_string_length(token->idata)) {
+               return CSS_INVALID;
+       }
+
+       return css__stylesheet_style_vappend(result, 2, (css_code_t) 
CALC_PUSH_NUMBER, (css_code_t)num);
+}
+
+static css_error
 css__parse_calc_value(css_language *c,
                const parserutils_vector *vector, int *ctx,
                css_style *result)
@@ -1373,8 +1398,11 @@ css__parse_calc_value(css_language *c,
        int orig_ctx = *ctx;
        const css_token *token;
 
-       token = parserutils_vector_iterate(vector, ctx);
+       /* On entry, we are already pointing at the value to parse, so peek it 
*/
+       token = parserutils_vector_peek(vector, *ctx);
        if (tokenIsChar(token, '(')) {
+               parserutils_vector_iterate(vector, ctx);
+               consumeWhitespace(vector, ctx);
                error = css__parse_calc_sum(c, vector, ctx, result);
                if (error != CSS_OK) {
                        return error;
@@ -1384,9 +1412,15 @@ css__parse_calc_value(css_language *c,
                if (!tokenIsChar(token, ')')) {
                        return CSS_INVALID;
                }
-
+               /* Consume the close-paren to complete this value */
+               parserutils_vector_iterate(vector, ctx);
        } else switch (token->type) {
-       case CSS_TOKEN_NUMBER:    /* Fall through */
+       case CSS_TOKEN_NUMBER:
+               error = css__parse_calc_number(vector, ctx, result);
+               if (error != CSS_OK) {
+                       return error;
+               }
+               break;
        case CSS_TOKEN_DIMENSION: /* Fall through */
        case CSS_TOKEN_PERCENTAGE:
        {
@@ -1400,7 +1434,7 @@ css__parse_calc_value(css_language *c,
                        return error;
                }
 
-               error = css__stylesheet_style_vappend(result, 3, (css_code_t) 
'V', length, unit);
+               error = css__stylesheet_style_vappend(result, 3, (css_code_t) 
CALC_PUSH_VALUE, length, unit);
        }
                break;
 
@@ -1409,6 +1443,7 @@ css__parse_calc_value(css_language *c,
                break;
        }
 
+       consumeWhitespace(vector, ctx);
        return error;
 }
 
@@ -1439,7 +1474,10 @@ css__parse_calc_product(css_language *c,
                if (token == NULL) {
                        error = CSS_INVALID;
                        break;
-               } else if (tokenIsChar(token, ')'))
+               } else if (
+                               tokenIsChar(token, ')') ||
+                               tokenIsChar(token, '+') ||
+                               tokenIsChar(token, '-'))
                        break;
                else if (tokenIsChar(token, '*'))
                        multiplication = true;
@@ -1450,15 +1488,22 @@ css__parse_calc_product(css_language *c,
                        break;
                }
                /* Consume that * or / now */
-               token = parserutils_vector_iterate(vector, ctx);
+               parserutils_vector_iterate(vector, ctx);
 
-               /* parse another value */
-               error = css__parse_calc_value(c, vector, ctx, result);
+               consumeWhitespace(vector, ctx);
+
+               if (multiplication) {
+                       /* parse another value */
+                       error = css__parse_calc_value(c, vector, ctx, result);
+               } else {
+                       error = css__parse_calc_number(vector, ctx, result);
+               }
                if (error != CSS_OK)
                        break;
 
                /* emit the multiplication/division operator */
-               error = css__stylesheet_style_append(result, (css_code_t) 
(multiplication ? '*' : '/'));
+               error = css__stylesheet_style_append(result,
+                                       (css_code_t) (multiplication ? 
CALC_MULTIPLY : CALC_DIVIDE));
        } while (1);
        /* We've fallen off, either we had an error or we're left with ')' */
        return error;
@@ -1498,7 +1543,8 @@ css__parse_calc_sum(css_language *c,
                        break;
                }
                /* Consume that + or - now */
-               token = parserutils_vector_iterate(vector, ctx);
+               parserutils_vector_iterate(vector, ctx);
+               consumeWhitespace(vector, ctx);
 
                /* parse another product */
                error = css__parse_calc_product(c, vector, ctx, result);
@@ -1506,7 +1552,7 @@ css__parse_calc_sum(css_language *c,
                        break;
 
                /* emit the addition/subtraction operator */
-               error = css__stylesheet_style_append(result, (css_code_t) 
(addition ? '+' : '-'));
+               error = css__stylesheet_style_append(result, (css_code_t) 
(addition ? CALC_ADD : CALC_SUBTRACT));
        } while (1);
        /* We've fallen off, either we had an error or we're left with ')' */
        return error;
@@ -1524,14 +1570,10 @@ css_error css__parse_calc(css_language *c,
        css_error error = CSS_OK;
        css_style *calc_style = NULL;
 
-       token = parserutils_vector_iterate(vector, ctx);
-       if (token == NULL) {
-               *ctx = orig_ctx;
-               return CSS_INVALID;
-       }
+       consumeWhitespace(vector, ctx);
 
-       if (!tokenIsChar(token, '(')) {
-               /* If we don't get an open-paren, give up now */
+       token = parserutils_vector_peek(vector, *ctx);
+       if (token == NULL) {
                *ctx = orig_ctx;
                return CSS_INVALID;
        }
@@ -1545,27 +1587,30 @@ css_error css__parse_calc(css_language *c,
                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);
        if (error != CSS_OK)
                goto cleanup;
 
-       token = parserutils_vector_iterate(vector, ctx);
+       consumeWhitespace(vector, ctx);
+       token = parserutils_vector_peek(vector, *ctx);
        if (!tokenIsChar(token, ')')) {
                /* If we don't get a close-paren, give up now */
                error = CSS_INVALID;
                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) '=');
+       error = css__stylesheet_style_append(calc_style, (css_code_t) 
CALC_FINISH);
        if (error != CSS_OK)
                goto cleanup;
 
-       /* TODO: Once we're OK to do so, merge the style */
-       (void)result;
-       /* error = css__stylesheet_style_merge_style(result, calc_style); */
-
+       error = css__stylesheet_merge_style(result, calc_style);
 cleanup:
        css__stylesheet_style_destroy(calc_style);
        if (error != CSS_OK) {
diff --git a/test/data/parse2/INDEX b/test/data/parse2/INDEX
index 331cf5c..bb2a79b 100644
--- a/test/data/parse2/INDEX
+++ b/test/data/parse2/INDEX
@@ -23,3 +23,4 @@ multicol.dat                  Multi-column layout property 
tests
 flexbox.dat                    Flexbox properties and shorthands tests
 units.dat                      Length unit tests
 dodgy-media-block.dat          Media block with incomplete ruleset
+calc.dat                       calc() tests
diff --git a/test/data/parse2/calc.dat b/test/data/parse2/calc.dat
new file mode 100644
index 0000000..e9d176d
--- /dev/null
+++ b/test/data/parse2/calc.dat
@@ -0,0 +1,157 @@
+#data
+* { height: calc(50vh + 10px)}
+#errors
+#expected
+| *
+|  height: /* -> 0px */ calc(50vh 10px + =)
+#reset
+
+#data
+* { line-height: calc(50vh + 10px)}
+#errors
+#expected
+| *
+|  line-height: /* -> 0any */ calc(50vh 10px + =)
+#reset
+
+#data
+* { line-height: calc( / 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { line-height: calc( + 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { line-height: calc(2 / 2px)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(50vh + 10px)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(50vh 10px + =)
+#reset
+
+#data
+* { z-index: calc(2 * 3)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(2 3 * =)
+#reset
+
+#data
+* { z-index: calc(50vh + 10px / 9)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(50vh 10px 9 / + =)
+#reset
+
+#data
+* { z-index: calc(1 + 2 + 3 + 4)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + 3 + 4 + =)
+#reset
+
+#data
+* { z-index: calc(1 + 2 * 3 + 4)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 3 * + 4 + =)
+#reset
+
+#data
+* { z-index: calc((1 + 2) * (3 + 4))}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + 3 4 + * =)
+#reset
+
+#data
+* { z-index: calc(1 + 2}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc (1 + 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(1)}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 =)
+#reset
+
+#data
+* { z-index: calc()}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc((1 + 2)}
+#errors
+#expected
+| *
+#reset
+
+#data
+* { z-index: calc(((1 + 2)))}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + =)
+#reset
+
+#data
+* { z-index: calc( ( ( 1 + 2 ) ) )}
+#errors
+#expected
+| *
+|  z-index: /* -> 0number */ calc(1 2 + =)
+#reset
+
+#data
+* { z-index: calc( ( 3 / ( 1 + 2 ) ) )}
+#errors
+#expected
+| *
+#reset
diff --git a/test/dump.h b/test/dump.h
index d67bb2a..71d2801 100644
--- a/test/dump.h
+++ b/test/dump.h
@@ -647,6 +647,12 @@ static void dump_unit(css_fixed val, uint32_t unit, char 
**ptr)
        case UNIT_KHZ:
                *ptr += sprintf(*ptr, "kHz");
                break;
+       case UNIT_CALC_ANY:
+               *ptr += sprintf(*ptr, "any");
+               break;
+       case UNIT_CALC_NUMBER:
+               *ptr += sprintf(*ptr, "number");
+               break;
        }
 }
 
@@ -797,6 +803,52 @@ void dump_bytecode(css_style *style, char **ptr, uint32_t 
depth)
 
                if (isInherit(opv)) {
                        *ptr += sprintf(*ptr, "inherit");
+               } else if (isCalc(opv)) {
+                       /* First entry is a unit */
+                       uint32_t unit = *((uint32_t *)bytecode);
+                       ADVANCE(sizeof(unit));
+                       *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));
+                               switch (calc_opcode) {
+                               case CALC_ADD:
+                                       *ptr += sprintf(*ptr, "+ ");
+                                       break;
+                               case CALC_SUBTRACT:
+                                       *ptr += sprintf(*ptr, "- ");
+                                       break;
+                               case CALC_MULTIPLY:
+                                       *ptr += sprintf(*ptr, "* ");
+                                       break;
+                               case CALC_DIVIDE:
+                                       *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));
+                                       dump_unit(num, unit, ptr);
+                                       *ptr += sprintf(*ptr, " ");
+                                       break;
+                               case CALC_PUSH_NUMBER: {
+                                       css_fixed num = *((css_fixed 
*)bytecode);
+                                       ADVANCE(sizeof(num));
+                                       dump_number(num, ptr);
+                                       *ptr += sprintf(*ptr, " ");
+                                       break;
+                               }
+                               }
+                               default:
+                                       *ptr += sprintf(*ptr, "??%d ", 
calc_opcode);
+                                       break;
+                               }
+                       }
+                       ADVANCE(sizeof(calc_opcode));
+                       *ptr += sprintf(*ptr, "=)");
                } else {
                        value = getValue(opv);
 


-- 
Cascading Style Sheets library
_______________________________________________
netsurf-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to