| 1328 | } |
| 1329 | |
| 1330 | CPreprocessor::Token CPreprocessor::Parse( const Token &iSource ) |
| 1331 | { |
| 1332 | Source = iSource.String; |
| 1333 | SourceEnd = Source + iSource.Length; |
| 1334 | Line = 1; |
| 1335 | BOL = true; |
| 1336 | EnableOutput = 1; |
| 1337 | |
| 1338 | // Accumulate output into this token |
| 1339 | Token output( Token::TK_TEXT ); |
| 1340 | int empty_lines = 0; |
| 1341 | |
| 1342 | // Enable output only if all embedded #if's were true |
| 1343 | bool old_output_enabled = true; |
| 1344 | bool output_enabled = true; |
| 1345 | int output_disabled_line = 0; |
| 1346 | |
| 1347 | while( Source < SourceEnd ) |
| 1348 | { |
| 1349 | int old_line = Line; |
| 1350 | Token t = GetToken( true ); |
| 1351 | |
| 1352 | NextToken: |
| 1353 | switch( t.Type ) |
| 1354 | { |
| 1355 | case Token::TK_ERROR: |
| 1356 | return t; |
| 1357 | |
| 1358 | case Token::TK_EOS: |
| 1359 | return output; // Force termination |
| 1360 | |
| 1361 | case Token::TK_COMMENT: |
| 1362 | // C comments are replaced with single spaces. |
| 1363 | if( output_enabled ) |
| 1364 | { |
| 1365 | output.Append( " ", 1 ); |
| 1366 | output.AppendNL( Line - old_line ); |
| 1367 | } |
| 1368 | break; |
| 1369 | |
| 1370 | case Token::TK_LINECOMMENT: |
| 1371 | // C++ comments are ignored |
| 1372 | continue; |
| 1373 | |
| 1374 | case Token::TK_DIRECTIVE: |
| 1375 | // Handle preprocessor directives |
| 1376 | t = HandleDirective( t, old_line ); |
| 1377 | |
| 1378 | output_enabled = ( ( EnableOutput & ( EnableOutput + 1 ) ) == 0 ); |
| 1379 | if( output_enabled != old_output_enabled ) |
| 1380 | { |
| 1381 | if( output_enabled ) |
| 1382 | output.AppendNL( old_line - output_disabled_line ); |
| 1383 | else |
| 1384 | output_disabled_line = old_line; |
| 1385 | old_output_enabled = output_enabled; |
| 1386 | } |
| 1387 | |