diff options
author | John Mark Bell <jmb@netsurf-browser.org> | 2008-10-27 05:57:18 +0000 |
---|---|---|
committer | John Mark Bell <jmb@netsurf-browser.org> | 2008-10-27 05:57:18 +0000 |
commit | 93db0a01a331b1820ba26e1ced4cb288ee8bb47d (patch) | |
tree | be3ba849a78b4340e4d3d911472167586afb3b3f /src/lex | |
parent | 749093e336264042c4cc37e3f0c18a052fad2114 (diff) | |
download | libcss-93db0a01a331b1820ba26e1ced4cb288ee8bb47d.tar.gz libcss-93db0a01a331b1820ba26e1ced4cb288ee8bb47d.tar.bz2 |
Support signs on numbers, percentages, and dimensions
svn path=/trunk/libcss/; revision=5648
Diffstat (limited to 'src/lex')
-rw-r--r-- | src/lex/lex.c | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/lex/lex.c b/src/lex/lex.c index 8f85d25..460cca0 100644 --- a/src/lex/lex.c +++ b/src/lex/lex.c @@ -130,7 +130,7 @@ static inline css_error emitToken(css_lexer *lexer, css_token_type type, css_token **token); static inline css_error AtKeyword(css_lexer *lexer, css_token **token); -static inline css_error CDCOrIdentOrFunction(css_lexer *lexer, +static inline css_error CDCOrIdentOrFunctionOrNPD(css_lexer *lexer, css_token **token); static inline css_error CDO(css_lexer *lexer, css_token **token); static inline css_error Comment(css_lexer *lexer, css_token **token); @@ -285,7 +285,7 @@ css_error css_lexer_get_token(css_lexer *lexer, css_token **token) case sCDO: return CDO(lexer, token); case sCDC: - return CDCOrIdentOrFunction(lexer, token); + return CDCOrIdentOrFunctionOrNPD(lexer, token); case sS: return S(lexer, token); case sCOMMENT: @@ -541,7 +541,7 @@ css_error AtKeyword(css_lexer *lexer, css_token **token) return emitToken(lexer, CSS_TOKEN_ATKEYWORD, token); } -css_error CDCOrIdentOrFunction(css_lexer *lexer, css_token **token) +css_error CDCOrIdentOrFunctionOrNPD(css_lexer *lexer, css_token **token) { css_token *t = &lexer->token; uintptr_t cptr; @@ -553,10 +553,14 @@ css_error CDCOrIdentOrFunction(css_lexer *lexer, css_token **token) /* CDC = "-->" * IDENT = [-]? nmstart nmchar* * FUNCTION = [-]? nmstart nmchar* '(' + * NUMBER = num = [-+]? ([0-9]+ | [0-9]* '.' [0-9]+) + * PERCENTAGE = num '%' + * DIMENSION = num ident * * The first dash has been consumed. Thus, we must consume the next * character in the stream. If it's a dash, then we're dealing with - * CDC. Otherwise, we're dealing with IDENT/FUNCTION. + * CDC. If it's a digit or dot, then we're dealing with NPD. + * Otherwise, we're dealing with IDENT/FUNCTION. */ switch (lexer->substate) { @@ -573,6 +577,16 @@ css_error CDCOrIdentOrFunction(css_lexer *lexer, css_token **token) c = *((uint8_t *) cptr); + if (isDigit(c) || c == '.') { + /* NPD */ + APPEND(lexer, cptr, clen); + lexer->state = sNUMBER; + lexer->substate = 0; + /* Abuse "first" to store first non-sign character */ + lexer->context.first = c; + return NumberOrPercentageOrDimension(lexer, token); + } + if (c != '-' && !startNMStart(c)) { /* Can only be CHAR */ return emitToken(lexer, CSS_TOKEN_CHAR, token); @@ -975,11 +989,12 @@ css_error NumberOrPercentageOrDimension(css_lexer *lexer, css_token **token) enum { Initial = 0, Dot = 1, MoreDigits = 2, Suffix = 3, NMChars = 4, Escape = 5 }; - /* NUMBER = num = [0-9]+ | [0-9]* '.' [0-9]+ + /* NUMBER = num = [-+]? ([0-9]+ | [0-9]* '.' [0-9]+) * PERCENTAGE = num '%' * DIMENSION = num ident * - * The first digit, or '.' has been consumed. + * The sign, or sign and first digit or dot, + * or first digit, or '.' has been consumed. */ switch (lexer->substate) { @@ -998,7 +1013,8 @@ css_error NumberOrPercentageOrDimension(css_lexer *lexer, css_token **token) return CSS_NEEDDATA; if (cptr == PARSERUTILS_INPUTSTREAM_EOF) { - if (t->data.len == 1 && lexer->context.first == '.') + if (t->data.len == 1 && (lexer->context.first == '.' || + lexer->context.first == '+')) return emitToken(lexer, CSS_TOKEN_CHAR, token); else return emitToken(lexer, CSS_TOKEN_NUMBER, @@ -1042,7 +1058,8 @@ css_error NumberOrPercentageOrDimension(css_lexer *lexer, css_token **token) return CSS_NEEDDATA; if (cptr == PARSERUTILS_INPUTSTREAM_EOF) { - if (t->data.len == 1 && lexer->context.first == '.') + if (t->data.len == 1 && (lexer->context.first == '.' || + lexer->context.first == '+')) return emitToken(lexer, CSS_TOKEN_CHAR, token); else return emitToken(lexer, CSS_TOKEN_NUMBER, @@ -1051,8 +1068,9 @@ css_error NumberOrPercentageOrDimension(css_lexer *lexer, css_token **token) c = *((uint8_t *) cptr); - /* A solitary '.' is a CHAR, not numeric */ - if (t->data.len == 1 && lexer->context.first == '.') + /* A solitary '.' or '+' is a CHAR, not numeric */ + if (t->data.len == 1 && (lexer->context.first == '.' || + lexer->context.first == '+')) return emitToken(lexer, CSS_TOKEN_CHAR, token); if (c == '%') { @@ -1183,7 +1201,7 @@ start: return Hash(lexer, token); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - case '.': + case '.': case '+': lexer->state = sNUMBER; lexer->substate = 0; lexer->context.first = c; @@ -1195,7 +1213,7 @@ start: case '-': lexer->state = sCDC; lexer->substate = 0; - return CDCOrIdentOrFunction(lexer, token); + return CDCOrIdentOrFunctionOrNPD(lexer, token); case ' ': case '\t': case '\r': case '\n': case '\f': lexer->state = sS; lexer->substate = 0; |