00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
#include "compiler_defines.h"
00030
#include "astyle.h"
00031
00032
#include <string>
00033
#include <cctype>
00034
#include <vector>
00035
#include <algorithm>
00036
#include <iostream>
00037
00038
00039 #define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); }
00040 #define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container) ; }
00041 #define IS_A(a,b) ( ((a) & (b)) == (b))
00042
#ifdef USES_NAMESPACE
00043
using namespace std;
00044
00045
namespace astyle {
00046
#endif
00047
00048
00049 bool ASFormatter::calledInitStatic =
false;
00050 vector<const string*> ASFormatter::headers;
00051 vector<const string*> ASFormatter::nonParenHeaders;
00052 vector<const string*> ASFormatter::preprocessorHeaders;
00053 vector<const string*> ASFormatter::preDefinitionHeaders;
00054 vector<const string*> ASFormatter::preCommandHeaders;
00055 vector<const string*> ASFormatter::operators;
00056 vector<const string*> ASFormatter::assignmentOperators;
00057
00061 ASFormatter::ASFormatter() {
00062
staticInit();
00063
00064
preBracketHeaderStack = NULL;
00065
bracketTypeStack = NULL;
00066
parenStack = NULL;
00067
00068
sourceIterator = NULL;
00069
bracketFormatMode =
NONE_MODE;
00070
shouldPadOperators =
false;
00071
shouldPadParenthesies =
false;
00072
shouldBreakOneLineBlocks =
true;
00073
shouldBreakOneLineStatements =
true;
00074
shouldConvertTabs =
false;
00075
shouldBreakBlocks =
false;
00076
shouldBreakClosingHeaderBlocks =
false;
00077
shouldBreakClosingHeaderBrackets =
false;
00078
shouldBreakElseIfs =
false;
00079 }
00080
00084 ASFormatter::~ASFormatter() {
00085
DELETE_CONTAINER(
preBracketHeaderStack );
00086 }
00087
00091 void ASFormatter::staticInit() {
00092
if (
calledInitStatic)
00093
return;
00094
00095
calledInitStatic =
true;
00096
00097
headers.push_back(&AS_IF);
00098
headers.push_back(&AS_ELSE);
00099
headers.push_back(&AS_DO);
00100
headers.push_back(&AS_WHILE);
00101
headers.push_back(&AS_FOR);
00102
headers.push_back(&AS_SYNCHRONIZED);
00103
headers.push_back(&AS_TRY);
00104
headers.push_back(&AS_CATCH);
00105
headers.push_back(&AS_FINALLY);
00106
headers.push_back(&AS_SWITCH);
00107
headers.push_back(&AS_TEMPLATE);
00108
headers.push_back(&AS_FOREACH);
00109
headers.push_back(&AS_LOCK);
00110
headers.push_back(&AS_UNSAFE);
00111
headers.push_back(&AS_FIXED);
00112
headers.push_back(&AS_GET);
00113
headers.push_back(&AS_SET);
00114
headers.push_back(&AS_ADD);
00115
headers.push_back(&AS_REMOVE);
00116
00117
nonParenHeaders.push_back(&AS_ELSE);
00118
nonParenHeaders.push_back(&AS_DO);
00119
nonParenHeaders.push_back(&AS_TRY);
00120
nonParenHeaders.push_back(&AS_FINALLY);
00121
nonParenHeaders.push_back(&AS_UNSAFE);
00122
nonParenHeaders.push_back(&AS_GET);
00123
nonParenHeaders.push_back(&AS_SET);
00124
nonParenHeaders.push_back(&AS_ADD);
00125
nonParenHeaders.push_back(&AS_REMOVE);
00126
00127
00128
00129
preDefinitionHeaders.push_back(&AS_CLASS);
00130
preDefinitionHeaders.push_back(&AS_INTERFACE);
00131
preDefinitionHeaders.push_back(&AS_NAMESPACE);
00132
preDefinitionHeaders.push_back(&AS_STRUCT);
00133
00134
preCommandHeaders.push_back(&AS_EXTERN);
00135
preCommandHeaders.push_back(&AS_THROWS);
00136
preCommandHeaders.push_back(&AS_CONST);
00137
00138
preprocessorHeaders.push_back(&AS_BAR_DEFINE);
00144
00145 operators.push_back(&AS_PLUS_ASSIGN);
00146 operators.push_back(&AS_MINUS_ASSIGN);
00147 operators.push_back(&AS_MULT_ASSIGN);
00148 operators.push_back(&AS_DIV_ASSIGN);
00149 operators.push_back(&AS_MOD_ASSIGN);
00150 operators.push_back(&AS_OR_ASSIGN);
00151 operators.push_back(&AS_AND_ASSIGN);
00152 operators.push_back(&AS_XOR_ASSIGN);
00153 operators.push_back(&AS_EQUAL);
00154 operators.push_back(&AS_PLUS_PLUS);
00155 operators.push_back(&AS_MINUS_MINUS);
00156 operators.push_back(&AS_NOT_EQUAL);
00157 operators.push_back(&AS_GR_EQUAL);
00158 operators.push_back(&AS_GR_GR_GR_ASSIGN);
00159 operators.push_back(&AS_GR_GR_ASSIGN);
00160 operators.push_back(&AS_GR_GR_GR);
00161 operators.push_back(&AS_GR_GR);
00162 operators.push_back(&AS_LS_EQUAL);
00163 operators.push_back(&AS_LS_LS_LS_ASSIGN);
00164 operators.push_back(&AS_LS_LS_ASSIGN);
00165 operators.push_back(&AS_LS_LS_LS);
00166 operators.push_back(&AS_LS_LS);
00167 operators.push_back(&AS_ARROW);
00168 operators.push_back(&AS_AND);
00169 operators.push_back(&AS_OR);
00170 operators.push_back(&AS_COLON_COLON);
00171
00175
00176 operators.push_back(&AS_PLUS);
00177 operators.push_back(&AS_MINUS);
00178 operators.push_back(&AS_MULT);
00179 operators.push_back(&AS_DIV);
00180 operators.push_back(&AS_MOD);
00181 operators.push_back(&AS_QUESTION);
00182 operators.push_back(&AS_COLON);
00183 operators.push_back(&AS_ASSIGN);
00184 operators.push_back(&AS_LS);
00185 operators.push_back(&AS_GR);
00186 operators.push_back(&AS_NOT);
00187 operators.push_back(&AS_BIT_OR);
00188 operators.push_back(&AS_BIT_AND);
00189 operators.push_back(&AS_BIT_NOT);
00190 operators.push_back(&AS_BIT_XOR);
00191 operators.push_back(&AS_OPERATOR);
00192 operators.push_back(&AS_COMMA);
00193
00194 operators.push_back(&AS_RETURN);
00195
00196
assignmentOperators.push_back(&AS_PLUS_ASSIGN);
00197
assignmentOperators.push_back(&AS_MINUS_ASSIGN);
00198
assignmentOperators.push_back(&AS_MULT_ASSIGN);
00199
assignmentOperators.push_back(&AS_DIV_ASSIGN);
00200
assignmentOperators.push_back(&AS_MOD_ASSIGN);
00201
assignmentOperators.push_back(&AS_XOR_ASSIGN);
00202
assignmentOperators.push_back(&AS_OR_ASSIGN);
00203
assignmentOperators.push_back(&AS_AND_ASSIGN);
00204
assignmentOperators.push_back(&AS_GR_GR_GR_ASSIGN);
00205
assignmentOperators.push_back(&AS_LS_LS_LS_ASSIGN);
00206
assignmentOperators.push_back(&AS_ASSIGN);
00207 }
00208
00221 void ASFormatter::init(
ASSourceIterator *si) {
00222 ASBeautifier::init(si);
00223
sourceIterator = si;
00224
00225
INIT_CONTAINER(
preBracketHeaderStack,
new vector<const string*> );
00226
INIT_CONTAINER(
bracketTypeStack,
new vector<BracketType> );
00227
bracketTypeStack->push_back(
DEFINITION_TYPE);
00228
INIT_CONTAINER(
parenStack,
new vector<int> );
00229
parenStack->push_back(0);
00230
00231
currentHeader = NULL;
00232
currentLine = string(
"");
00233
formattedLine =
"";
00234
currentChar =
' ';
00235
previousCommandChar =
' ';
00236
previousNonWSChar =
' ';
00237
quoteChar =
'"';
00238
charNum = 0;
00239
previousOperator = NULL;
00240
00241
isVirgin =
true;
00242
isInLineComment =
false;
00243
isInComment =
false;
00244
isInPreprocessor =
false;
00245
doesLineStartComment =
false;
00246
isInQuote =
false;
00247
isSpecialChar =
false;
00248
isNonParenHeader =
true;
00249
foundPreDefinitionHeader =
false;
00250
foundPreCommandHeader =
false;
00251
foundQuestionMark =
false;
00252
isInLineBreak =
false;
00253
endOfCodeReached =
false;
00254
isLineReady =
false;
00255
isPreviousBracketBlockRelated =
true;
00256
isInPotentialCalculation =
false;
00257
00258
shouldReparseCurrentChar =
false;
00259
passedSemicolon =
false;
00260
passedColon =
false;
00261
isInTemplate =
false;
00262
shouldBreakLineAfterComments =
false;
00263
isImmediatelyPostComment =
false;
00264
isImmediatelyPostLineComment =
false;
00265
isImmediatelyPostEmptyBlock =
false;
00266
00267
isPrependPostBlockEmptyLineRequested =
false;
00268
isAppendPostBlockEmptyLineRequested =
false;
00269
prependEmptyLine =
false;
00270
00271
foundClosingHeader =
false;
00272
previousReadyFormattedLineLength = 0;
00273
00274
isImmediatelyPostHeader =
false;
00275
isInHeader =
false;
00276 }
00277
00284 string ASFormatter::nextLine() {
00285
const string *newHeader;
00286
bool isCharImmediatelyPostComment =
false;
00287
bool isPreviousCharPostComment =
false;
00288
bool isCharImmediatelyPostLineComment =
false;
00289
bool isInVirginLine =
isVirgin;
00290
bool isCharImmediatelyPostOpenBlock =
false;
00291
bool isCharImmediatelyPostCloseBlock =
false;
00292
bool isCharImmediatelyPostTemplate =
false;
00293
bool isCharImmediatelyPostHeader =
false;
00294
00295
if (!
isFormattingEnabled())
00296
return ASBeautifier::nextLine();
00297
00298
while (!
isLineReady) {
00299
if (
shouldReparseCurrentChar)
00300
shouldReparseCurrentChar =
false;
00301
else if (!
getNextChar()) {
00302
breakLine();
00303
return beautify(
readyFormattedLine);
00304 }
else
00305 {
00306
00307
if (isInVirginLine &&
currentChar ==
'{')
00308
previousCommandChar =
'{';
00309 isPreviousCharPostComment = isCharImmediatelyPostComment;
00310 isCharImmediatelyPostComment =
false;
00311 isCharImmediatelyPostTemplate =
false;
00312 isCharImmediatelyPostHeader =
false;
00313 }
00314
00315
if (
isInLineComment) {
00316
appendCurrentChar();
00317
00318
00319
if (
charNum+1 == (
int)
currentLine.length()) {
00320
isInLineBreak =
true;
00321
isInLineComment =
false;
00322
isImmediatelyPostLineComment =
true;
00323
currentChar = 0;
00324 }
00325
00326
00327
00328
continue;
00329 }
else if (
isInComment) {
00330
if (
isSequenceReached(AS_CLOSE_COMMENT)) {
00331
isInComment =
false;
00332
isImmediatelyPostComment =
true;
00333
appendSequence(AS_CLOSE_COMMENT);
00334
goForward(1);
00335 }
else
00336
appendCurrentChar();
00337
00338
continue;
00339 }
00340
00341
00342
00343
else if (
isInQuote) {
00344
if (
isSpecialChar) {
00345
isSpecialChar =
false;
00346
appendCurrentChar();
00347 }
else if (
currentChar ==
'\\') {
00348
isSpecialChar =
true;
00349
appendCurrentChar();
00350 }
else if (
quoteChar ==
currentChar) {
00351
isInQuote =
false;
00352
appendCurrentChar();
00353 }
else {
00354
appendCurrentChar();
00355 }
00356
00357
continue;
00358 }
00359
00360
00361
00362
00363
if (isWhiteSpace(
currentChar) ||
isInPreprocessor) {
00365
appendCurrentChar();
00366
continue;
00367 }
00368
00369
00370
00371
if (
isSequenceReached(AS_OPEN_LINE_COMMENT)) {
00372
isInLineComment =
true;
00373
if (
shouldPadOperators)
00374
appendSpacePad();
00375
appendSequence(AS_OPEN_LINE_COMMENT);
00376
goForward(1);
00377
continue;
00378 }
else if (
isSequenceReached(AS_OPEN_COMMENT)) {
00379
isInComment =
true;
00380
if (
shouldPadOperators)
00381
appendSpacePad();
00382
appendSequence(AS_OPEN_COMMENT);
00383
goForward(1);
00384
continue;
00385 }
else if (
currentChar ==
'"' ||
currentChar ==
'\'') {
00386
isInQuote =
true;
00387
quoteChar =
currentChar;
00390
appendCurrentChar();
00391
continue;
00392 }
00393
00394
00395
00396
00397
00398
00399
if (
currentChar ==
'#')
00400
isInPreprocessor =
true;
00401
00402
if (
isInPreprocessor) {
00403
appendCurrentChar();
00404
continue;
00405 }
00406
00407
00408
00409
if (
isImmediatelyPostComment) {
00410
isImmediatelyPostComment =
false;
00411 isCharImmediatelyPostComment =
true;
00412 }
00413
00414
if (
isImmediatelyPostLineComment) {
00415
isImmediatelyPostLineComment =
false;
00416 isCharImmediatelyPostLineComment =
true;
00417 }
00418
00419
if (
shouldBreakLineAfterComments) {
00420
shouldBreakLineAfterComments =
false;
00421
shouldReparseCurrentChar =
true;
00422
breakLine();
00423
continue;
00424 }
00425
00426
00427
if (
isImmediatelyPostHeader) {
00428
isImmediatelyPostHeader =
false;
00429 isCharImmediatelyPostHeader =
true;
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
if (
shouldBreakOneLineStatements) {
00440
00441
00442
if (
shouldBreakElseIfs)
00443
isInLineBreak =
true;
00444
00445
else {
00446
00447
00448
bool isInElseIf =
false;
00449
const string *upcomingHeader;
00450
00451 upcomingHeader =
findHeader(
headers);
00452
if (
currentHeader == &AS_ELSE && upcomingHeader == &AS_IF)
00453 isInElseIf =
true;
00454
00455
if (!isInElseIf)
00456
isInLineBreak =
true;
00457 }
00458
00459
00460
00461 }
00462 }
00463
00464
if (
passedSemicolon) {
00465
passedSemicolon =
false;
00466
if (
parenStack->back() == 0) {
00467
shouldReparseCurrentChar =
true;
00468
isInLineBreak =
true;
00469
continue;
00470 }
00471 }
00472
00473
if (
passedColon) {
00474
passedColon =
false;
00475
if (
parenStack->back() == 0) {
00476
shouldReparseCurrentChar =
true;
00477
isInLineBreak =
true;
00478
continue;
00479 }
00480 }
00481
00482
00483
00484
00485
if (!
isInTemplate &&
currentChar ==
'<') {
00486
int templateDepth = 0;
00487
const string *oper;
00488
for (
int i=
charNum;
00489 i< (
int)
currentLine.length();
00490 i += (oper ? oper->length() : 1) ) {
00491 oper = ASBeautifier::findHeader(
currentLine, i,
operators);
00492
00493
if (oper == &AS_LS) {
00494 templateDepth++;
00495 }
else if (oper == &AS_GR) {
00496 templateDepth--;
00497
if (templateDepth == 0) {
00498
00499
00500
isInTemplate =
true;
00501
break;
00502 }
00503 }
else if (oper == &AS_COMMA
00504 || oper == &AS_BIT_AND
00505 || oper == &AS_MULT
00506 || oper == &AS_COLON_COLON)
00507 {
00508
continue;
00509 }
else if (!isLegalNameChar(
currentLine[i]) && !isWhiteSpace(
currentLine[i])) {
00510
00511
00512
isInTemplate =
false;
00513
break;
00514 }
00515 }
00516 }
00517
00518
00519
00520
if (currentChar ==
'(' || currentChar ==
'[' || (
isInTemplate && currentChar ==
'<')) {
00521
parenStack->back()++;
00522 }
else if (currentChar ==
')' || currentChar ==
']' || (
isInTemplate && currentChar ==
'>')) {
00523
parenStack->back()--;
00524
if (
isInTemplate &&
parenStack->back() == 0) {
00525
isInTemplate =
false;
00526 isCharImmediatelyPostTemplate =
true;
00527 }
00528
00529
00530
00531
if (
isInHeader &&
parenStack->back() == 0) {
00532
isInHeader =
false;
00533
isImmediatelyPostHeader =
true;
00534 }
00535
00536 }
00537
00538
00539
00540
BracketType bracketType =
NULL_TYPE;
00541
00542
if (currentChar ==
'{') {
00543 bracketType =
getBracketType();
00544
foundPreDefinitionHeader =
false;
00545
foundPreCommandHeader =
false;
00546
00547
bracketTypeStack->push_back(bracketType);
00548
preBracketHeaderStack->push_back(
currentHeader);
00549
currentHeader = NULL;
00550
00551
isPreviousBracketBlockRelated = !
IS_A(bracketType,
ARRAY_TYPE);
00552 }
else if (currentChar ==
'}') {
00553
00554
00555
00556
00557
isAppendPostBlockEmptyLineRequested =
false;
00558
00559
if (!
bracketTypeStack->empty()) {
00560 bracketType =
bracketTypeStack->back();
00561
bracketTypeStack->pop_back();
00562
00563
isPreviousBracketBlockRelated = !
IS_A(bracketType,
ARRAY_TYPE);
00564 }
00565
00566
if (!
preBracketHeaderStack->empty()) {
00567
currentHeader =
preBracketHeaderStack->back();
00568
preBracketHeaderStack->pop_back();
00569 }
else
00570
currentHeader = NULL;
00571 }
00572
00573
if (!
IS_A(bracketType,
ARRAY_TYPE)) {
00574
00575
if (currentChar ==
'{') {
00576
parenStack->push_back(0);
00577 }
else if (currentChar ==
'}') {
00578
if (!
parenStack->empty()) {
00579
parenStack->pop_back();
00580 }
00581 }
00582
00583
if (
bracketFormatMode !=
NONE_MODE) {
00584
if (currentChar ==
'{') {
00585
if ( (
bracketFormatMode ==
ATTACH_MODE
00586 ||
bracketFormatMode ==
BDAC_MODE &&
bracketTypeStack->size()>=2
00587 &&
IS_A((*
bracketTypeStack)[
bracketTypeStack->size()-2],
COMMAND_TYPE) )
00588 && !isCharImmediatelyPostLineComment ) {
00589
appendSpacePad();
00590
if (!isCharImmediatelyPostComment
00591 &&
previousCommandChar !=
'{'
00592 &&
previousCommandChar !=
'}'
00593 &&
previousCommandChar !=
';')
00594
appendCurrentChar(
false);
00595
else
00596
appendCurrentChar(
true);
00597
continue;
00598 }
else if (
bracketFormatMode ==
BREAK_MODE
00599 ||
bracketFormatMode ==
BDAC_MODE &&
bracketTypeStack->size()>=2
00600 &&
IS_A((*
bracketTypeStack)[
bracketTypeStack->size()-2],
DEFINITION_TYPE)) {
00601
if (
shouldBreakOneLineBlocks || !
IS_A(bracketType,
SINGLE_LINE_TYPE) )
00602
breakLine();
00603
appendCurrentChar();
00604
continue;
00605 }
00606 }
else if (currentChar ==
'}') {
00607
00608
00609
00610
00611
if (
previousCommandChar ==
'{')
00612
isImmediatelyPostEmptyBlock =
true;
00613
00614
if ( (!(
previousCommandChar ==
'{' &&
isPreviousBracketBlockRelated) )
00615 && (
shouldBreakOneLineBlocks || !
IS_A(bracketType,
SINGLE_LINE_TYPE))
00616 && !
isImmediatelyPostEmptyBlock)
00617 {
00618
breakLine();
00619
appendCurrentChar();
00620 }
else {
00621
if (!isCharImmediatelyPostComment)
00622
isInLineBreak =
false;
00623
appendCurrentChar();
00624
if (
shouldBreakOneLineBlocks || !
IS_A(bracketType,
SINGLE_LINE_TYPE))
00625
shouldBreakLineAfterComments =
true;
00626 }
00627
00628
if (
shouldBreakBlocks) {
00629
isAppendPostBlockEmptyLineRequested =
true;
00630 }
00631
00632
continue;
00633 }
00634 }
00635 }
00636
00637
if ( ( (
previousCommandChar ==
'{'
00638 &&
isPreviousBracketBlockRelated)
00639
00640 || (
previousCommandChar ==
'}'
00641 && !
isImmediatelyPostEmptyBlock
00642 &&
isPreviousBracketBlockRelated
00643 && !isPreviousCharPostComment
00644 &&
peekNextChar() !=
' '))
00645
00646 && (
shouldBreakOneLineBlocks || !
IS_A(
bracketTypeStack->back(),
SINGLE_LINE_TYPE)) ) {
00647 isCharImmediatelyPostOpenBlock = (
previousCommandChar ==
'{');
00648 isCharImmediatelyPostCloseBlock = (previousCommandChar ==
'}');
00649
00650 previousCommandChar =
' ';
00651
isInLineBreak =
true;
00652 }
00653
00654
00655
00656
00657
00658
isImmediatelyPostEmptyBlock =
false;
00659
00660
00661
if (!
isInTemplate) {
00662
if ( (newHeader =
findHeader(
headers)) != NULL) {
00663
foundClosingHeader =
false;
00664
const string *previousHeader;
00665
00666
00667
if ( (newHeader == &AS_ELSE &&
currentHeader == &AS_IF)
00668 || (newHeader == &AS_WHILE && currentHeader == &AS_DO)
00669 || (newHeader == &AS_CATCH && currentHeader == &AS_TRY)
00670 || (newHeader == &AS_CATCH && currentHeader == &AS_CATCH)
00671 || (newHeader == &AS_FINALLY && currentHeader == &AS_TRY)
00672 || (newHeader == &AS_FINALLY && currentHeader == &AS_CATCH) )
00673
foundClosingHeader =
true;
00674
00675 previousHeader = currentHeader;
00676 currentHeader = newHeader;
00677
00678
00679
00680
00681
if (!
shouldBreakClosingHeaderBrackets &&
foundClosingHeader && (
bracketFormatMode ==
ATTACH_MODE || bracketFormatMode ==
BDAC_MODE) &&
previousNonWSChar ==
'}') {
00682
isInLineBreak =
false;
00683
appendSpacePad();
00684
00685
if (
shouldBreakBlocks)
00686
isAppendPostBlockEmptyLineRequested =
false;
00687 }
00688
00689
00690
if (newHeader == &AS_TEMPLATE) {
00691
isInTemplate =
true;
00692 }
00693
00694
00695
isNonParenHeader = ( find(
nonParenHeaders.begin(),
nonParenHeaders.end(),
00696 newHeader) !=
nonParenHeaders.end() );
00697
appendSequence(*currentHeader);
00698
goForward(currentHeader->length() - 1);
00699
00700
00701
if (
shouldPadOperators && !
isNonParenHeader)
00702
appendSpacePad();
00703
00704
00705
00706
00707
00708
00709
if (!(
foundClosingHeader && currentHeader == &AS_WHILE)) {
00710
isInHeader =
true;
00711
if (
isNonParenHeader) {
00712
isImmediatelyPostHeader =
true;
00713
isInHeader =
false;
00714 }
00715 }
00716
00717
if (currentHeader == &AS_IF && previousHeader == &AS_ELSE)
00718
isInLineBreak =
false;
00719
00720
if (
shouldBreakBlocks) {
00721
if (previousHeader == NULL
00722 && !
foundClosingHeader
00723 && !isCharImmediatelyPostOpenBlock) {
00724
isPrependPostBlockEmptyLineRequested =
true;
00725 }
00726
00727
if (currentHeader == &AS_ELSE
00728 || currentHeader == &AS_CATCH
00729 || currentHeader == &AS_FINALLY
00730 ||
foundClosingHeader) {
00731
isPrependPostBlockEmptyLineRequested =
false;
00732 }
00733
00734
if (
shouldBreakClosingHeaderBlocks
00735 && isCharImmediatelyPostCloseBlock) {
00736
isPrependPostBlockEmptyLineRequested =
true;
00737 }
00738
00739 }
00740
00741
continue;
00742 }
else if ( (newHeader = findHeader(
preDefinitionHeaders)) != NULL) {
00743
foundPreDefinitionHeader =
true;
00744
appendSequence(*newHeader);
00745
goForward(newHeader->length() - 1);
00746
00747
if (
shouldBreakBlocks)
00748
isPrependPostBlockEmptyLineRequested =
true;
00749
00750
continue;
00751 }
else if ( (newHeader = findHeader(
preCommandHeaders)) != NULL) {
00752
foundPreCommandHeader =
true;
00753
appendSequence(*newHeader);
00754
goForward(newHeader->length() - 1);
00755
00756
continue;
00757 }
00758 }
00759
00760
if (
previousNonWSChar ==
'}' || currentChar ==
';') {
00761
if (
shouldBreakOneLineStatements && currentChar ==
';'
00762 && (
shouldBreakOneLineBlocks || !
IS_A(
bracketTypeStack->back(),
SINGLE_LINE_TYPE))) {
00763
passedSemicolon =
true;
00764 }
00765
00766
if (
shouldBreakBlocks &&
currentHeader != NULL &&
parenStack->back() == 0) {
00767
isAppendPostBlockEmptyLineRequested =
true;
00768 }
00769
00770
if (currentChar !=
';')
00771
currentHeader = NULL;
00772
00773
foundQuestionMark =
false;
00774
foundPreDefinitionHeader =
false;
00775
foundPreCommandHeader =
false;
00776
isInPotentialCalculation =
false;
00777
00778 }
00779
00780
if (currentChar ==
':'
00781 &&
shouldBreakOneLineStatements
00782 && !
foundQuestionMark
00783 && !
foundPreDefinitionHeader
00784 &&
previousCommandChar !=
')'
00785 &&
previousChar !=
':'
00786 &&
peekNextChar() !=
':')
00787 {
00788
passedColon =
true;
00789
if (
shouldBreakBlocks)
00790
isPrependPostBlockEmptyLineRequested =
true;
00791 }
00792
00793
if (currentChar ==
'?')
00794
foundQuestionMark =
true;
00795
00796
if (
shouldPadOperators) {
00797
if ((newHeader =
findHeader(
operators)) != NULL) {
00798
bool shouldPad = (newHeader != &AS_COLON_COLON
00799 && newHeader != &AS_PAREN_PAREN
00800 && newHeader != &AS_BLPAREN_BLPAREN
00801 && newHeader != &AS_PLUS_PLUS
00802 && newHeader != &AS_MINUS_MINUS
00803 && newHeader != &AS_NOT
00804 && newHeader != &AS_BIT_NOT
00805 && newHeader != &AS_ARROW
00806 && newHeader != &AS_OPERATOR
00807 && !(newHeader == &AS_MINUS &&
isInExponent())
00808 && !(newHeader == &AS_PLUS &&
isInExponent())
00809 &&
previousOperator != &AS_OPERATOR
00810 && !((newHeader == &AS_MULT || newHeader == &AS_BIT_AND)
00811 &&
isPointerOrReference())
00812 && !( (
isInTemplate || isCharImmediatelyPostTemplate)
00813 && (newHeader == &AS_LS || newHeader == &AS_GR))
00814 );
00815
00816
if (!
isInPotentialCalculation)
00817
if (find(
assignmentOperators.begin(),
assignmentOperators.end(), newHeader)
00818 !=
assignmentOperators.end())
00819
isInPotentialCalculation =
true;
00820
00821
00822
if (shouldPad
00823 && !(newHeader == &AS_COLON && !
foundQuestionMark)
00824 && newHeader != &AS_SEMICOLON
00825 && newHeader != &AS_COMMA)
00826
appendSpacePad();
00827
appendSequence(*newHeader);
00828
goForward(newHeader->length() - 1);
00829
00830
00831
00832
if (newHeader == &AS_PAREN_PAREN
00833 || newHeader == &AS_BLPAREN_BLPAREN)
00834
parenStack->back()--;
00835
00836 currentChar = (*newHeader)[newHeader->length() - 1];
00837
00838
00839
if ( shouldPad && !(newHeader == &AS_MINUS &&
isUnaryMinus()) )
00840
appendSpacePad();
00841
00842
previousOperator = newHeader;
00843
continue;
00844 }
00845 }
00846
if (
shouldPadParenthesies) {
00847
if (currentChar ==
'(' || currentChar ==
'[' ) {
00848
char peekedChar =
peekNextChar();
00849
00850
isInPotentialCalculation =
true;
00851
appendCurrentChar();
00852
if (!(currentChar ==
'(' && peekedChar ==
')')
00853 && !(currentChar ==
'[' && peekedChar ==
']'))
00854
appendSpacePad();
00855
continue;
00856 }
else if (currentChar ==
')' || currentChar ==
']') {
00857
char peekedChar =
peekNextChar();
00858
00859
if (!(
previousChar ==
'(' && currentChar ==
')')
00860 && !(
previousChar ==
'[' && currentChar ==
']'))
00861
appendSpacePad();
00862
00863
appendCurrentChar();
00864
00865
if (peekedChar !=
';' && peekedChar !=
',' && peekedChar !=
'.'
00866 && !(currentChar ==
']' && peekedChar ==
'['))
00867
appendSpacePad();
00868
continue;
00869 }
00870 }
00871
00872
appendCurrentChar();
00873 }
00874
00875
00876
00877 string beautifiedLine;
00878
int readyFormattedLineLength = trim(
readyFormattedLine).length();
00879
00880
if (
prependEmptyLine
00881 && readyFormattedLineLength > 0
00882 &&
previousReadyFormattedLineLength > 0) {
00883
isLineReady =
true;
00884 beautifiedLine = beautify(
"");
00885 }
else {
00886
isLineReady =
false;
00887 beautifiedLine = beautify(
readyFormattedLine);
00888 }
00889
00890
prependEmptyLine =
false;
00891
previousReadyFormattedLineLength = readyFormattedLineLength;
00892
00893
return beautifiedLine;
00894
00895 }
00896
00897
00903 bool ASFormatter::hasMoreLines()
const {
00904
if (!
isFormattingEnabled())
00905
return ASBeautifier::hasMoreLines();
00906
else
00907
return !
endOfCodeReached;
00908 }
00909
00915 bool ASFormatter::isFormattingEnabled()
const {
00916
return (
bracketFormatMode !=
NONE_MODE
00917 ||
shouldPadOperators
00918 ||
shouldConvertTabs);
00919 }
00920
00930 void ASFormatter::setBracketFormatMode(BracketMode mode) {
00931
bracketFormatMode = mode;
00932 }
00933
00943 void ASFormatter::setBreakClosingHeaderBracketsMode(
bool state) {
00944
shouldBreakClosingHeaderBrackets = state;
00945 }
00946
00955 void ASFormatter::setBreakElseIfsMode(
bool state) {
00956
shouldBreakElseIfs = state;
00957 }
00958
00967 void ASFormatter::setOperatorPaddingMode(
bool state) {
00968
shouldPadOperators = state;
00969 }
00970
00979 void ASFormatter::setParenthesisPaddingMode(
bool state) {
00980
shouldPadParenthesies = state;
00981 }
00982
00988 void ASFormatter::setBreakOneLineBlocksMode(
bool state) {
00989
shouldBreakOneLineBlocks = state;
00990 }
00991
00997 void ASFormatter::setSingleStatementsMode(
bool state) {
00998
shouldBreakOneLineStatements = state;
00999 }
01000
01006 void ASFormatter::setTabSpaceConversionMode(
bool state) {
01007
shouldConvertTabs = state;
01008 }
01009
01010
01016 void ASFormatter::setBreakBlocksMode(
bool state) {
01017
shouldBreakBlocks = state;
01018 }
01019
01025 void ASFormatter::setBreakClosingHeaderBlocksMode(
bool state) {
01026
shouldBreakClosingHeaderBlocks = state;
01027 }
01028
01035 bool ASFormatter::isSequenceReached(
const string &sequence)
const {
01036
return currentLine.COMPARE(
charNum, sequence.length(), sequence) == 0;
01037
01038 }
01039
01045 void ASFormatter::goForward(
int i) {
01046
while (--i >= 0)
01047
getNextChar();
01048 }
01049
01055 char ASFormatter::peekNextChar()
const {
01056
int peekNum =
charNum + 1;
01057
int len =
currentLine.length();
01058
char ch =
' ';
01059
01060
while (peekNum <
len) {
01061 ch =
currentLine[peekNum++];
01062
if (!isWhiteSpace(ch))
01063
return ch;
01064 }
01065
01066
if (
shouldConvertTabs && ch ==
'\t')
01067 ch =
' ';
01068
01069
return ch;
01070 }
01071
01077 bool ASFormatter::isBeforeComment()
const {
01078
int peekNum =
charNum + 1;
01079
int len =
currentLine.length();
01080
01081
bool foundComment =
false;
01082
01083
for (peekNum = charNum + 1;
01084 peekNum <
len && isWhiteSpace(
currentLine[peekNum]);
01085 ++peekNum)
01086 ;
01087
01088
if (peekNum <
len)
01089 foundComment = (
currentLine.COMPARE(peekNum, 2, AS_OPEN_COMMENT) == 0
01090 ||
currentLine.COMPARE(peekNum, 2, AS_OPEN_LINE_COMMENT) == 0 );
01091
01092
return foundComment;
01093 }
01094
01101 bool ASFormatter::getNextChar() {
01102
isInLineBreak =
false;
01103
bool isAfterFormattedWhiteSpace =
false;
01104
01105
if (
shouldPadOperators && !
isInComment && !
isInLineComment
01106 && !
isInQuote && !
doesLineStartComment && !
isInPreprocessor
01107 && !
isBeforeComment()) {
01108
int len =
formattedLine.length();
01109
if (
len > 0 && isWhiteSpace(
formattedLine[
len-1]))
01110 isAfterFormattedWhiteSpace =
true;
01111 }
01112
01113
previousChar =
currentChar;
01114
if (!isWhiteSpace(currentChar)) {
01115
previousNonWSChar = currentChar;
01116
if (!
isInComment && !
isInLineComment && !
isInQuote
01117 && !
isSequenceReached(AS_OPEN_COMMENT)
01118 && !
isSequenceReached(AS_OPEN_LINE_COMMENT) )
01119
previousCommandChar =
previousNonWSChar;
01120 }
01121
01122
int currentLineLength =
currentLine.length();
01123
01124
if (
charNum+1 < currentLineLength
01125 && (!isWhiteSpace(
peekNextChar()) ||
isInComment ||
isInLineComment)) {
01126 currentChar =
currentLine[++
charNum];
01127
if (isAfterFormattedWhiteSpace)
01128
while (isWhiteSpace(currentChar) &&
charNum+1 < currentLineLength)
01129 currentChar = currentLine[++
charNum];
01130
01131
if (
shouldConvertTabs && currentChar ==
'\t')
01132 currentChar =
' ';
01133
01134
return true;
01135 }
else {
01136
if (
sourceIterator->
hasMoreLines()) {
01137
currentLine =
sourceIterator->
nextLine();
01138
if (
currentLine.length() == 0) {
01139
currentLine = string(
" ");
01140 }
01141
01142
01143
01144
if (!
isVirgin)
01145
isInLineBreak =
true;
01146
else
01147
isVirgin =
false;
01148
01149
if (
isInLineComment)
01150
isImmediatelyPostLineComment =
true;
01151
isInLineComment =
false;
01152
01153
trimNewLine();
01154 currentChar =
currentLine[
charNum];
01155
01156
01157
if (
previousNonWSChar !=
'\\')
01158
isInPreprocessor =
false;
01159
01160
if (
shouldConvertTabs && currentChar ==
'\t')
01161 currentChar =
' ';
01162
01163
return true;
01164 }
else {
01165
endOfCodeReached =
true;
01166
return false;
01167 }
01168 }
01169 }
01170
01175 void ASFormatter::trimNewLine() {
01176
int len =
currentLine.length();
01177
charNum = 0;
01178
01179
if (
isInComment ||
isInPreprocessor)
01180
return;
01181
01182
while (isWhiteSpace(
currentLine[
charNum]) && charNum+1 <
len)
01183 ++charNum;
01184
01185
doesLineStartComment =
false;
01186
if (
isSequenceReached(string(
"/*"))) {
01187 charNum = 0;
01188
doesLineStartComment =
true;
01189 }
01190 }
01191
01202 void ASFormatter::appendChar(
char ch,
bool canBreakLine) {
01203
if (canBreakLine &&
isInLineBreak)
01204
breakLine();
01205
formattedLine.append(1, ch);
01206 }
01207
01217 void ASFormatter::appendCurrentChar(
bool canBreakLine) {
01218
appendChar(
currentChar, canBreakLine);
01219 }
01220
01231 void ASFormatter::appendSequence(
const string &sequence,
bool canBreakLine) {
01232
if (canBreakLine &&
isInLineBreak)
01233
breakLine();
01234
formattedLine.append(sequence);
01235 }
01236
01241 void ASFormatter::appendSpacePad() {
01242
int len =
formattedLine.length();
01243
if (
len == 0 || !isWhiteSpace(
formattedLine[
len-1]))
01244
formattedLine.append(1,
' ');
01245 }
01246
01250 void ASFormatter::breakLine() {
01251
isLineReady =
true;
01252
isInLineBreak =
false;
01253
01254
01255
prependEmptyLine =
isPrependPostBlockEmptyLineRequested;
01256
01257
readyFormattedLine =
formattedLine;
01258
if (
isAppendPostBlockEmptyLineRequested) {
01259
isAppendPostBlockEmptyLineRequested =
false;
01260 isPrependPostBlockEmptyLineRequested =
true;
01261 }
else {
01262 isPrependPostBlockEmptyLineRequested =
false;
01263 }
01264
01265 formattedLine =
"";
01266 }
01267
01279 BracketType ASFormatter::getBracketType()
const {
01280
BracketType returnVal;
01281
01282
if (
foundPreDefinitionHeader)
01283 returnVal =
DEFINITION_TYPE;
01284
else {
01285
bool isCommandType;
01286 isCommandType = (
foundPreCommandHeader
01287 || (
currentHeader != NULL &&
isNonParenHeader )
01288 || (
previousCommandChar ==
')' )
01289 || (
previousCommandChar ==
':' && !
foundQuestionMark )
01290 || (
previousCommandChar ==
';' )
01291 || ( (
previousCommandChar ==
'{' ||
previousCommandChar ==
'}')
01292 &&
isPreviousBracketBlockRelated ) );
01293
01294 returnVal = (isCommandType ?
COMMAND_TYPE :
ARRAY_TYPE);
01295 }
01296
01297
if (
isOneLineBlockReached())
01298 returnVal = (
BracketType) (returnVal |
SINGLE_LINE_TYPE);
01299
01300
return returnVal;
01301 }
01302
01311 bool ASFormatter::isPointerOrReference()
const {
01312
bool isPR;
01313 isPR = ( !
isInPotentialCalculation
01314 ||
IS_A(
bracketTypeStack->back(),
DEFINITION_TYPE)
01315 || (!isLegalNameChar(
previousNonWSChar)
01316 &&
previousNonWSChar !=
')'
01317 &&
previousNonWSChar !=
']')
01318 );
01319
01320
if (!isPR) {
01321
char nextChar =
peekNextChar();
01322 isPR |= (!isWhiteSpace(nextChar)
01323 && nextChar !=
'-'
01324 && nextChar !=
'('
01325 && nextChar !=
'['
01326 && !isLegalNameChar(nextChar));
01327 }
01328
01329
return isPR;
01330 }
01331
01332
01341 bool ASFormatter::isUnaryMinus()
const {
01342
return ( (
previousOperator == &AS_RETURN || !isalnum(
previousCommandChar))
01343 &&
previousCommandChar !=
'.'
01344 &&
previousCommandChar !=
')'
01345 &&
previousCommandChar !=
']' );
01346 }
01347
01348
01357 bool ASFormatter::isInExponent()
const {
01358
int formattedLineLength =
formattedLine.length();
01359
if (formattedLineLength >= 2) {
01360
char prevPrevFormattedChar =
formattedLine[formattedLineLength - 2];
01361
char prevFormattedChar = formattedLine[formattedLineLength - 1];
01362
01363
return ( (prevFormattedChar ==
'e' || prevFormattedChar ==
'E')
01364 && (prevPrevFormattedChar ==
'.' || isdigit(prevPrevFormattedChar)) );
01365 }
else
01366
return false;
01367 }
01368
01376 bool ASFormatter::isOneLineBlockReached()
const {
01377
bool isInComment =
false;
01378
bool isInQuote =
false;
01379
int bracketCount = 1;
01380
int currentLineLength =
currentLine.length();
01381
int i = 0;
01382
char ch =
' ';
01383
char quoteChar =
' ';
01384
01385
for (i =
charNum + 1; i < currentLineLength; ++i) {
01386 ch =
currentLine[i];
01387
01388
if (isInComment) {
01389
if (currentLine.COMPARE(i, 2,
"*/") == 0) {
01390 isInComment =
false;
01391 ++i;
01392 }
01393
continue;
01394 }
01395
01396
if (ch ==
'\\') {
01397 ++i;
01398
continue;
01399 }
01400
01401
if (isInQuote) {
01402
if (ch == quoteChar)
01403 isInQuote =
false;
01404
continue;
01405 }
01406
01407
if (ch ==
'"' || ch ==
'\'') {
01408 isInQuote =
true;
01409 quoteChar = ch;
01410
continue;
01411 }
01412
01413
if (currentLine.COMPARE(i, 2,
"//") == 0)
01414
break;
01415
01416
if (currentLine.COMPARE(i, 2,
"/*") == 0) {
01417 isInComment =
true;
01418 ++i;
01419
continue;
01420 }
01421
01422
if (ch ==
'{')
01423 ++bracketCount;
01424
else if (ch ==
'}')
01425 --bracketCount;
01426
01427
if(bracketCount == 0)
01428
return true;
01429 }
01430
01431
return false;
01432 }
01433
01434
01443 const string *ASFormatter::findHeader(
const vector<const string*> &headers,
bool checkBoundry) {
01444
return ASBeautifier::findHeader(
currentLine,
charNum, headers, checkBoundry);
01445 }
01446
01447
01448
01449
#ifdef USES_NAMESPACE
01450
}
01451
#endif
01452
01453