cr-tknzr.c revision 7e2a6804dfcc5976c7ee384d2fc50a91a854adf6
/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
/*
* This file is part of The Croco Library
*
* modify it under the terms of version 2.1 of the GNU Lesser General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* Author: Dodji Seketeli
* See the COPYRIGHTS file for copyrights information.
*/
/**
*@file
*The definition of the #CRTknzr (tokenizer)
*class.
*/
#include "string.h"
#include "cr-tknzr.h"
#include "cr-doc-handler.h"
struct _CRTknzrPriv {
/**The parser input stream of bytes*/
/**
*A cache where tknzr_unget_token()
*puts back the token. tknzr_get_next_token()
*first look in this cache, and if and
*only if it's empty, fetches the next token
*from the input stream.
*/
/**
*The position of the end of the previous token
*or char fetched.
*/
/**
*The reference count of the current instance
*of #CRTknzr. Is manipulated by cr_tknzr_ref()
*and cr_tknzr_unref().
*/
};
/**
*return TRUE if the character is a number ([0-9]), FALSE otherwise
*@param a_char the char to test.
*/
/**
*Checks if 'status' equals CR_OK. If not, goto the 'error' label.
*
*@param status the status (of type enum CRStatus) to test.
*@param is_exception if set to FALSE, the final status returned the
*current function will be CR_PARSING_ERROR. If set to TRUE, the
*current status will be the current value of the 'status' variable.
*
*/
{ \
if (is_exception == FALSE) \
{ \
status = CR_PARSING_ERROR ; \
} \
goto error ; \
}
/**
*Peeks the next char from the input stream of the current tokenizer.
*invokes CHECK_PARSING_STATUS on the status returned by
*cr_tknzr_input_peek_char().
*
*@param the current instance of #CRTkzr.
*@param to_char a pointer to the char where to store the
*char peeked.
*/
{\
}
/**
*Reads the next char from the input stream of the current parser.
*In case of error, jumps to the "error:" label located in the
*function where this macro is called.
*@param parser the curent instance of #CRTknzr
*@param to_char a pointer to the guint32 char where to store
*the character read.
*/
/**
*Gets information about the current position in
*the input of the parser.
*In case of failure, this macro returns from the
*calling function and
*returns a status code of type enum #CRStatus.
*@param parser the current instance of #CRTknzr.
*@param pos out parameter. A pointer to the position
*inside the current parser input. Must
*/
/**
*Gets the address of the current byte inside the
*parser input.
*@param parser the current instance of #CRTknzr.
*@param addr out parameter a pointer (guchar*)
*to where the address must be put.
*/
/**
*Peeks a byte from the topmost parser input at
*a given offset from the current position.
*If it fails, goto the "error:" label.
*
*@param a_parser the current instance of #CRTknzr.
*@param a_offset the offset of the byte to peek, the
*current byte having the offset '0'.
*@param a_byte_ptr out parameter a pointer (guchar*) to
*where the peeked char is to be stored.
*/
a_offset, \
a_byte_ptr) ; \
/**
*Reads a byte from the topmost parser input
*steam.
*If it fails, goto the "error" label.
*@param a_parser the current instance of #CRTknzr.
*@param a_byte_ptr the guchar * where to put the read char.
*/
status = \
/**
*Skips a given number of byte in the topmost
*parser input. Don't update line and column number.
*In case of error, jumps to the "error:" label
*of the surrounding function.
*@param a_parser the current instance of #CRTknzr.
*@param a_nb_bytes the number of bytes to skip.
*/
CR_SEEK_CUR, a_nb_bytes) ; \
/**
*Skip utf8 encoded characters.
*Updates line and column numbers.
*@param a_parser the current instance of #CRTknzr.
*@param a_nb_chars the number of chars to skip. Must be of
*type glong.
*/
{ \
}
/**
*Tests the condition and if it is false, sets
*status to "CR_PARSING_ERROR" and goto the 'error'
*label.
*@param condition the condition to test.
*/
#define ENSURE_PARSING_COND(condition) \
/**********************************
*PRIVATE methods
**********************************/
/**
*Parses a "w" as defined by the css spec at [4.1.1]:
* w ::= [ \t\r\n\f]*
*
*@param a_this the current instance of #CRTknzr.
*@param a_start out param. Upon successfull completion, points
*to the beginning of the parsed white space, points to NULL otherwise.
*Can also point to NULL is there is no white space actually.
*@param a_end out param. Upon successfull completion, points
*to the end of the parsed white space, points to NULL otherwise.
*Can also point to NULL is there is no white space actually.
*/
static enum CRStatus
{
goto error;
}
if (a_location) {
a_location) ;
}
for (;;) {
if (is_eof)
break;
if (status == CR_END_OF_INPUT_ERROR) {
break;
goto error;
}
} else {
break;
}
}
return CR_OK;
return status;
}
/**
*Parses a newline as defined in the css2 spec:
* nl ::= \n|\r\n|\r|\f
*
*@param a_this the "this pointer" of the current instance of #CRTknzr.
*@param a_start a pointer to the first character of the successfully
*parsed string.
*@param a_end a pointer to the last character of the successfully parsed
*string.
*@result CR_OK uppon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
if (a_location) {
(a_this, a_location) ;
}
} else if (next_chars[0] == '\n'
if (a_location) {
(a_this, a_location) ;
}
} else {
goto error;
}
return CR_OK ;
return status;
}
/**
*Go ahead in the parser input, skipping all the spaces.
*If the next char if not a white space, this function does nothing.
*In any cases, it stops when it encounters a non white space character.
*
*@param a_this the current instance of #CRTknzr.
*@return CR_OK upon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
if (status == CR_END_OF_INPUT_ERROR)
return CR_OK;
return status;
}
}
return status;
}
/**
*Parses a "comment" as defined in the css spec at [4.1.1]:
*COMMENT ::= \/\*[^*]*\*+([^/][^*]*\*+)*\/ .
*This complex regexp is just to say that comments start
*with the two chars '/''*' and ends with the two chars '*''/'.
*It also means that comments cannot be nested.
*So based on that, I've just tried to implement the parsing function
*simply and in a straight forward manner.
*/
static enum CRStatus
{
CRParsingLocation loc = {0,0,0} ;
comment = cr_string_new ();
for (;;) {
/*make sure there are no nested comments */
if (cur_char == '/') {
cur_char);
continue;
}
/*Detect the end of the comments region */
if (cur_char == '*') {
if (next_char == '/') {
/*
*end of comments region
*Now, call the right SAC callback.
*/
break;
} else {
'*');
}
}
}
&loc) ;
return CR_OK;
}
if (comment) {
}
return status;
}
/**
*Parses an 'unicode' escape sequence defined
*in css spec at chap 4.1.1:
*unicode ::= \\[0-9a-f]{1,6}[ \n\r\t\f]?
*@param a_this the current instance of #CRTknzr.
*@param a_start out parameter. A pointer to the start
*of the unicode escape sequence. Must *NOT* be deleted by
*the caller.
*@param a_end out parameter. A pointer to the last character
*of the unicode escape sequence. Must *NOT* be deleted by the caller.
*@return CR_OK if parsing succeded, an error code otherwise.
*Error code can be either CR_PARSING_ERROR if the string
*parsed just doesn't
*respect the production or another error if a
*lower level error occured.
*/
static enum CRStatus
{
*tmp_char_ptr2 = NULL;
&& a_unicode, CR_BAD_PARAM_ERROR);
/*first, let's backup the current position pointer */
if (cur_char != '\\') {
goto error;
}
if (a_location) {
(a_this, a_location) ;
}
gint cur_char_val = 0;
}
}
if (occur == 5) {
/*
*the unicode escape is 6 digit length
*/
/*
*parse one space that may
*appear just after the unicode
*escape.
*/
&tmp_char_ptr2, NULL);
} else {
/*
*The unicode escape is less than
*6 digit length. The character
*that comes right after the escape
*must be a white space.
*/
&tmp_char_ptr2, NULL);
}
return CR_OK;
}
/*
*restore the initial position pointer backuped at
*the beginning of this function.
*/
return status;
}
/**
*parses an escape sequence as defined by the css spec:
*escape ::= {unicode}|\\[ -~\200-\4177777]
*@param a_this the current instance of #CRTknzr .
*/
static enum CRStatus
{
&& a_esc_code, CR_BAD_PARAM_ERROR);
if (next_chars[0] != '\\') {
goto error;
}
} else {
/*consume the '\' char */
if (a_location) {
a_location) ;
}
/*then read the char after the '\' */
goto error;
}
*a_esc_code = cur_char;
}
return CR_OK;
}
return status;
}
/**
*Parses a string type as defined in css spec [4.1.1]:
*
*string ::= {string1}|{string2}
*string1 ::= \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\"
*string2 ::= \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\'
*
*@param a_this the current instance of #CRTknzr.
*@param a_start out parameter. Upon successfull completion,
*points to the beginning of the string, points to an undefined value
*otherwise.
*@param a_end out parameter. Upon successfull completion, points to
*the beginning of the string, points to an undefined value otherwise.
*@return CR_OK upon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
delim = 0;
&& a_str, CR_BAD_PARAM_ERROR);
if (cur_char == '"')
delim = '"';
else if (cur_char == '\'')
delim = '\'';
else {
goto error;
}
str = cr_string_new ();
if (str) {
}
for (;;) {
if (next_chars[0] == '\\') {
*tmp_char_ptr2 = NULL;
next_chars[1]);
} else {
esc_code);
}
}
/*
*consume the '\' char, and try to parse
*a newline.
*/
(a_this, &tmp_char_ptr1,
&tmp_char_ptr2, NULL);
}
cur_char);
}
else if (cr_utils_is_nonascii (next_chars[0])) {
} else if (next_chars[0] == delim) {
break;
} else {
goto error;
}
}
} else {
}
return CR_OK;
}
if (str) {
cr_string_destroy (str) ;
}
return status;
}
/**
*Parses the an nmstart as defined by the css2 spec [4.1.1]:
* nmstart [a-zA-Z]|{nonascii}|{escape}
*
*@param a_this the current instance of #CRTknzr.
*@param a_start out param. A pointer to the starting point of
*the token.
*@param a_end out param. A pointer to the ending point of the
*token.
*@param a_char out param. The actual parsed nmchar.
*@return CR_OK upon successfull completion,
*an error code otherwise.
*/
static enum CRStatus
{
next_char = 0;
&& a_char, CR_BAD_PARAM_ERROR);
if (next_char == '\\') {
goto error;
) {
if (a_location) {
a_location) ;
}
} else {
goto error;
}
return CR_OK;
return status;
}
/**
*Parses an nmchar as described in the css spec at
*chap 4.1.1:
*nmchar ::= [a-z0-9-]|{nonascii}|{escape}
*
*Humm, I have added the possibility for nmchar to
*contain upper case letters.
*
*@param a_this the current instance of #CRTknzr.
*@param a_start out param. A pointer to the starting point of
*the token.
*@param a_end out param. A pointer to the ending point of the
*token.
*@param a_char out param. The actual parsed nmchar.
*@return CR_OK upon successfull completion,
*an error code otherwise.
*/
static enum CRStatus
{
next_char = 0;
&next_char) ;
goto error;
if (next_char == '\\') {
goto error;
|| (next_char == '-')
) {
if (a_location) {
(a_this, a_location) ;
}
} else {
goto error;
}
return CR_OK;
return status;
}
/**
*Parses an "ident" as defined in css spec [4.1.1]:
*ident ::= {nmstart}{nmchar}*
*
*Actually parses it using the css3 grammar:
*ident ::= -?{nmstart}{nmchar}*
*@param a_this the currens instance of #CRTknzr.
*
*@param a_str a pointer to parsed ident. If *a_str is NULL,
*this function allocates a new instance of CRString. If not,
*the function just appends the parsed string to the one passed.
*In both cases it is up to the caller to free *a_str.
*
*@return CR_OK upon successfull completion, an error code
*otherwise.
*/
static enum CRStatus
{
&& a_str, CR_BAD_PARAM_ERROR);
stringue = cr_string_new () ;
if (tmp_char == '-') {
location_is_set = TRUE ;
tmp_char) ;
}
goto end ;
}
if (location_is_set == FALSE) {
location_is_set = TRUE ;
}
for (;;) {
&tmp_char,
NULL);
break;
}
}
if (!*a_str) {
} else {
}
}
end:
if (stringue) {
}
}
return status ;
}
/**
*Parses a "name" as defined by css spec [4.1.1]:
*name ::= {nmchar}+
*
*@param a_this the current instance of #CRTknzr.
*
*@param a_str out parameter. A pointer to the successfully parsed
*name. If *a_str is set to NULL, this function allocates a new instance
*of CRString. If not, it just appends the parsed name to the passed *a_str.
*In both cases, it is up to the caller to free *a_str.
*
*@return CR_OK upon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
glong i = 0;
CRParsingLocation loc = {0,0,0} ;
&& a_str,
*a_str = cr_string_new ();
}
for (i = 0;; i++) {
if (is_first_nmchar == TRUE) {
&loc) ;
is_first_nmchar = FALSE ;
} else {
}
break;
tmp_char);
}
if (i > 0) {
return CR_OK;
}
}
return CR_PARSING_ERROR;
}
/**
*Parses a "hash" as defined by the css spec in [4.1.1]:
*HASH ::= #{name}
*/
static enum CRStatus
{
CRParsingLocation loc = {0,0,0} ;
if (cur_char != '#') {
goto error;
}
*a_str = cr_string_new ();
}
&loc) ;
goto error;
}
return CR_OK;
}
return status;
}
/**
*Parses an uri as defined by the css spec [4.1.1]:
* URI ::= url\({w}{string}{w}\)
* |url\({w}([!#$%&*-~]|{nonascii}|{escape})*{w}\)
*
*@param a_this the current instance of #CRTknzr.
*@param a_str the successfully parsed url.
*@return CR_OK upon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
CRParsingLocation location = {0,0,0} ;
&& a_str,
goto error;
}
/*
*Here, we want to skip 4 bytes ('u''r''l''(').
*But we also need to keep track of the parsing location
*of the 'u'. So, we skip 1 byte, we record the parsing
*location, then we skip the 3 remaining bytes.
*/
if (next_char == ')') {
} else {
}
}
str = cr_string_new ();
for (;;) {
} else {
esc_code);
} else {
break;
}
}
}
if (cur_char == ')') {
} else {
goto error;
}
if (str) {
} else {
}
}
}
&location) ;
return CR_OK ;
if (str) {
}
return status;
}
/**
*parses an RGB as defined in the css2 spec.
*rgb: rgb '('S*{num}%?S* ',' {num}#?S*,S*{num}#?S*')'
*
*@param a_this the "this pointer" of the current instance of
*@param a_rgb out parameter the parsed rgb.
*@return CR_OK upon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
green = 0,
blue = 0,
i = 0;
CRParsingLocation location = {0,0,0} ;
} else {
goto error;
}
if (next_bytes[0] == '%') {
}
for (i = 0; i < 2; i++) {
if (next_bytes[0] == '%') {
is_percentage = 1;
}
if (i == 0) {
} else if (i == 1) {
}
if (num) {
}
}
goto error;
}
} else {
}
&location) ;
}
return CR_OK;
}
if (num) {
}
return CR_OK;
}
/**
*Parses a atkeyword as defined by the css spec in [4.1.1]:
*ATKEYWORD ::= @{ident}
*
*@param a_this the "this pointer" of the current instance of
*#CRTknzr.
*
*@param a_str out parameter. The parsed atkeyword. If *a_str is
*set to NULL this function allocates a new instance of CRString and
*sets it to the parsed atkeyword. If not, this function just appends
*the parsed atkeyword to the end of *a_str. In both cases it is up to
*the caller to free *a_str.
*
*@return CR_OK upon successfull completion, an error code otherwise.
*/
static enum CRStatus
{
&& a_str, CR_BAD_PARAM_ERROR);
if (cur_char != '@') {
goto error;
}
*a_str = cr_string_new ();
}
goto error;
}
return CR_OK;
}
return status;
}
static enum CRStatus
{
if (a_location) {
a_location) ;
}
if (a_location) {
a_location) ;
}
return CR_OK;
} else {
}
return status;
}
/**
*Parses a num as defined in the css spec [4.1.1]:
*[0-9]+|[0-9]*\.[0-9]+
*@param a_this the current instance of #CRTknzr.
*@param a_num out parameter. The parsed number.
*@return CR_OK upon successfull completion,
*an error code otherwise.
*/
static enum CRStatus
{
parsed; /* true iff the substring seen so far is a valid CSS
number, i.e. `[0-9]+|[0-9]*\.[0-9]+'. */
next_char = 0;
CRParsingLocation location = {0,0,0} ;
parsing_dec = FALSE;
} else if (cur_char == '.') {
numerator = 0;
parsing_dec = TRUE;
} else {
goto error;
}
for (;;) {
if (status == CR_END_OF_INPUT_ERROR)
break;
}
if (next_char == '.') {
if (parsing_dec) {
goto error;
}
parsing_dec = TRUE;
one digit after `.'. */
if (parsing_dec) {
denominator *= 10;
}
} else {
break;
}
}
if (!parsed) {
}
/*
*Now, set the output param values.
*/
goto error;
}
} else {
}
&location) ;
return CR_OK;
}
return status;
}
/*********************************************
*PUBLIC methods
********************************************/
CRTknzr *
{
cr_utils_trace_info ("Out of memory");
return NULL;
}
cr_utils_trace_info ("Out of memory");
if (result) {
}
return NULL;
}
if (a_input)
return result;
}
CRTknzr *
enum CREncoding a_enc,
{
return result;
}
CRTknzr *
enum CREncoding a_enc)
{
return result;
}
void
{
}
{
}
return TRUE;
}
return FALSE;
}
enum CRStatus
{
}
return CR_OK;
}
enum CRStatus
{
return CR_OK;
}
/*********************************
*Tokenizer input handling routines
*********************************/
/**
*Reads the next byte from the parser input stream.
*@param a_this the "this pointer" of the current instance of
*#CRParser.
*@param a_byte out parameter the place where to store the byte
*read.
*@return CR_OK upon successfull completion, an error
*code otherwise.
*/
enum CRStatus
{
}
/**
*Reads the next char from the parser input stream.
*@param a_this the current instance of #CRTknzr.
*@param a_char out parameter. The read char.
*@return CR_OK upon successfull completion, an error code
*otherwise.
*/
enum CRStatus
{
&& a_char, CR_BAD_PARAM_ERROR);
}
}
/**
*Peeks a char from the parser input stream.
*To "peek a char" means reads the next char without consuming it.
*Subsequent calls to this function return the same char.
*@param a_this the current instance of #CRTknzr.
*@param a_char out parameter. The peeked char uppon successfull completion.
*@return CR_OK upon successfull completion, an error code otherwise.
*/
enum CRStatus
{
&& a_char, CR_BAD_PARAM_ERROR);
}
}
/**
*Peeks a byte ahead at a given postion in the parser input stream.
*@param a_this the current instance of #CRTknzr.
*@param a_offset the offset of the peeked byte starting from the current
*byte in the parser input stream.
*@param a_byte out parameter. The peeked byte upon
*successfull completion.
*@return CR_OK upon successfull completion, an error code otherwise.
*/
enum CRStatus
{
}
}
/**
*Same as cr_tknzr_peek_byte() but this api returns the byte peeked.
*@param a_this the current instance of #CRTknzr.
*@param a_offset the offset of the peeked byte starting from the current
*byte in the parser input stream.
*@param a_eof out parameter. If not NULL, is set to TRUE if we reached end of
*file, FALE otherwise. If the caller sets it to NULL, this parameter
*is just ignored.
*@return the peeked byte.
*/
{
}
/**
*Gets the number of bytes left in the topmost input stream
*associated to this parser.
*@param a_this the current instance of #CRTknzr
*@return the number of bytes left or -1 in case of error.
*/
{
}
}
enum CRStatus
{
&& a_pos, CR_BAD_PARAM_ERROR);
}
}
enum CRStatus
{
&& a_loc,
}
enum CRStatus
{
}
}
enum CRStatus
{
}
}
enum CRStatus
{
}
}
enum CRStatus
{
}
}
enum CRStatus
{
return CR_OK;
}
/**
*Returns the next token of the input stream.
*This method is really central. Each parsing
*method calls it.
*@param a_this the current tokenizer.
*@param a_tk out parameter. The returned token.
*for the sake of mem leak avoidance, *a_tk must
*be NULL.
*@param CR_OK upon successfull completion, an error code
*otherwise.
*/
enum CRStatus
{
CRParsingLocation location = {0,0,0} ;
return CR_OK;
}
if (reached_eof == TRUE) {
goto error;
}
token = cr_token_new ();
switch (next_char) {
case '@':
{
&location) ;
goto done;
}
&location) ;
goto done;
}
&location) ;
goto done;
}
&location) ;
&location) ;
goto done;
}
&location) ;
&location) ;
goto done;
}
if (str) {
}
goto done;
}
}
break;
case 'u':
if (str) {
}
goto done;
}
} else {
if (str) {
}
goto done;
}
}
break;
case 'r':
if (rgb) {
}
goto done;
}
} else {
if (str) {
}
goto done;
}
}
break;
case '<':
&location) ;
&location) ;
goto done;
}
break;
case '-':
&location) ;
&location) ;
goto done;
} else {
if (str) {
}
goto done;
}
}
break;
case '~':
&location) ;
&location) ;
goto done;
}
break;
case '|':
&location) ;
&location) ;
goto done;
}
break;
case '/':
if (str) {
}
goto done;
}
}
break ;
case ';':
&location) ;
&location) ;
goto done;
case '{':
&location) ;
&location) ;
goto done;
case '}':
&location) ;
&location) ;
goto done;
case '(':
&location) ;
&location) ;
goto done;
case ')':
&location) ;
&location) ;
goto done;
case '[':
&location) ;
&location) ;
goto done;
case ']':
&location) ;
&location) ;
goto done;
case ' ':
case '\t':
case '\n':
case '\f':
case '\r':
{
&location) ;
goto done;
}
}
break;
case '#':
{
if (str) {
}
goto done;
}
}
break;
case '\'':
case '"':
if (str) {
}
goto done;
}
break;
case '!':
&location) ;
goto done;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
{
if (next_bytes[0] == 'e'
num);
} else if (next_bytes[0] == 'e'
num);
} else if (next_bytes[0] == 'p'
} else if (next_bytes[0] == 'c'
} else if (next_bytes[0] == 'm'
} else if (next_bytes[0] == 'i'
} else if (next_bytes[0] == 'p'
} else if (next_bytes[0] == 'p'
} else if (next_bytes[0] == 'd'
} else if (next_bytes[0] == 'r'
} else if (next_bytes[0] == 'g'
} else if (next_bytes[0] == 'm'
} else if (next_bytes[0] == 's') {
} else if (next_bytes[0] == 'H'
} else if (next_bytes[0] == 'k'
} else if (next_bytes[0] == '%') {
} else {
&str);
TRUE);
} else {
}
}
} else {
}
goto done ;
}
}
break;
default:
/*process the fallback cases here */
if (next_char == '\\'
/*ownership is transfered
*to token by cr_token_set_function.
*/
if (str) {
}
} else {
str);
if (str) {
}
}
goto done;
} else {
if (str) {
}
}
}
break;
}
&location) ;
&location) ;
done:
/*
*store the previous position input stream pos.
*/
&init_pos, sizeof (CRInputPos));
return CR_OK;
}
if (token) {
}
if (str) {
}
return status;
}
enum CRStatus
{
&& a_res, CR_BAD_PARAM_ERROR);
return status;
return CR_PARSING_ERROR;
switch (a_type) {
case NO_TK:
case S_TK:
case CDO_TK:
case CDC_TK:
case INCLUDES_TK:
case DASHMATCH_TK:
case IMPORT_SYM_TK:
case PAGE_SYM_TK:
case MEDIA_SYM_TK:
case FONT_FACE_SYM_TK:
case CHARSET_SYM_TK:
case IMPORTANT_SYM_TK:
break;
case STRING_TK:
case IDENT_TK:
case HASH_TK:
case ATKEYWORD_TK:
case FUNCTION_TK:
case COMMENT_TK:
case URI_TK:
break;
case EMS_TK:
case EXS_TK:
case PERCENTAGE_TK:
case NUMBER_TK:
break;
case LENGTH_TK:
case ANGLE_TK:
case TIME_TK:
case FREQ_TK:
}
break;
case DIMEN_TK:
if (a_extra_res == NULL) {
goto error;
}
break;
case DELIM_TK:
break;
case UNICODERANGE_TK:
default:
break;
}
} else {
}
return status;
if (token) {
}
return status;
}
void
{
== TRUE) {
}
}
}
}
}