151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*
251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2012 Intel Corporation. All rights reserved.
1051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *
1151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * This library is free software; you can redistribute it and/or
1251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * modify it under the terms of the GNU Library General Public
1351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * License as published by the Free Software Foundation; either
1451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * version 2 of the License, or (at your option) any later version.
1551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *
1651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * This library is distributed in the hope that it will be useful,
1751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
1851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Library General Public License for more details.
2051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *
2151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * You should have received a copy of the GNU Library General Public License
2251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
2351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Boston, MA 02110-1301, USA.
2551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */
2651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "config.h"
28e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/css/parser/CSSTokenizer.h"
2951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/css/CSSKeyframeRule.h"
3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/css/MediaQuery.h"
3251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/css/StyleRule.h"
33e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/css/parser/BisonCSSParser.h"
34e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/css/parser/CSSParserValues.h"
3551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h"
3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/svg/SVGParserUtilities.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
405d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/CSSGrammar.h"
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)enum CharacterType {
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Types for the main switch.
4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // The first 4 types must be grouped together, as they
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // represent the allowed chars in an identifier.
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterCaselessU,
4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterIdentifierStart,
4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterNumber,
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterDash,
5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterOther,
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterNull,
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterWhiteSpace,
5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterEndMediaQueryOrSupports,
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterEndNthChild,
5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterQuote,
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterExclamationMark,
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterHashmark,
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterDollar,
6151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterAsterisk,
6251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterPlus,
6351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterDot,
6451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterSlash,
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterLess,
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterAt,
6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterBackSlash,
6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterXor,
6951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterVerticalBar,
7051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterTilde,
7151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)};
7251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
7351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// 128 ASCII codes
7451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static const CharacterType typesOfASCIICharacters[128] = {
7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   0 - Null               */ CharacterNull,
7651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   1 - Start of Heading   */ CharacterOther,
7751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   2 - Start of Text      */ CharacterOther,
7851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   3 - End of Text        */ CharacterOther,
7951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   4 - End of Transm.     */ CharacterOther,
8051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   5 - Enquiry            */ CharacterOther,
8151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   6 - Acknowledgment     */ CharacterOther,
8251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   7 - Bell               */ CharacterOther,
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   8 - Back Space         */ CharacterOther,
8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*   9 - Horizontal Tab     */ CharacterWhiteSpace,
8551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  10 - Line Feed          */ CharacterWhiteSpace,
8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  11 - Vertical Tab       */ CharacterOther,
8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  12 - Form Feed          */ CharacterWhiteSpace,
8851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  13 - Carriage Return    */ CharacterWhiteSpace,
8951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  14 - Shift Out          */ CharacterOther,
9051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  15 - Shift In           */ CharacterOther,
9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  16 - Data Line Escape   */ CharacterOther,
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  17 - Device Control 1   */ CharacterOther,
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  18 - Device Control 2   */ CharacterOther,
9451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  19 - Device Control 3   */ CharacterOther,
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  20 - Device Control 4   */ CharacterOther,
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  21 - Negative Ack.      */ CharacterOther,
9751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  22 - Synchronous Idle   */ CharacterOther,
9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  23 - End of Transmit    */ CharacterOther,
9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  24 - Cancel             */ CharacterOther,
10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  25 - End of Medium      */ CharacterOther,
10151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  26 - Substitute         */ CharacterOther,
10251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  27 - Escape             */ CharacterOther,
10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  28 - File Separator     */ CharacterOther,
10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  29 - Group Separator    */ CharacterOther,
10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  30 - Record Separator   */ CharacterOther,
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  31 - Unit Separator     */ CharacterOther,
10751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  32 - Space              */ CharacterWhiteSpace,
10851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  33 - !                  */ CharacterExclamationMark,
10951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  34 - "                  */ CharacterQuote,
11051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  35 - #                  */ CharacterHashmark,
11151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  36 - $                  */ CharacterDollar,
11251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  37 - %                  */ CharacterOther,
11351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  38 - &                  */ CharacterOther,
11451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  39 - '                  */ CharacterQuote,
11551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  40 - (                  */ CharacterOther,
11651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  41 - )                  */ CharacterEndNthChild,
11751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  42 - *                  */ CharacterAsterisk,
11851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  43 - +                  */ CharacterPlus,
11951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  44 - ,                  */ CharacterOther,
12051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  45 - -                  */ CharacterDash,
12151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  46 - .                  */ CharacterDot,
12251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  47 - /                  */ CharacterSlash,
12351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  48 - 0                  */ CharacterNumber,
12451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  49 - 1                  */ CharacterNumber,
12551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  50 - 2                  */ CharacterNumber,
12651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  51 - 3                  */ CharacterNumber,
12751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  52 - 4                  */ CharacterNumber,
12851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  53 - 5                  */ CharacterNumber,
12951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  54 - 6                  */ CharacterNumber,
13051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  55 - 7                  */ CharacterNumber,
13151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  56 - 8                  */ CharacterNumber,
13251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  57 - 9                  */ CharacterNumber,
13351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  58 - :                  */ CharacterOther,
13451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  59 - ;                  */ CharacterEndMediaQueryOrSupports,
13551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  60 - <                  */ CharacterLess,
13651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  61 - =                  */ CharacterOther,
13751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  62 - >                  */ CharacterOther,
13851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  63 - ?                  */ CharacterOther,
13951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  64 - @                  */ CharacterAt,
14051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  65 - A                  */ CharacterIdentifierStart,
14151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  66 - B                  */ CharacterIdentifierStart,
14251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  67 - C                  */ CharacterIdentifierStart,
14351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  68 - D                  */ CharacterIdentifierStart,
14451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  69 - E                  */ CharacterIdentifierStart,
14551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  70 - F                  */ CharacterIdentifierStart,
14651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  71 - G                  */ CharacterIdentifierStart,
14751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  72 - H                  */ CharacterIdentifierStart,
14851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  73 - I                  */ CharacterIdentifierStart,
14951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  74 - J                  */ CharacterIdentifierStart,
15051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  75 - K                  */ CharacterIdentifierStart,
15151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  76 - L                  */ CharacterIdentifierStart,
15251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  77 - M                  */ CharacterIdentifierStart,
15351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  78 - N                  */ CharacterIdentifierStart,
15451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  79 - O                  */ CharacterIdentifierStart,
15551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  80 - P                  */ CharacterIdentifierStart,
15651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  81 - Q                  */ CharacterIdentifierStart,
15751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  82 - R                  */ CharacterIdentifierStart,
15851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  83 - S                  */ CharacterIdentifierStart,
15951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  84 - T                  */ CharacterIdentifierStart,
16051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  85 - U                  */ CharacterCaselessU,
16151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  86 - V                  */ CharacterIdentifierStart,
16251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  87 - W                  */ CharacterIdentifierStart,
16351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  88 - X                  */ CharacterIdentifierStart,
16451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  89 - Y                  */ CharacterIdentifierStart,
16551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  90 - Z                  */ CharacterIdentifierStart,
16651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  91 - [                  */ CharacterOther,
16751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  92 - \                  */ CharacterBackSlash,
16851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  93 - ]                  */ CharacterOther,
16951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  94 - ^                  */ CharacterXor,
17051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  95 - _                  */ CharacterIdentifierStart,
17151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  96 - `                  */ CharacterOther,
17251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  97 - a                  */ CharacterIdentifierStart,
17351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  98 - b                  */ CharacterIdentifierStart,
17451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*  99 - c                  */ CharacterIdentifierStart,
17551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 100 - d                  */ CharacterIdentifierStart,
17651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 101 - e                  */ CharacterIdentifierStart,
17751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 102 - f                  */ CharacterIdentifierStart,
17851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 103 - g                  */ CharacterIdentifierStart,
17951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 104 - h                  */ CharacterIdentifierStart,
18051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 105 - i                  */ CharacterIdentifierStart,
18151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 106 - j                  */ CharacterIdentifierStart,
18251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 107 - k                  */ CharacterIdentifierStart,
18351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 108 - l                  */ CharacterIdentifierStart,
18451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 109 - m                  */ CharacterIdentifierStart,
18551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 110 - n                  */ CharacterIdentifierStart,
18651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 111 - o                  */ CharacterIdentifierStart,
18751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 112 - p                  */ CharacterIdentifierStart,
18851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 113 - q                  */ CharacterIdentifierStart,
18951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 114 - r                  */ CharacterIdentifierStart,
19051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 115 - s                  */ CharacterIdentifierStart,
19151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 116 - t                  */ CharacterIdentifierStart,
19251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 117 - u                  */ CharacterCaselessU,
19351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 118 - v                  */ CharacterIdentifierStart,
19451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 119 - w                  */ CharacterIdentifierStart,
19551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 120 - x                  */ CharacterIdentifierStart,
19651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 121 - y                  */ CharacterIdentifierStart,
19751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 122 - z                  */ CharacterIdentifierStart,
19851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 123 - {                  */ CharacterEndMediaQueryOrSupports,
19951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 124 - |                  */ CharacterVerticalBar,
20051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 125 - }                  */ CharacterOther,
20151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 126 - ~                  */ CharacterTilde,
20251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/* 127 - Delete             */ CharacterOther,
20351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)};
20451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
20551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// Utility functions for the CSS tokenizer.
20651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
20751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
20851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline bool isCSSLetter(CharacterType character)
20951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
21051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return character >= 128 || typesOfASCIICharacters[character] <= CharacterDash;
21151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
21251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
21351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
21451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline bool isCSSEscape(CharacterType character)
21551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
21651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return character >= ' ' && character != 127;
21751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
21851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
21951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
22051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline bool isURILetter(CharacterType character)
22151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
22251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return (character >= '*' && character != 127) || (character >= '#' && character <= '&') || character == '!';
22351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
22451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
22551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
22651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline bool isIdentifierStartAfterDash(CharacterType* currentCharacter)
22751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
22851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return isASCIIAlpha(currentCharacter[0]) || currentCharacter[0] == '_' || currentCharacter[0] >= 128
22951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        || (currentCharacter[0] == '\\' && isCSSEscape(currentCharacter[1]));
23051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
23151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
23251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
23351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline bool isEqualToCSSIdentifier(CharacterType* cssString, const char* constantString)
23451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
23551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Compare an character memory data with a zero terminated string.
23651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    do {
23751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // The input must be part of an identifier if constantChar or constString
23851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // contains '-'. Otherwise toASCIILowerUnchecked('\r') would be equal to '-'.
23951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT((*constantString >= 'a' && *constantString <= 'z') || *constantString == '-');
24051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(*constantString != '-' || isCSSLetter(*cssString));
24151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (toASCIILowerUnchecked(*cssString++) != (*constantString++))
24251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return false;
24351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } while (*constantString);
24451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
24551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
24651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
24751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
24851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline bool isEqualToCSSCaseSensitiveIdentifier(CharacterType* string, const char* constantString)
24951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
25051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(*constantString);
25151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
25251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    do {
25351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*string++ != *constantString++)
25451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return false;
25551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } while (*constantString);
25651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
25751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
25851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
25951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
26051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static CharacterType* checkAndSkipEscape(CharacterType* currentCharacter)
26151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
26251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Returns with 0, if escape check is failed. Otherwise
26351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // it returns with the following character.
26451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(*currentCharacter == '\\');
26551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
26651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++currentCharacter;
26751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!isCSSEscape(*currentCharacter))
26851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return 0;
26951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
27051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (isASCIIHexDigit(*currentCharacter)) {
27151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        int length = 6;
27251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
27351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        do {
27451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter;
27551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } while (isASCIIHexDigit(*currentCharacter) && --length);
27651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
27751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Optional space after the escape sequence.
27851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isHTMLSpace<CharacterType>(*currentCharacter))
27951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter;
28051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return currentCharacter;
28151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
28251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return currentCharacter + 1;
28351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
28451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
28551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
28651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline CharacterType* skipWhiteSpace(CharacterType* currentCharacter)
28751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
28851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (isHTMLSpace<CharacterType>(*currentCharacter))
28951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ++currentCharacter;
29051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return currentCharacter;
29151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
29251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
29351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)// Main CSS tokenizer functions.
29451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
29551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
29651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline LChar*& CSSTokenizer::currentCharacter<LChar>()
29751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
29851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return m_currentCharacter8;
29951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
30051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
30151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
30251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline UChar*& CSSTokenizer::currentCharacter<UChar>()
30351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
30451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return m_currentCharacter16;
30551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
30651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
307aafa69cb17c9d6606c07663ade5f81388a2c5986Ben MurdochUChar* CSSTokenizer::allocateStringBuffer16(size_t len)
30851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
309aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // Allocates and returns a CSSTokenizer owned buffer for storing
310aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // UTF-16 data. Used to get a suitable life span for UTF-16
311aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // strings, identifiers and URIs created by the tokenizer.
312aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    OwnPtr<UChar[]> buffer = adoptArrayPtr(new UChar[len]);
31351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
314aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    UChar* bufferPtr = buffer.get();
315aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
316aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    m_cssStrings16.append(buffer.release());
317aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    return bufferPtr;
31851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
31951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
32051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
32151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline LChar* CSSTokenizer::dataStart<LChar>()
32251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
32351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return m_dataStart8.get();
32451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
32551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
32651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
32751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline UChar* CSSTokenizer::dataStart<UChar>()
32851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
32951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return m_dataStart16.get();
33051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
33151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
33251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
33351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline CSSParserLocation CSSTokenizer::tokenLocation()
33451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
33551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CSSParserLocation location;
33651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    location.token.init(tokenStart<CharacterType>(), currentCharacter<CharacterType>() - tokenStart<CharacterType>());
33751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    location.lineNumber = m_tokenStartLineNumber;
33851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    location.offset = tokenStart<CharacterType>() - dataStart<CharacterType>();
33951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return location;
34051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
34151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
34251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)CSSParserLocation CSSTokenizer::currentLocation()
34351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
34451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (is8BitSource())
34551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return tokenLocation<LChar>();
34651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return tokenLocation<UChar>();
34751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
34851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
34951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
35051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::isIdentifierStart()
35151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
35251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Check whether an identifier is started.
35351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return isIdentifierStartAfterDash((*currentCharacter<CharacterType>() != '-') ? currentCharacter<CharacterType>() : currentCharacter<CharacterType>() + 1);
35451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
35551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
356a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochenum CheckStringValidationMode {
357a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    AbortIfInvalid,
358a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    SkipInvalid
359a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch};
360a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch
36151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
362a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdochstatic inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote, CheckStringValidationMode mode)
36351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
364a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // If mode is AbortIfInvalid and the string check fails it returns
365a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // with 0. Otherwise it returns with a pointer to the first
366a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // character after the string.
36751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (true) {
36851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(*currentCharacter == quote)) {
36951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // String parsing is successful.
37051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return currentCharacter + 1;
37151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
37251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(!*currentCharacter)) {
37351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // String parsing is successful up to end of input.
37451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return currentCharacter;
37551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
376a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (mode == AbortIfInvalid && UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
37751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // String parsing is failed for character '\n', '\f' or '\r'.
37851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return 0;
37951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
38051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
38151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (LIKELY(currentCharacter[0] != '\\')) {
38251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter;
38351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f') {
38451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            currentCharacter += 2;
38551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (currentCharacter[1] == '\r') {
38651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            currentCharacter += currentCharacter[2] == '\n' ? 3 : 2;
38751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
388a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            CharacterType* next = checkAndSkipEscape(currentCharacter);
389a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            if (!next) {
390a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                if (mode == AbortIfInvalid)
391a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                    return 0;
392a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch                next = currentCharacter + 1;
393a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            }
394a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch            currentCharacter = next;
39551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
39651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
39751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
39851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
39951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
40051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)unsigned CSSTokenizer::parseEscape(CharacterType*& src)
40151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
40251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(*src == '\\' && isCSSEscape(src[1]));
40351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
40451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    unsigned unicode = 0;
40551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
40651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++src;
40751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (isASCIIHexDigit(*src)) {
40851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
40951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        int length = 6;
41051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
41151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        do {
41251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            unicode = (unicode << 4) + toASCIIHexValue(*src++);
41351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } while (--length && isASCIIHexDigit(*src));
41451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
41551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Characters above 0x10ffff are not handled.
41651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (unicode > 0x10ffff)
41751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            unicode = 0xfffd;
41851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
41951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Optional space after the escape sequence.
42051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isHTMLSpace<CharacterType>(*src))
42151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++src;
42251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
42351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return unicode;
42451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
42551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
426aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    return *src++;
42751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
42851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
42951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
43051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::UnicodeToChars<LChar>(LChar*& result, unsigned unicode)
43151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
43251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(unicode <= 0xff);
43351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    *result = unicode;
43451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
43551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++result;
43651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
43751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
43851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
43951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::UnicodeToChars<UChar>(UChar*& result, unsigned unicode)
44051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
44151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Replace unicode with a surrogate pairs when it is bigger than 0xffff
44251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (U16_LENGTH(unicode) == 2) {
44351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        *result++ = U16_LEAD(unicode);
44451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        *result = U16_TRAIL(unicode);
44551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } else {
44651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        *result = unicode;
44751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
44851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
44951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++result;
45051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
45151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
452aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochtemplate <typename SrcCharacterType>
453aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochsize_t CSSTokenizer::peekMaxIdentifierLen(SrcCharacterType* src)
454aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{
455aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // The decoded form of an identifier (after resolving escape
456aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // sequences) will not contain more characters (ASCII or UTF-16
457aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // codepoints) than the input. This code can therefore ignore
458aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // escape sequences completely.
459aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    SrcCharacterType* start = src;
460aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    do {
461aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        if (LIKELY(*src != '\\'))
462aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            src++;
463aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        else
464aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            parseEscape<SrcCharacterType>(src);
465aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    } while (isCSSLetter(src[0]) || (src[0] == '\\' && isCSSEscape(src[1])));
466aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
467aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    return src - start;
468aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch}
469aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
47051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename SrcCharacterType, typename DestCharacterType>
47151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::parseIdentifierInternal(SrcCharacterType*& src, DestCharacterType*& result, bool& hasEscape)
47251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
47351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    hasEscape = false;
47451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    do {
47551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (LIKELY(*src != '\\')) {
47651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            *result++ = *src++;
47751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
47851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            hasEscape = true;
47951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            SrcCharacterType* savedEscapeStart = src;
48051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            unsigned unicode = parseEscape<SrcCharacterType>(src);
48151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (unicode > 0xff && sizeof(DestCharacterType) == 1) {
48251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                src = savedEscapeStart;
48351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                return false;
48451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
48551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            UnicodeToChars(result, unicode);
48651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
48751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } while (isCSSLetter(src[0]) || (src[0] == '\\' && isCSSEscape(src[1])));
48851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
48951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
49051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
49151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
49251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
49351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::parseIdentifier(CharacterType*& result, CSSParserString& resultString, bool& hasEscape)
49451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
49551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // If a valid identifier start is found, we can safely
49651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // parse the identifier until the next invalid character.
49751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(isIdentifierStart<CharacterType>());
49851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
49951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* start = currentCharacter<CharacterType>();
50051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (UNLIKELY(!parseIdentifierInternal(currentCharacter<CharacterType>(), result, hasEscape))) {
50151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
50251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(is8BitSource());
503aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        UChar* result16 = allocateStringBuffer16((result - start) + peekMaxIdentifierLen(currentCharacter<CharacterType>()));
50451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        UChar* start16 = result16;
50551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        int i = 0;
50651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (; i < result - start; i++)
50751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            result16[i] = start[i];
50851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
50951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        result16 += i;
51051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
51151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        parseIdentifierInternal(currentCharacter<CharacterType>(), result16, hasEscape);
51251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
51351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        resultString.init(start16, result16 - start16);
51451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
51551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
51651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
51751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
51851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    resultString.init(start, result - start);
51951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
52051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
521aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochtemplate <typename SrcCharacterType>
522aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochsize_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote)
523aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{
524aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // The decoded form of a CSS string (after resolving escape
525aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // sequences) will not contain more characters (ASCII or UTF-16
526aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // codepoints) than the input. This code can therefore ignore
527aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // escape sequences completely and just return the length of the
528aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // input string (possibly including terminating quote if any).
529a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    SrcCharacterType* end = checkAndSkipString(src, quote, SkipInvalid);
530aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    return end ? end - src : 0;
531aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch}
532aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
53351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename SrcCharacterType, typename DestCharacterType>
53451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharacterType*& result, UChar quote)
53551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
53651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (true) {
53751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(*src == quote)) {
53851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // String parsing is done.
53951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++src;
54051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
54151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
54251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(!*src)) {
54351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // String parsing is done, but don't advance pointer if at the end of input.
54451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
54551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
54651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (LIKELY(src[0] != '\\')) {
54751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            *result++ = *src++;
54851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (src[1] == '\n' || src[1] == '\f') {
54951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            src += 2;
55051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (src[1] == '\r') {
55151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            src += src[2] == '\n' ? 3 : 2;
55251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
55351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            SrcCharacterType* savedEscapeStart = src;
55451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            unsigned unicode = parseEscape<SrcCharacterType>(src);
55551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (unicode > 0xff && sizeof(DestCharacterType) == 1) {
55651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                src = savedEscapeStart;
55751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                return false;
55851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
55951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            UnicodeToChars(result, unicode);
56051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
56151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
56251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
56351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
56451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
56551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
56651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
56751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::parseString(CharacterType*& result, CSSParserString& resultString, UChar quote)
56851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
56951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* start = currentCharacter<CharacterType>();
57051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
57151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (UNLIKELY(!parseStringInternal(currentCharacter<CharacterType>(), result, quote))) {
57251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
57351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(is8BitSource());
574aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        UChar* result16 = allocateStringBuffer16((result - start) + peekMaxStringLen(currentCharacter<CharacterType>(), quote));
57551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        UChar* start16 = result16;
57651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        int i = 0;
57751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (; i < result - start; i++)
57851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            result16[i] = start[i];
57951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
58051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        result16 += i;
58151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
58251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        parseStringInternal(currentCharacter<CharacterType>(), result16, quote);
58351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
58451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        resultString.init(start16, result16 - start16);
58551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
58651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
58751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
58851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    resultString.init(start, result - start);
58951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
59051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
59151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
59251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UChar& quote)
59351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
59451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    start = skipWhiteSpace(currentCharacter<CharacterType>());
59551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
59651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (*start == '"' || *start == '\'') {
59751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        quote = *start++;
598a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        end = checkAndSkipString(start, quote, AbortIfInvalid);
59951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!end)
60051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return false;
60151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } else {
60251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        quote = 0;
60351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        end = start;
60451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while (isURILetter(*end)) {
60551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(*end != '\\')) {
60651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++end;
60751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else {
60851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                end = checkAndSkipEscape(end);
60951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (!end)
61051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    return false;
61151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
61251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
61351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
61451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
61551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    end = skipWhiteSpace(end);
61651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (*end != ')')
61751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return false;
61851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
61951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
62051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
62151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
622aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochtemplate <typename SrcCharacterType>
623aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdochinline size_t CSSTokenizer::peekMaxURILen(SrcCharacterType* src, UChar quote)
624aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch{
625aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // The decoded form of a URI (after resolving escape sequences)
626aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // will not contain more characters (ASCII or UTF-16 codepoints)
627aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // than the input. This code can therefore ignore escape sequences
628aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    // completely.
629aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    SrcCharacterType* start = src;
630aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (quote) {
631aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        ASSERT(quote == '"' || quote == '\'');
632aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return peekMaxStringLen(src, quote);
633aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
634aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
635aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    while (isURILetter(*src)) {
636aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        if (LIKELY(*src != '\\'))
637aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            src++;
638aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        else
639aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            parseEscape<SrcCharacterType>(src);
640aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
641aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
642aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    return src - start;
643aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch}
644aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch
64551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename SrcCharacterType, typename DestCharacterType>
64651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::parseURIInternal(SrcCharacterType*& src, DestCharacterType*& dest, UChar quote)
64751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
64851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (quote) {
64951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(quote == '"' || quote == '\'');
65051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return parseStringInternal(src, dest, quote);
65151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
65251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
65351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (isURILetter(*src)) {
65451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (LIKELY(*src != '\\')) {
65551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            *dest++ = *src++;
65651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
65751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            unsigned unicode = parseEscape<SrcCharacterType>(src);
658aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch            if (unicode > 0xff && sizeof(DestCharacterType) == 1)
65951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                return false;
66051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            UnicodeToChars(dest, unicode);
66151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
66251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
66351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
66451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
66551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
66651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
66751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
66851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::parseURI(CSSParserString& string)
66951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
67051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* uriStart;
67151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* uriEnd;
67251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    UChar quote;
67351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!findURI(uriStart, uriEnd, quote))
67451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
67551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
67651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* dest = currentCharacter<CharacterType>() = uriStart;
67751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (LIKELY(parseURIInternal(currentCharacter<CharacterType>(), dest, quote))) {
67851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        string.init(uriStart, dest - uriStart);
67951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } else {
68051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // An escape sequence was encountered that can't be stored in 8 bits.
68151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Reset the current character to the start of the URI and re-parse with
68251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // a 16-bit destination.
68351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT(is8BitSource());
68451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        currentCharacter<CharacterType>() = uriStart;
685aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        UChar* result16 = allocateStringBuffer16(peekMaxURILen(currentCharacter<CharacterType>(), quote));
686aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        UChar* uriStart16 = result16;
687aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        bool result = parseURIInternal(currentCharacter<CharacterType>(), result16, quote);
68851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT_UNUSED(result, result);
689aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        string.init(uriStart16, result16 - uriStart16);
69051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
69151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
69251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    currentCharacter<CharacterType>() = uriEnd + 1;
69351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_token = URI;
69451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
69551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
69651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
69751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::parseUnicodeRange()
69851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
69951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* character = currentCharacter<CharacterType>() + 1;
70051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    int length = 6;
70151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(*currentCharacter<CharacterType>() == '+');
70251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
70351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (isASCIIHexDigit(*character) && length) {
70451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ++character;
70551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        --length;
70651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
70751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
70851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (length && *character == '?') {
70951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // At most 5 hex digit followed by a question mark.
71051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        do {
71151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++character;
71251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            --length;
71351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } while (*character == '?' && length);
71451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        currentCharacter<CharacterType>() = character;
71551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return true;
71651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
71751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
71851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (length < 6) {
71951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // At least one hex digit.
72051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (character[0] == '-' && isASCIIHexDigit(character[1])) {
72151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // Followed by a dash and a hex digit.
72251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++character;
72351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            length = 6;
72451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            do {
72551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++character;
72651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } while (--length && isASCIIHexDigit(*character));
72751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
72851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        currentCharacter<CharacterType>() = character;
72951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return true;
73051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
73151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return false;
73251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
73351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
73451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
73551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool CSSTokenizer::parseNthChild()
73651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
73751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* character = currentCharacter<CharacterType>();
73851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
73951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    while (isASCIIDigit(*character))
74051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ++character;
74151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (isASCIIAlphaCaselessEqual(*character, 'n')) {
74251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        currentCharacter<CharacterType>() = character + 1;
74351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return true;
74451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
74551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return false;
74651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
74751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
74851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
74951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)bool CSSTokenizer::parseNthChildExtra()
75051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
75151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* character = skipWhiteSpace(currentCharacter<CharacterType>());
75251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (*character != '+' && *character != '-')
75351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return false;
75451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
75551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    character = skipWhiteSpace(character + 1);
75651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!isASCIIDigit(*character))
75751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return false;
75851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
75951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    do {
76051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ++character;
76151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } while (isASCIIDigit(*character));
76251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
76351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    currentCharacter<CharacterType>() = character;
76451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return true;
76551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
76651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
76751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
76851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool CSSTokenizer::detectFunctionTypeToken(int length)
76951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
77051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(length > 0);
77151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* name = tokenStart<CharacterType>();
77251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SWITCH(name, length) {
77351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("not") {
77451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = NOTFUNCTION;
77551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
77651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
77751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("url") {
77851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = URI;
77951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
78051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
78151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("cue") {
78251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = CUEFUNCTION;
78351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
78451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
78551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("calc") {
78651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = CALCFUNCTION;
78751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
78851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
78951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("host") {
79051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = HOSTFUNCTION;
79151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
79251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
79307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        CASE("host-context") {
79407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            m_token = HOSTCONTEXTFUNCTION;
79509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return true;
79609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
79751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("nth-child") {
79851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = NthChildMode;
79951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
80051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
80151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("nth-of-type") {
80251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = NthChildMode;
80351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
80451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
80551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("nth-last-child") {
80651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = NthChildMode;
80751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
80851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
80951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("nth-last-of-type") {
81051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = NthChildMode;
81151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return true;
81251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
81351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
81451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return false;
81551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
81651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
81751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
81851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::detectMediaQueryToken(int length)
81951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
82051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(m_parsingMode == MediaQueryMode);
82151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* name = tokenStart<CharacterType>();
82251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
82351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SWITCH(name, length) {
82451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("and") {
82551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MEDIA_AND;
82651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
82751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("not") {
82851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MEDIA_NOT;
82951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
83051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("only") {
83151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MEDIA_ONLY;
83251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
83351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("or") {
83451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MEDIA_OR;
83551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
83651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
83751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
83851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
83951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
84051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::detectNumberToken(CharacterType* type, int length)
84151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
84251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(length > 0);
84351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
84451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SWITCH(type, length) {
84551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("cm") {
84651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = CMS;
84751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
84851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("ch") {
84951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = CHS;
85051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
85151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("deg") {
85251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = DEGS;
85351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
85451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("dppx") {
85551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // There is a discussion about the name of this unit on www-style.
85651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // Keep this compile time guard in place until that is resolved.
85751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // http://lists.w3.org/Archives/Public/www-style/2012May/0915.html
85851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = DPPX;
85951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
86051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("dpcm") {
86151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = DPCM;
86251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
86351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("dpi") {
86451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = DPI;
86551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
86651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("em") {
86751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = EMS;
86851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
86951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("ex") {
87051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = EXS;
87151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
87251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("fr") {
87351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = FR;
87451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
87551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("grad") {
87651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = GRADS;
87751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
87851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("hz") {
87951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = HERTZ;
88051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
88151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("in") {
88251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = INS;
88351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
88451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("khz") {
88551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = KHERTZ;
88651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
88751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("mm") {
88851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MMS;
88951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
89051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("ms") {
89151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MSECS;
89251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
89351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("px") {
89451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = PXS;
89551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
89651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("pt") {
89751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = PTS;
89851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
89951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("pc") {
90051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = PCS;
90151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
90251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("rad") {
90351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = RADS;
90451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
90551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("rem") {
90651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = REMS;
90751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
90851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("s") {
90951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SECS;
91051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
91151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("turn") {
91251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = TURNS;
91351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
91451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("vw") {
91551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = VW;
91651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
91751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("vh") {
91851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = VH;
91951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
92051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("vmin") {
92151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = VMIN;
92251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
92351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("vmax") {
92451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = VMAX;
92551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
92651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("__qem") {
92751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = QEMS;
92851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
92951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
93051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
93151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
93251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
93351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::detectDashToken(int length)
93451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
93551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* name = tokenStart<CharacterType>();
93651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
93751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Ignore leading dash.
93851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++name;
93951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    --length;
94051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
94151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SWITCH(name, length) {
94251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("webkit-any") {
94351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = ANYFUNCTION;
94451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
94551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("webkit-calc") {
94651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = CALCFUNCTION;
94751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
94851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
94951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
95051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
95151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
95251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::detectAtToken(int length, bool hasEscape)
95351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
95451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* name = tokenStart<CharacterType>();
95551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(name[0] == '@' && length >= 2);
95651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
95751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Ignore leading @.
95851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++name;
95951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    --length;
96051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
96151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // charset, font-face, import, media, namespace, page, supports,
96251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // -webkit-keyframes, keyframes, and -webkit-mediaquery are not affected by hasEscape.
96351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SWITCH(name, length) {
96451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("bottom-left") {
96551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
96651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = BOTTOMLEFT_SYM;
96751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
96851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("bottom-right") {
96951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
97051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = BOTTOMRIGHT_SYM;
97151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
97251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("bottom-center") {
97351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
97451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = BOTTOMCENTER_SYM;
97551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
97651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("bottom-left-corner") {
97751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
97851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = BOTTOMLEFTCORNER_SYM;
97951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
98051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("bottom-right-corner") {
98151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
98251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = BOTTOMRIGHTCORNER_SYM;
98351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
98451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("charset") {
98551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (name - 1 == dataStart<CharacterType>())
98651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = CHARSET_SYM;
98751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
98851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("font-face") {
98951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = FONT_FACE_SYM;
99051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
99151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("import") {
99251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = MediaQueryMode;
99351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = IMPORT_SYM;
99451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
99551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("keyframes") {
99651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
99751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = KEYFRAMES_SYM;
99851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
99951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("left-top") {
100051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
100151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = LEFTTOP_SYM;
100251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
100351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("left-middle") {
100451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
100551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = LEFTMIDDLE_SYM;
100651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
100751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("left-bottom") {
100851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
100951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = LEFTBOTTOM_SYM;
101051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
101151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("media") {
101251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = MediaQueryMode;
101351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = MEDIA_SYM;
101451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
101551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("namespace") {
101651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = NAMESPACE_SYM;
101751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
101851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("page") {
101951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = PAGE_SYM;
102051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
102151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("right-top") {
102251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
102351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = RIGHTTOP_SYM;
102451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
102551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("right-middle") {
102651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
102751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = RIGHTMIDDLE_SYM;
102851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
102951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("right-bottom") {
103051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
103151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = RIGHTBOTTOM_SYM;
103251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
103351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("supports") {
103451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = SupportsMode;
103551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SUPPORTS_SYM;
103651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
103751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("top-left") {
103851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
103951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = TOPLEFT_SYM;
104051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
104151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("top-right") {
104251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
104351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = TOPRIGHT_SYM;
104451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
104551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("top-center") {
104651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
104751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = TOPCENTER_SYM;
104851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
104951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("top-left-corner") {
105051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
105151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = TOPLEFTCORNER_SYM;
105251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
105351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("top-right-corner") {
105451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape))
105551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = TOPRIGHTCORNER_SYM;
105651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
105751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("viewport") {
105851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = VIEWPORT_RULE_SYM;
105951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
106051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-rule") {
106151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape && m_internal))
106251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = INTERNAL_RULE_SYM;
106351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
106451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-decls") {
106551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape && m_internal))
106651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = INTERNAL_DECLS_SYM;
106751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
106851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-value") {
106951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape && m_internal))
107051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = INTERNAL_VALUE_SYM;
107151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
107251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-webkit-keyframes") {
107351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = WEBKIT_KEYFRAMES_SYM;
107451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
107551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-selector") {
107651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape && m_internal))
107751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = INTERNAL_SELECTOR_SYM;
107851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
107951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-keyframe-rule") {
108051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (LIKELY(!hasEscape && m_internal))
108151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = INTERNAL_KEYFRAME_RULE_SYM;
108251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
108351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-keyframe-key-list") {
108451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!m_internal)
108551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                return;
108651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = INTERNAL_KEYFRAME_KEY_LIST_SYM;
108751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
108851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("-internal-supports-condition") {
108951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!m_internal)
109051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                return;
109151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = SupportsMode;
109251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = INTERNAL_SUPPORTS_CONDITION_SYM;
109351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
109451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
109551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
109651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
109751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename CharacterType>
109851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::detectSupportsToken(int length)
109951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
110051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(m_parsingMode == SupportsMode);
110151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CharacterType* name = tokenStart<CharacterType>();
110251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
110351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SWITCH(name, length) {
110451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("or") {
110551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SUPPORTS_OR;
110651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
110751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("and") {
110851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SUPPORTS_AND;
110951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
111051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        CASE("not") {
111151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SUPPORTS_NOT;
111251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
111351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
111451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
111551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
111651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <typename SrcCharacterType>
111751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)int CSSTokenizer::realLex(void* yylvalWithoutType)
111851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
111951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    YYSTYPE* yylval = static_cast<YYSTYPE*>(yylvalWithoutType);
112051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // Write pointer for the next character.
112151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    SrcCharacterType* result;
112251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    CSSParserString resultString;
112351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool hasEscape;
112451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
112551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // The input buffer is terminated by a \0 character, so
112651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // it is safe to read one character ahead of a known non-null.
1127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT)
112851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // In debug we check with an ASSERT that the length is > 0 for string types.
112951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    yylval->string.clear();
113051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#endif
113151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
113251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)restartAfterComment:
113351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    result = currentCharacter<SrcCharacterType>();
113451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    setTokenStart(result);
113551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_tokenStartLineNumber = m_lineNumber;
113651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_token = *currentCharacter<SrcCharacterType>();
113751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ++currentCharacter<SrcCharacterType>();
113851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
113951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    switch ((m_token <= 127) ? typesOfASCIICharacters[m_token] : CharacterIdentifierStart) {
114051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterCaselessU:
114151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(*currentCharacter<SrcCharacterType>() == '+')) {
114251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (parseUnicodeRange<SrcCharacterType>()) {
114351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = UNICODERANGE;
114451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                yylval->string.init(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
114551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                break;
114651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
114751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
114851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Fall through to CharacterIdentifierStart.
114951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
115051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterIdentifierStart:
115151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        --currentCharacter<SrcCharacterType>();
115251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        parseIdentifier(result, yylval->string, hasEscape);
115351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_token = IDENT;
115451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
115551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(*currentCharacter<SrcCharacterType>() == '(')) {
115651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (m_parsingMode == SupportsMode && !hasEscape) {
115751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
115851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (m_token != IDENT)
115951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    break;
116051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
116151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
116251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = FUNCTION;
116351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!hasEscape)
116451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                detectFunctionTypeToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
116551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
116651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // Skip parenthesis
116751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
116851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++result;
116951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
117051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (m_token == URI) {
117151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = FUNCTION;
117251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                // Check whether it is really an URI.
117351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (yylval->string.is8Bit())
117451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    parseURI<LChar>(yylval->string);
117551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                else
117651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    parseURI<UChar>(yylval->string);
117751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
117851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (UNLIKELY(m_parsingMode != NormalMode) && !hasEscape) {
117951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (m_parsingMode == MediaQueryMode) {
118051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                detectMediaQueryToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
118151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (m_parsingMode == SupportsMode) {
118251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                detectSupportsToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
118351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (m_parsingMode == NthChildMode && isASCIIAlphaCaselessEqual(tokenStart<SrcCharacterType>()[0], 'n')) {
118451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (result - tokenStart<SrcCharacterType>() == 1) {
118551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // String "n" is IDENT but "n+1" is NTH.
118651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (parseNthChildExtra<SrcCharacterType>()) {
118751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        m_token = NTH;
118851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        yylval->string.m_length = currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>();
118951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    }
119051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                } else if (result - tokenStart<SrcCharacterType>() >= 2 && tokenStart<SrcCharacterType>()[1] == '-') {
119151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // String "n-" is IDENT but "n-1" is NTH.
119251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // Set currentCharacter to '-' to continue parsing.
119351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    SrcCharacterType* nextCharacter = result;
119451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    currentCharacter<SrcCharacterType>() = tokenStart<SrcCharacterType>() + 1;
119551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (parseNthChildExtra<SrcCharacterType>()) {
119651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        m_token = NTH;
119751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        yylval->string.setLength(currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
119851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    } else {
119951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        // Revert the change to currentCharacter if unsuccessful.
120051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        currentCharacter<SrcCharacterType>() = nextCharacter;
120151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    }
120251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
120351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
120451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
120551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
120651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
120751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterDot:
120851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!isASCIIDigit(currentCharacter<SrcCharacterType>()[0]))
120951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            break;
121051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Fall through to CharacterNumber.
121151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
121251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterNumber: {
121351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        bool dotSeen = (m_token == '.');
121451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
121551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while (true) {
121651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!isASCIIDigit(currentCharacter<SrcCharacterType>()[0])) {
121751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                // Only one dot is allowed for a number,
121851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                // and it must be followed by a digit.
121951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (currentCharacter<SrcCharacterType>()[0] != '.' || dotSeen || !isASCIIDigit(currentCharacter<SrcCharacterType>()[1]))
122051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    break;
122151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                dotSeen = true;
122251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
122351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
122451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
122551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
122651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(m_parsingMode == NthChildMode) && !dotSeen && isASCIIAlphaCaselessEqual(*currentCharacter<SrcCharacterType>(), 'n')) {
122751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // "[0-9]+n" is always an NthChild.
122851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
122951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseNthChildExtra<SrcCharacterType>();
123051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = NTH;
123151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            yylval->string.init(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
123251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            break;
123351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
123451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
12357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        // We need to take care of units like 'em' or 'ex'.
12367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        SrcCharacterType* character = currentCharacter<SrcCharacterType>();
12377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (isASCIIAlphaCaselessEqual(*character, 'e')) {
12387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ASSERT(character - tokenStart<SrcCharacterType>() > 0);
12397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            ++character;
12407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            if (*character == '-' || *character == '+' || isASCIIDigit(*character)) {
124151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++character;
12427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                while (isASCIIDigit(*character))
124351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    ++character;
12447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                // Use FLOATTOKEN if the string contains exponents.
12457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                dotSeen = true;
12467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                currentCharacter<SrcCharacterType>() = character;
124751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
124851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
124951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
12507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        yylval->number = charactersToDouble(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
12517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
125251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Type of the function.
125351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isIdentifierStart<SrcCharacterType>()) {
125451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            SrcCharacterType* type = currentCharacter<SrcCharacterType>();
125551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            result = currentCharacter<SrcCharacterType>();
125651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
125751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseIdentifier(result, resultString, hasEscape);
125851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
125951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = DIMEN;
126051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!hasEscape)
126151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                detectNumberToken(type, currentCharacter<SrcCharacterType>() - type);
126251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
126351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (m_token == DIMEN) {
126451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                // The decoded number is overwritten, but this is intentional.
126551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                yylval->string.init(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
126651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
126751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (*currentCharacter<SrcCharacterType>() == '%') {
126851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // Although the CSS grammar says {num}% we follow
126951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // webkit at the moment which uses {num}%+.
127051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            do {
127151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++currentCharacter<SrcCharacterType>();
127251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } while (*currentCharacter<SrcCharacterType>() == '%');
127351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = PERCENTAGE;
127451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
127551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = dotSeen ? FLOATTOKEN : INTEGER;
127651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
127751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
127851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
127951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
128051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterDash:
128151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isIdentifierStartAfterDash(currentCharacter<SrcCharacterType>())) {
128251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            --currentCharacter<SrcCharacterType>();
128351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseIdentifier(result, resultString, hasEscape);
128451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = IDENT;
128551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
128651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (*currentCharacter<SrcCharacterType>() == '(') {
128751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = FUNCTION;
128851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (!hasEscape)
128951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    detectDashToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
129051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++currentCharacter<SrcCharacterType>();
129151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++result;
129251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } else if (UNLIKELY(m_parsingMode == NthChildMode) && !hasEscape && isASCIIAlphaCaselessEqual(tokenStart<SrcCharacterType>()[1], 'n')) {
129351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (result - tokenStart<SrcCharacterType>() == 2) {
129451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // String "-n" is IDENT but "-n+1" is NTH.
129551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (parseNthChildExtra<SrcCharacterType>()) {
129651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        m_token = NTH;
129751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        result = currentCharacter<SrcCharacterType>();
129851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    }
129951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                } else if (result - tokenStart<SrcCharacterType>() >= 3 && tokenStart<SrcCharacterType>()[2] == '-') {
130051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // String "-n-" is IDENT but "-n-1" is NTH.
130151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // Set currentCharacter to second '-' of '-n-' to continue parsing.
130251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    SrcCharacterType* nextCharacter = result;
130351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    currentCharacter<SrcCharacterType>() = tokenStart<SrcCharacterType>() + 2;
130451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (parseNthChildExtra<SrcCharacterType>()) {
130551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        m_token = NTH;
130651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        result = currentCharacter<SrcCharacterType>();
130751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    } else {
130851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        // Revert the change to currentCharacter if unsuccessful.
130951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        currentCharacter<SrcCharacterType>() = nextCharacter;
131051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    }
131151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
13127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci                resultString.setLength(result - tokenStart<SrcCharacterType>());
131351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
131451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            yylval->string = resultString;
131551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (currentCharacter<SrcCharacterType>()[0] == '-' && currentCharacter<SrcCharacterType>()[1] == '>') {
131651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            currentCharacter<SrcCharacterType>() += 2;
131751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SGML_CD;
131851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (UNLIKELY(m_parsingMode == NthChildMode)) {
131951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // "-[0-9]+n" is always an NthChild.
132051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (parseNthChild<SrcCharacterType>()) {
132151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                parseNthChildExtra<SrcCharacterType>();
132251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = NTH;
132351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                yylval->string.init(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
132451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
132551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
132651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
132751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
132851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterOther:
132951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // m_token is simply the current character.
133051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
133151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
133251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterNull:
133351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Do not advance pointer at the end of input.
133451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        --currentCharacter<SrcCharacterType>();
133551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
133651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
133751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterWhiteSpace:
133851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_token = WHITESPACE;
133951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Might start with a '\n'.
134051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        --currentCharacter<SrcCharacterType>();
134151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        do {
134251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (*currentCharacter<SrcCharacterType>() == '\n')
134351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++m_lineNumber;
134451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
134551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } while (*currentCharacter<SrcCharacterType>() <= ' ' && (typesOfASCIICharacters[*currentCharacter<SrcCharacterType>()] == CharacterWhiteSpace));
134651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
134751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
134851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterEndMediaQueryOrSupports:
134951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode)
135051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = NormalMode;
135151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
135251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
135351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterEndNthChild:
135451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (m_parsingMode == NthChildMode)
135551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_parsingMode = NormalMode;
135651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
135751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
135851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterQuote:
1359a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch        if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token, AbortIfInvalid)) {
136051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++result;
136151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseString<SrcCharacterType>(result, yylval->string, m_token);
136251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = STRING;
136351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
136451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
136551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
136651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterExclamationMark: {
136751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        SrcCharacterType* start = skipWhiteSpace(currentCharacter<SrcCharacterType>());
136851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isEqualToCSSIdentifier(start, "important")) {
136951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = IMPORTANT_SYM;
137051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            currentCharacter<SrcCharacterType>() = start + 9;
137151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
137251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
137351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
137451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
137551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterHashmark: {
137651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        SrcCharacterType* start = currentCharacter<SrcCharacterType>();
137751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        result = currentCharacter<SrcCharacterType>();
137851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
137951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isASCIIDigit(*currentCharacter<SrcCharacterType>())) {
138051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // This must be a valid hex number token.
138151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            do {
138251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++currentCharacter<SrcCharacterType>();
138351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            } while (isASCIIHexDigit(*currentCharacter<SrcCharacterType>()));
138451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = HEX;
138551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            yylval->string.init(start, currentCharacter<SrcCharacterType>() - start);
138651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else if (isIdentifierStart<SrcCharacterType>()) {
138751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = IDSEL;
138851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseIdentifier(result, yylval->string, hasEscape);
138951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (!hasEscape) {
139051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                // Check whether the identifier is also a valid hex number.
139151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                SrcCharacterType* current = start;
139251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = HEX;
139351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                do {
139451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    if (!isASCIIHexDigit(*current)) {
139551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        m_token = IDSEL;
139651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                        break;
139751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    }
139851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    ++current;
139951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                } while (current < result);
140051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
140151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
140251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
140351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
140451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
140551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterSlash:
140651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // Ignore comments. They are not even considered as white spaces.
140751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*currentCharacter<SrcCharacterType>() == '*') {
140851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            const CSSParserLocation startLocation = currentLocation();
140909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (m_parser.m_observer) {
141051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                unsigned startOffset = currentCharacter<SrcCharacterType>() - dataStart<SrcCharacterType>() - 1; // Start with a slash.
141109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                m_parser.m_observer->startComment(startOffset - m_parsedTextPrefixLength);
141251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
141351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
141451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            while (currentCharacter<SrcCharacterType>()[0] != '*' || currentCharacter<SrcCharacterType>()[1] != '/') {
141551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (*currentCharacter<SrcCharacterType>() == '\n')
141651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    ++m_lineNumber;
141751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (*currentCharacter<SrcCharacterType>() == '\0') {
141851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    // Unterminated comments are simply ignored.
141951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    currentCharacter<SrcCharacterType>() -= 2;
142009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    m_parser.reportError(startLocation, UnterminatedCommentCSSError);
142151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    break;
142251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                }
142351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                ++currentCharacter<SrcCharacterType>();
142451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
142551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            currentCharacter<SrcCharacterType>() += 2;
142609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (m_parser.m_observer) {
142751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                unsigned endOffset = currentCharacter<SrcCharacterType>() - dataStart<SrcCharacterType>();
142851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                unsigned userTextEndOffset = static_cast<unsigned>(m_length - 1 - m_parsedTextSuffixLength);
142909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                m_parser.m_observer->endComment(std::min(endOffset, userTextEndOffset) - m_parsedTextPrefixLength);
143051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
143151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            goto restartAfterComment;
143251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
143351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
143451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
143551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterDollar:
143651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*currentCharacter<SrcCharacterType>() == '=') {
143751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
143851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = ENDSWITH;
143951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
144051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
144151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
144251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterAsterisk:
144351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*currentCharacter<SrcCharacterType>() == '=') {
144451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
144551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = CONTAINS;
144651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
144751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
144851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
144951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterPlus:
145051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (UNLIKELY(m_parsingMode == NthChildMode)) {
145151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            // Simplest case. "+[0-9]*n" is always NthChild.
145251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (parseNthChild<SrcCharacterType>()) {
145351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                parseNthChildExtra<SrcCharacterType>();
145451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                m_token = NTH;
145551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                yylval->string.init(tokenStart<SrcCharacterType>(), currentCharacter<SrcCharacterType>() - tokenStart<SrcCharacterType>());
145651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
145751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
145851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
145951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
146051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterLess:
146151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (currentCharacter<SrcCharacterType>()[0] == '!' && currentCharacter<SrcCharacterType>()[1] == '-' && currentCharacter<SrcCharacterType>()[2] == '-') {
146251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            currentCharacter<SrcCharacterType>() += 3;
146351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = SGML_CD;
146451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
146551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
146651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
146751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterAt:
146851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isIdentifierStart<SrcCharacterType>()) {
146951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = ATKEYWORD;
147051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++result;
147151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseIdentifier(result, resultString, hasEscape);
1472d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            // The standard enables unicode escapes in at-rules. In this case only the resultString will contain the
1473d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            // correct identifier, hence we have to use it to determine its length instead of the usual pointer arithmetic.
1474d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            detectAtToken<SrcCharacterType>(resultString.length() + 1, hasEscape);
147551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
147651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
147751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
147851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterBackSlash:
147951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isCSSEscape(*currentCharacter<SrcCharacterType>())) {
148051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            --currentCharacter<SrcCharacterType>();
148151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            parseIdentifier(result, yylval->string, hasEscape);
148251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = IDENT;
148351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
148451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
148551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
148651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterXor:
148751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*currentCharacter<SrcCharacterType>() == '=') {
148851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
148951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = BEGINSWITH;
149051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
149151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
149251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
149351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterVerticalBar:
149451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*currentCharacter<SrcCharacterType>() == '=') {
149551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
149651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = DASHMATCH;
149751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
149851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
149951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
150051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    case CharacterTilde:
150151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (*currentCharacter<SrcCharacterType>() == '=') {
150251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            ++currentCharacter<SrcCharacterType>();
150351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_token = INCLUDES;
150451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
150551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
150651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
150751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    default:
150851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ASSERT_NOT_REACHED();
150951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        break;
151051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
151151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
151251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return m_token;
151351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
151451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
151551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
151651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::setTokenStart<LChar>(LChar* tokenStart)
151751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
151851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_tokenStart.ptr8 = tokenStart;
151951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
152051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
152151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)template <>
152251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline void CSSTokenizer::setTokenStart<UChar>(UChar* tokenStart)
152351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
152451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_tokenStart.ptr16 = tokenStart;
152551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
152651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
152751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void CSSTokenizer::setupTokenizer(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength)
152851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
152951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_parsedTextPrefixLength = prefixLength;
153051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_parsedTextSuffixLength = suffixLength;
153151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    unsigned stringLength = string.length();
153251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    unsigned length = stringLength + m_parsedTextPrefixLength + m_parsedTextSuffixLength + 1;
153351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_length = length;
153451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
153551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!stringLength || string.is8Bit()) {
153651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_dataStart8 = adoptArrayPtr(new LChar[length]);
153751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (unsigned i = 0; i < m_parsedTextPrefixLength; i++)
153851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_dataStart8[i] = prefix[i];
153951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
154051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (stringLength)
154151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            memcpy(m_dataStart8.get() + m_parsedTextPrefixLength, string.characters8(), stringLength * sizeof(LChar));
154251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
154351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        unsigned start = m_parsedTextPrefixLength + stringLength;
154451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        unsigned end = start + suffixLength;
154551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        for (unsigned i = start; i < end; i++)
154651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_dataStart8[i] = suffix[i - start];
154751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
154851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_dataStart8[length - 1] = 0;
154951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
155051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_is8BitSource = true;
155151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_currentCharacter8 = m_dataStart8.get();
155251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_currentCharacter16 = 0;
155351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        setTokenStart<LChar>(m_currentCharacter8);
155451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_lexFunc = &CSSTokenizer::realLex<LChar>;
155551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
155651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
155751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
155851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_dataStart16 = adoptArrayPtr(new UChar[length]);
155951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (unsigned i = 0; i < m_parsedTextPrefixLength; i++)
156051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_dataStart16[i] = prefix[i];
156151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
156251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(stringLength);
156351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    memcpy(m_dataStart16.get() + m_parsedTextPrefixLength, string.characters16(), stringLength * sizeof(UChar));
156451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
156551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    unsigned start = m_parsedTextPrefixLength + stringLength;
156651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    unsigned end = start + suffixLength;
156751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    for (unsigned i = start; i < end; i++)
156851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_dataStart16[i] = suffix[i - start];
156951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
157051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_dataStart16[length - 1] = 0;
157151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
157251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_is8BitSource = false;
157351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_currentCharacter8 = 0;
157451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_currentCharacter16 = m_dataStart16.get();
157551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    setTokenStart<UChar>(m_currentCharacter16);
157651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    m_lexFunc = &CSSTokenizer::realLex<UChar>;
157751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
157851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
1579c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
1580