| 273 | } |
| 274 | |
| 275 | CPreprocessor::Token CPreprocessor::GetToken( bool iExpand ) |
| 276 | { |
| 277 | if( Source >= SourceEnd ) |
| 278 | return Token( Token::TK_EOS ); |
| 279 | |
| 280 | const char *begin = Source; |
| 281 | char c = *Source++; |
| 282 | |
| 283 | if( c == '\n' || ( c == '\r' && *Source == '\n' ) ) |
| 284 | { |
| 285 | Line++; |
| 286 | BOL = true; |
| 287 | if( c == '\r' ) |
| 288 | Source++; |
| 289 | return Token( Token::TK_NEWLINE, begin, static_cast<size_t>( Source - begin ) ); |
| 290 | } |
| 291 | else if( isspace( c ) ) |
| 292 | { |
| 293 | while( Source < SourceEnd && *Source != '\r' && *Source != '\n' && isspace( *Source ) ) |
| 294 | Source++; |
| 295 | |
| 296 | return Token( Token::TK_WHITESPACE, begin, static_cast<size_t>( Source - begin ) ); |
| 297 | } |
| 298 | else if( isdigit( c ) ) |
| 299 | { |
| 300 | BOL = false; |
| 301 | if( c == '0' && Source < SourceEnd && Source[0] == 'x' ) // hex numbers |
| 302 | { |
| 303 | Source++; |
| 304 | while( Source < SourceEnd && isxdigit( *Source ) ) |
| 305 | Source++; |
| 306 | } |
| 307 | else |
| 308 | while( Source < SourceEnd && isdigit( *Source ) ) |
| 309 | Source++; |
| 310 | return Token( Token::TK_NUMBER, begin, static_cast<size_t>( Source - begin ) ); |
| 311 | } |
| 312 | else if( c == '_' || isalnum( c ) ) |
| 313 | { |
| 314 | BOL = false; |
| 315 | while( Source < SourceEnd && ( *Source == '_' || isalnum( *Source ) ) ) |
| 316 | Source++; |
| 317 | Token t( Token::TK_KEYWORD, begin, static_cast<size_t>( Source - begin ) ); |
| 318 | if( iExpand ) |
| 319 | t = ExpandMacro( t ); |
| 320 | return t; |
| 321 | } |
| 322 | else if( c == '"' || c == '\'' ) |
| 323 | { |
| 324 | BOL = false; |
| 325 | while( Source < SourceEnd && *Source != c ) |
| 326 | { |
| 327 | if( *Source == '\\' ) |
| 328 | { |
| 329 | Source++; |
| 330 | if( Source >= SourceEnd ) |
| 331 | break; |
| 332 | } |
no test coverage detected