ASFormatter.cpp
Go to the documentation of this file.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
This file is part of the documentation for KDevelop Version 3.1.2.