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 #include "compiler_defines.h"
00028 #include "astyle.h"
00029
00030 #include <vector>
00031 #include <string>
00032 #include <cctype>
00033 #include <algorithm>
00034 #include <iostream>
00035
00036
00037 #define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); }
00038 #define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container) ; }
00039
00040 #ifdef USES_NAMESPACE
00041 using namespace std;
00042 #endif
00043
00044
00045
00046
00047 #ifdef USES_NAMESPACE
00048 namespace astyle
00049 {
00050 #endif
00051
00052 bool ASBeautifier::calledInitStatic = false;
00053
00054 vector<const string*> ASBeautifier::headers;
00055 vector<const string*> ASBeautifier::nonParenHeaders;
00056 vector<const string*> ASBeautifier::preBlockStatements;
00057 vector<const string*> ASBeautifier::assignmentOperators;
00058 vector<const string*> ASBeautifier::nonAssignmentOperators;
00059
00060
00061
00062
00063 void ASBeautifier::initStatic()
00064 {
00065 if (calledInitStatic)
00066 return;
00067
00068 calledInitStatic = true;
00069
00070 headers.push_back(&AS_IF);
00071 headers.push_back(&AS_ELSE);
00072 headers.push_back(&AS_FOR);
00073 headers.push_back(&AS_WHILE);
00074 headers.push_back(&AS_DO);
00075 headers.push_back(&AS_TRY);
00076 headers.push_back(&AS_CATCH);
00077 headers.push_back(&AS_FINALLY);
00078 headers.push_back(&AS_SYNCHRONIZED);
00079 headers.push_back(&AS_SWITCH);
00080 headers.push_back(&AS_CASE);
00081 headers.push_back(&AS_DEFAULT);
00082 headers.push_back(&AS_FOREACH);
00083 headers.push_back(&AS_LOCK);
00084 headers.push_back(&AS_UNSAFE);
00085 headers.push_back(&AS_FIXED);
00086 headers.push_back(&AS_GET);
00087 headers.push_back(&AS_SET);
00088 headers.push_back(&AS_ADD);
00089 headers.push_back(&AS_REMOVE);
00090
00091
00092
00093
00094
00095 headers.push_back(&AS_TEMPLATE);
00096 headers.push_back(&AS_CONST);
00097
00098 headers.push_back(&AS_STATIC);
00099 headers.push_back(&AS_EXTERN);
00100
00101 nonParenHeaders.push_back(&AS_ELSE);
00102 nonParenHeaders.push_back(&AS_DO);
00103 nonParenHeaders.push_back(&AS_TRY);
00104 nonParenHeaders.push_back(&AS_FINALLY);
00105 nonParenHeaders.push_back(&AS_STATIC);
00106 nonParenHeaders.push_back(&AS_CONST);
00107 nonParenHeaders.push_back(&AS_EXTERN);
00108 nonParenHeaders.push_back(&AS_CASE);
00109 nonParenHeaders.push_back(&AS_DEFAULT);
00110 nonParenHeaders.push_back(&AS_UNSAFE);
00111 nonParenHeaders.push_back(&AS_GET);
00112 nonParenHeaders.push_back(&AS_SET);
00113 nonParenHeaders.push_back(&AS_ADD);
00114 nonParenHeaders.push_back(&AS_REMOVE);
00115
00116
00117
00118 nonParenHeaders.push_back(&AS_PUBLIC);
00119 nonParenHeaders.push_back(&AS_PRIVATE);
00120 nonParenHeaders.push_back(&AS_PROTECTED);
00121 nonParenHeaders.push_back(&AS_TEMPLATE);
00122 nonParenHeaders.push_back(&AS_CONST);
00124
00125 preBlockStatements.push_back(&AS_CLASS);
00126 preBlockStatements.push_back(&AS_STRUCT);
00127 preBlockStatements.push_back(&AS_UNION);
00128 preBlockStatements.push_back(&AS_INTERFACE);
00129 preBlockStatements.push_back(&AS_NAMESPACE);
00130 preBlockStatements.push_back(&AS_THROWS);
00131 preBlockStatements.push_back(&AS_EXTERN);
00132
00133 assignmentOperators.push_back(&AS_ASSIGN);
00134 assignmentOperators.push_back(&AS_PLUS_ASSIGN);
00135 assignmentOperators.push_back(&AS_MINUS_ASSIGN);
00136 assignmentOperators.push_back(&AS_MULT_ASSIGN);
00137 assignmentOperators.push_back(&AS_DIV_ASSIGN);
00138 assignmentOperators.push_back(&AS_MOD_ASSIGN);
00139 assignmentOperators.push_back(&AS_OR_ASSIGN);
00140 assignmentOperators.push_back(&AS_AND_ASSIGN);
00141 assignmentOperators.push_back(&AS_XOR_ASSIGN);
00142 assignmentOperators.push_back(&AS_GR_GR_GR_ASSIGN);
00143 assignmentOperators.push_back(&AS_GR_GR_ASSIGN);
00144 assignmentOperators.push_back(&AS_LS_LS_LS_ASSIGN);
00145 assignmentOperators.push_back(&AS_LS_LS_ASSIGN);
00146
00147 assignmentOperators.push_back(&AS_RETURN);
00148
00149 nonAssignmentOperators.push_back(&AS_EQUAL);
00150 nonAssignmentOperators.push_back(&AS_PLUS_PLUS);
00151 nonAssignmentOperators.push_back(&AS_MINUS_MINUS);
00152 nonAssignmentOperators.push_back(&AS_NOT_EQUAL);
00153 nonAssignmentOperators.push_back(&AS_GR_EQUAL);
00154 nonAssignmentOperators.push_back(&AS_GR_GR_GR);
00155 nonAssignmentOperators.push_back(&AS_GR_GR);
00156 nonAssignmentOperators.push_back(&AS_LS_EQUAL);
00157 nonAssignmentOperators.push_back(&AS_LS_LS_LS);
00158 nonAssignmentOperators.push_back(&AS_LS_LS);
00159 nonAssignmentOperators.push_back(&AS_ARROW);
00160 nonAssignmentOperators.push_back(&AS_AND);
00161 nonAssignmentOperators.push_back(&AS_OR);
00162 }
00163
00167 ASBeautifier::ASBeautifier()
00168 {
00169 initStatic();
00170
00171 waitingBeautifierStack = NULL;
00172 activeBeautifierStack = NULL;
00173 waitingBeautifierStackLengthStack = NULL;
00174 activeBeautifierStackLengthStack = NULL;
00175
00176 headerStack = NULL;
00177 tempStacks = NULL;
00178 blockParenDepthStack = NULL;
00179 blockStatementStack = NULL;
00180 parenStatementStack = NULL;
00181 bracketBlockStateStack = NULL;
00182 inStatementIndentStack = NULL;
00183 inStatementIndentStackSizeStack = NULL;
00184 parenIndentStack = NULL;
00185 sourceIterator = NULL;
00186
00187 isMinimalConditinalIndentSet = false;
00188 shouldForceTabIndentation = false;
00189
00190 setSpaceIndentation(4);
00191 setMaxInStatementIndentLength(40);
00192 setClassIndent(false);
00193 setSwitchIndent(false);
00194 setCaseIndent(false);
00195 setBlockIndent(false);
00196 setBracketIndent(false);
00197 setNamespaceIndent(false);
00198 setLabelIndent(false);
00199 setEmptyLineFill(false);
00200 setCStyle();
00201 setPreprocessorIndent(false);
00202 }
00203
00204 ASBeautifier::ASBeautifier(const ASBeautifier &other)
00205 {
00206 waitingBeautifierStack = NULL;
00207 activeBeautifierStack = NULL;
00208 waitingBeautifierStackLengthStack = NULL;
00209 activeBeautifierStackLengthStack = NULL;
00210
00211 headerStack = new vector<const string*>;
00212 *headerStack = *other.headerStack;
00213
00214 tempStacks = new vector< vector<const string*>* >;
00215 vector< vector<const string*>* >::iterator iter;
00216 for (iter = other.tempStacks->begin();
00217 iter != other.tempStacks->end();
00218 ++iter)
00219 {
00220 vector<const string*> *newVec = new vector<const string*>;
00221 *newVec = **iter;
00222 tempStacks->push_back(newVec);
00223 }
00224 blockParenDepthStack = new vector<int>;
00225 *blockParenDepthStack = *other.blockParenDepthStack;
00226
00227 blockStatementStack = new vector<bool>;
00228 *blockStatementStack = *other.blockStatementStack;
00229
00230 parenStatementStack = new vector<bool>;
00231 *parenStatementStack = *other.parenStatementStack;
00232
00233 bracketBlockStateStack = new vector<bool>;
00234 *bracketBlockStateStack = *other.bracketBlockStateStack;
00235
00236 inStatementIndentStack = new vector<int>;
00237 *inStatementIndentStack = *other.inStatementIndentStack;
00238
00239 inStatementIndentStackSizeStack = new vector<int>;
00240 *inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack;
00241
00242 parenIndentStack = new vector<int>;
00243 *parenIndentStack = *other.parenIndentStack;
00244
00245 sourceIterator = other.sourceIterator;
00246
00247 indentString = other.indentString;
00248 currentHeader = other.currentHeader;
00249 previousLastLineHeader = other.previousLastLineHeader;
00250 immediatelyPreviousAssignmentOp = other.immediatelyPreviousAssignmentOp;
00251 isInQuote = other.isInQuote;
00252 isInComment = other.isInComment;
00253 isInCase = other.isInCase;
00254 isInQuestion = other.isInQuestion;
00255 isInStatement =other. isInStatement;
00256 isInHeader = other.isInHeader;
00257 isCStyle = other.isCStyle;
00258 isInOperator = other.isInOperator;
00259 isInTemplate = other.isInTemplate;
00260 isInConst = other.isInConst;
00261 classIndent = other.classIndent;
00262 isInClassHeader = other.isInClassHeader;
00263 isInClassHeaderTab = other.isInClassHeaderTab;
00264 switchIndent = other.switchIndent;
00265 caseIndent = other.caseIndent;
00266 namespaceIndent = other.namespaceIndent;
00267 bracketIndent = other.bracketIndent;
00268 blockIndent = other.blockIndent;
00269 labelIndent = other.labelIndent;
00270 preprocessorIndent = other.preprocessorIndent;
00271 parenDepth = other.parenDepth;
00272 indentLength = other.indentLength;
00273 blockTabCount = other.blockTabCount;
00274 leadingWhiteSpaces = other.leadingWhiteSpaces;
00275 maxInStatementIndent = other.maxInStatementIndent;
00276 templateDepth = other.templateDepth;
00277 quoteChar = other.quoteChar;
00278 prevNonSpaceCh = other.prevNonSpaceCh;
00279 currentNonSpaceCh = other.currentNonSpaceCh;
00280 currentNonLegalCh = other.currentNonLegalCh;
00281 prevNonLegalCh = other.prevNonLegalCh;
00282 isInConditional = other.isInConditional;
00283 minConditionalIndent = other.minConditionalIndent;
00284 prevFinalLineSpaceTabCount = other.prevFinalLineSpaceTabCount;
00285 prevFinalLineTabCount = other.prevFinalLineTabCount;
00286 emptyLineFill = other.emptyLineFill;
00287 probationHeader = other.probationHeader;
00288 isInDefine = other.isInDefine;
00289 isInDefineDefinition = other.isInDefineDefinition;
00290 backslashEndsPrevLine = other.backslashEndsPrevLine;
00291 defineTabCount = other.defineTabCount;
00292 }
00293
00297 ASBeautifier::~ASBeautifier()
00298 {
00299 DELETE_CONTAINER( headerStack );
00300 DELETE_CONTAINER( tempStacks );
00301 DELETE_CONTAINER( blockParenDepthStack );
00302 DELETE_CONTAINER( blockStatementStack );
00303 DELETE_CONTAINER( parenStatementStack );
00304 DELETE_CONTAINER( bracketBlockStateStack );
00305 DELETE_CONTAINER( inStatementIndentStack );
00306 DELETE_CONTAINER( inStatementIndentStackSizeStack );
00307 DELETE_CONTAINER( parenIndentStack );
00308
00309
00310 }
00311
00324 void ASBeautifier::init(ASSourceIterator *iter)
00325 {
00326 sourceIterator = iter;
00327 init();
00328 }
00329
00333 void ASBeautifier::init()
00334 {
00335 INIT_CONTAINER( waitingBeautifierStack, new vector<ASBeautifier*> );
00336 INIT_CONTAINER( activeBeautifierStack, new vector<ASBeautifier*> );
00337
00338 INIT_CONTAINER( waitingBeautifierStackLengthStack, new vector<int> );
00339 INIT_CONTAINER( activeBeautifierStackLengthStack, new vector<int> );
00340
00341 INIT_CONTAINER( headerStack, new vector<const string*> );
00342 INIT_CONTAINER( tempStacks, new vector< vector<const string*>* > );
00343 tempStacks->push_back(new vector<const string*>);
00344
00345 INIT_CONTAINER( blockParenDepthStack, new vector<int> );
00346 INIT_CONTAINER( blockStatementStack, new vector<bool> );
00347 INIT_CONTAINER( parenStatementStack, new vector<bool> );
00348
00349 INIT_CONTAINER( bracketBlockStateStack, new vector<bool> );
00350 bracketBlockStateStack->push_back(true);
00351
00352 INIT_CONTAINER( inStatementIndentStack, new vector<int> );
00353 INIT_CONTAINER( inStatementIndentStackSizeStack, new vector<int> );
00354 inStatementIndentStackSizeStack->push_back(0);
00355 INIT_CONTAINER( parenIndentStack, new vector<int> );
00356
00357 immediatelyPreviousAssignmentOp = NULL;
00358 previousLastLineHeader = NULL;
00359
00360 isInQuote = false;
00361 isInComment = false;
00362 isInStatement = false;
00363 isInCase = false;
00364 isInQuestion = false;
00365 isInClassHeader = false;
00366 isInClassHeaderTab = false;
00367 isInHeader = false;
00368 isInOperator = false;
00369 isInTemplate = false;
00370 isInConst = false;
00371 isInConditional = false;
00372 templateDepth = 0;
00373 parenDepth=0;
00374 blockTabCount = 0;
00375 leadingWhiteSpaces = 0;
00376 prevNonSpaceCh = '{';
00377 currentNonSpaceCh = '{';
00378 prevNonLegalCh = '{';
00379 currentNonLegalCh = '{';
00380 prevFinalLineSpaceTabCount = 0;
00381 prevFinalLineTabCount = 0;
00382 probationHeader = NULL;
00383 backslashEndsPrevLine = false;
00384 isInDefine = false;
00385 isInDefineDefinition = false;
00386 defineTabCount = 0;
00387 }
00388
00392 void ASBeautifier::setCStyle()
00393 {
00394 isCStyle = true;
00395 }
00396
00400 void ASBeautifier::setJavaStyle()
00401 {
00402 isCStyle = false;
00403 }
00404
00408 void ASBeautifier::setTabIndentation(int length, bool forceTabs)
00409 {
00410 indentString = "\t";
00411 indentLength = length;
00412 shouldForceTabIndentation = forceTabs;
00413
00414 if (!isMinimalConditinalIndentSet)
00415 minConditionalIndent = indentLength * 2;
00416 }
00417
00423 void ASBeautifier::setSpaceIndentation(int length)
00424 {
00425 indentString=string(length, ' ');
00426 indentLength = length;
00427
00428 if (!isMinimalConditinalIndentSet)
00429 minConditionalIndent = indentLength * 2;
00430 }
00431
00437 void ASBeautifier::setMaxInStatementIndentLength(int max)
00438 {
00439 maxInStatementIndent = max;
00440 }
00441
00447 void ASBeautifier::setMinConditionalIndentLength(int min)
00448 {
00449 minConditionalIndent = min;
00450 isMinimalConditinalIndentSet = true;
00451 }
00452
00459 void ASBeautifier::setBracketIndent(bool state)
00460 {
00461 bracketIndent = state;
00462 }
00463
00470 void ASBeautifier::setBlockIndent(bool state)
00471 {
00472 if (state)
00473 setBracketIndent(false);
00474 blockIndent = state;
00475 }
00476
00483 void ASBeautifier::setClassIndent(bool state)
00484 {
00485 classIndent = state;
00486 }
00487
00494 void ASBeautifier::setSwitchIndent(bool state)
00495 {
00496 switchIndent = state;
00497 }
00498
00505 void ASBeautifier::setCaseIndent(bool state)
00506 {
00507 caseIndent = state;
00508 }
00516 void ASBeautifier::setNamespaceIndent(bool state)
00517 {
00518 namespaceIndent = state;
00519 }
00520
00530 void ASBeautifier::setLabelIndent(bool state)
00531 {
00532 labelIndent = state;
00533 }
00534
00541 void ASBeautifier::setPreprocessorIndent(bool state)
00542 {
00543 preprocessorIndent = state;
00544 }
00545
00554 void ASBeautifier::setEmptyLineFill(bool state)
00555 {
00556 emptyLineFill = state;
00557 }
00558
00564 bool ASBeautifier::hasMoreLines() const
00565 {
00566 return sourceIterator->hasMoreLines();
00567 }
00568
00574 string ASBeautifier::nextLine()
00575 {
00576 return beautify(sourceIterator->nextLine());
00577 }
00578
00587 string ASBeautifier::beautify(const string &originalLine)
00588 {
00589 string line;
00590 bool isInLineComment = false;
00591 bool lineStartsInComment = false;
00592 bool isInClass = false;
00593 bool isInSwitch = false;
00594 bool isImmediatelyAfterConst = false;
00595 bool isSpecialChar = false;
00596 char ch = ' ';
00597 char prevCh;
00598 string outBuffer;
00599 int tabCount = 0;
00600 const string *lastLineHeader = NULL;
00601 bool closingBracketReached = false;
00602 int spaceTabCount = 0;
00603 char tempCh;
00604 int headerStackSize = headerStack->size();
00605
00606 bool shouldIndentBrackettedLine = true;
00607 int lineOpeningBlocksNum = 0;
00608 int lineClosingBlocksNum = 0;
00609 bool previousLineProbation = (probationHeader != NULL);
00610 int i;
00611
00612 currentHeader = NULL;
00613
00614 lineStartsInComment = isInComment;
00615
00616
00617
00618
00619
00620 if (!isInComment)
00621 {
00622 leadingWhiteSpaces = 0;
00623 while (leadingWhiteSpaces<(int)originalLine.length() && originalLine[leadingWhiteSpaces] <= 0x20)
00624 leadingWhiteSpaces++;
00625
00626 line = trim(originalLine);
00627 }
00628 else
00629 {
00630 int trimSize;
00631 for (trimSize=0;
00632 trimSize < (int)originalLine.length() && trimSize<leadingWhiteSpaces && originalLine[trimSize] <= 0x20 ;
00633 trimSize++)
00634 ;
00635 line = originalLine.substr(trimSize);
00636 }
00637
00638
00639 if (line.length() == 0)
00640 {
00641 if (emptyLineFill)
00642 return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
00643 else
00644 return line;
00645 }
00646
00647
00648
00649 if (isCStyle && !isInComment && (line[0] == '#' || backslashEndsPrevLine))
00650 {
00651 if (line[0] == '#')
00652 {
00653 string preproc = trim(string(line.c_str() + 1));
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 if (preprocessorIndent && preproc.COMPARE(0, 6, string("define")) == 0 && line[line.length() - 1] == '\\')
00664 {
00665 if (!isInDefineDefinition)
00666 {
00667 ASBeautifier *defineBeautifier;
00668
00669
00670 isInDefineDefinition = true;
00671
00672
00673
00674 defineBeautifier = new ASBeautifier(*this);
00675
00676
00677
00678 activeBeautifierStack->push_back(defineBeautifier);
00679 }
00680 else
00681 {
00682
00683 isInDefine = true;
00684 }
00685 }
00686 else if (preproc.COMPARE(0, 2, string("if")) == 0)
00687 {
00688
00689 waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
00690 activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
00691 waitingBeautifierStack->push_back(new ASBeautifier(*this));
00692 }
00693 else if (preproc.COMPARE(0, 4, string("else")) == 0)
00694 {
00695 if (!waitingBeautifierStack->empty())
00696 {
00697
00698 activeBeautifierStack->push_back(waitingBeautifierStack->back());
00699 waitingBeautifierStack->pop_back();
00700 }
00701 }
00702 else if (preproc.COMPARE(0, 4, string("elif")) == 0)
00703 {
00704 if (!waitingBeautifierStack->empty())
00705 {
00706
00707 activeBeautifierStack->push_back( new ASBeautifier( *(waitingBeautifierStack->back()) ) );
00708 }
00709 }
00710 else if (preproc.COMPARE(0, 5, string("endif")) == 0)
00711 {
00712 int stackLength;
00713 ASBeautifier *beautifier;
00714
00715 if (!waitingBeautifierStackLengthStack->empty())
00716 {
00717 stackLength = waitingBeautifierStackLengthStack->back();
00718 waitingBeautifierStackLengthStack->pop_back();
00719 while ((int)waitingBeautifierStack->size() > stackLength)
00720 {
00721 beautifier = waitingBeautifierStack->back();
00722 waitingBeautifierStack->pop_back();
00723 delete beautifier;
00724 }
00725 }
00726
00727 if (!activeBeautifierStackLengthStack->empty())
00728 {
00729 stackLength = activeBeautifierStackLengthStack->back();
00730 activeBeautifierStackLengthStack->pop_back();
00731 while ((int)activeBeautifierStack->size() > stackLength)
00732 {
00733 beautifier = activeBeautifierStack->back();
00734 activeBeautifierStack->pop_back();
00735 delete beautifier;
00736 }
00737 }
00738
00739
00740 }
00741 }
00742
00743
00744 if(line.length() > 0)
00745 backslashEndsPrevLine = (line[line.length() - 1] == '\\');
00746 else
00747 backslashEndsPrevLine = false;
00748
00749
00750
00751
00752 if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine)
00753 {
00754 string beautifiedLine;
00755 ASBeautifier *defineBeautifier;
00756
00757 isInDefineDefinition = false;
00758 defineBeautifier = activeBeautifierStack->back();
00759 activeBeautifierStack->pop_back();
00760
00761 beautifiedLine = defineBeautifier->beautify(line);
00762 delete defineBeautifier;
00763 return beautifiedLine;
00764 }
00765
00766
00767 if (!isInDefine && !isInDefineDefinition)
00768 return originalLine;
00769 }
00770
00771
00772
00773 if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty())
00774 {
00775 return activeBeautifierStack->back()->beautify(line);
00776 }
00777
00778
00779 if (!inStatementIndentStack->empty())
00780 spaceTabCount = inStatementIndentStack->back();
00781
00782
00783 for (i=0; i<headerStackSize; i++)
00784 {
00785 isInClass = false;
00786
00787 if (blockIndent || (!(i>0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET
00788 && (*headerStack)[i] == &AS_OPEN_BRACKET)))
00789 ++tabCount;
00790
00791 if (isCStyle && !namespaceIndent && i >= 1
00792 && (*headerStack)[i-1] == &AS_NAMESPACE
00793 && (*headerStack)[i] == &AS_OPEN_BRACKET)
00794 --tabCount;
00795
00796 if (isCStyle && i >= 1
00797 && (*headerStack)[i-1] == &AS_CLASS
00798 && (*headerStack)[i] == &AS_OPEN_BRACKET )
00799 {
00800 if (classIndent)
00801 ++tabCount;
00802 isInClass = true;
00803 }
00804
00805
00806 else if (switchIndent && i > 1 &&
00807 (*headerStack)[i-1] == &AS_SWITCH &&
00808 (*headerStack)[i] == &AS_OPEN_BRACKET
00809 )
00810 {
00811 ++tabCount;
00812 isInSwitch = true;
00813 }
00814
00815 }
00816
00817 if (!lineStartsInComment
00818 && isCStyle
00819 && isInClass
00820 && classIndent
00821 && headerStackSize >= 2
00822 &&(*headerStack)[headerStackSize-2] == &AS_CLASS
00823 && (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
00824 && line[0] == '}')
00825 --tabCount;
00826
00827 else if (!lineStartsInComment
00828 && isInSwitch
00829 && switchIndent
00830 && headerStackSize >= 2
00831 && (*headerStack)[headerStackSize-2] == &AS_SWITCH
00832 && (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
00833 && line[0] == '}')
00834 --tabCount;
00835
00836 if (isInClassHeader)
00837 {
00838 isInClassHeaderTab = true;
00839 tabCount += 2;
00840 }
00841
00842 if (isInConditional)
00843 {
00844 --tabCount;
00845 }
00846
00847
00848
00849
00850 for (i=0; i<(int)line.length(); i++)
00851 {
00852 tempCh = line[i];
00853
00854 prevCh = ch;
00855 ch = tempCh;
00856
00857 outBuffer.append(1, ch);
00858
00859 if (isWhiteSpace(ch))
00860 continue;
00861
00862
00863 if (isSpecialChar)
00864 {
00865 isSpecialChar = false;
00866 continue;
00867 }
00868 if (!(isInComment || isInLineComment) && line.COMPARE(i, 2, string("\\\\")) == 0)
00869 {
00870 outBuffer.append(1, '\\');
00871 i++;
00872 continue;
00873 }
00874 if (!(isInComment || isInLineComment) && ch=='\\')
00875 {
00876 isSpecialChar = true;
00877 continue;
00878 }
00879
00880
00881 if (!(isInComment || isInLineComment) && (ch=='"' || ch=='\''))
00882 if (!isInQuote)
00883 {
00884 quoteChar = ch;
00885 isInQuote = true;
00886 }
00887 else if (quoteChar == ch)
00888 {
00889 isInQuote = false;
00890 isInStatement = true;
00891 continue;
00892 }
00893 if (isInQuote)
00894 continue;
00895
00896
00897
00898 if ( !(isInComment || isInLineComment) && line.COMPARE(i, 2, AS_OPEN_LINE_COMMENT) == 0 )
00899 {
00900 isInLineComment = true;
00901 outBuffer.append(1, '/');
00902 i++;
00903 continue;
00904 }
00905 else if ( !(isInComment || isInLineComment) && line.COMPARE(i, 2, AS_OPEN_COMMENT) == 0 )
00906 {
00907 isInComment = true;
00908 outBuffer.append(1, '*');
00909 i++;
00910 continue;
00911 }
00912 else if ( (isInComment || isInLineComment) && line.COMPARE(i, 2, AS_CLOSE_COMMENT) == 0 )
00913 {
00914 isInComment = false;
00915 outBuffer.append(1, '/');
00916 i++;
00917 continue;
00918 }
00919
00920 if (isInComment||isInLineComment)
00921 continue;
00922
00923
00924
00925 if (probationHeader != NULL)
00926 {
00927 if ( ((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{')
00928 || (probationHeader == &AS_SYNCHRONIZED && ch == '('))
00929 {
00930
00931 isInHeader = true;
00932 headerStack->push_back(probationHeader);
00933
00934
00935 isInConditional = (probationHeader == &AS_SYNCHRONIZED);
00936 if (probationHeader == &AS_CONST)
00937 isImmediatelyAfterConst = true;
00938
00947 isInStatement = false;
00948
00949 if (previousLineProbation && ch == '{')
00950 tabCount++;
00951 previousLineProbation = false;
00952 }
00953
00954
00955 probationHeader = NULL;
00956 }
00957
00958 prevNonSpaceCh = currentNonSpaceCh;
00959 currentNonSpaceCh = ch;
00960 if (!isLegalNameChar(ch) && ch != ',' && ch != ';' )
00961 {
00962 prevNonLegalCh = currentNonLegalCh;
00963 currentNonLegalCh = ch;
00964 }
00965
00966
00967
00968
00969
00970
00971
00972 if (isInHeader)
00973 {
00974 isInHeader = false;
00975 currentHeader = headerStack->back();
00976 }
00977 else
00978 currentHeader = NULL;
00979
00980 if (isCStyle && isInTemplate
00981 && (ch == '<' || ch == '>')
00982 && findHeader(line, i, nonAssignmentOperators) == NULL)
00983 {
00984 if (ch == '<')
00985 {
00986 ++templateDepth;
00987 }
00988 else if (ch == '>')
00989 {
00990 if (--templateDepth <= 0)
00991 {
00992 if (isInTemplate)
00993 ch = ';';
00994 else
00995 ch = 't';
00996 isInTemplate = false;
00997 templateDepth = 0;
00998 }
00999 }
01000 }
01001
01002
01003 if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
01004 {
01005 if (ch == '(' || ch == '[')
01006 {
01007 if (parenDepth == 0)
01008 {
01009 parenStatementStack->push_back(isInStatement);
01010 isInStatement = true;
01011 }
01012 parenDepth++;
01013
01014 inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
01015
01016 if (currentHeader != NULL)
01017 registerInStatementIndent(line, i, spaceTabCount, minConditionalIndent, true);
01018 else
01019 registerInStatementIndent(line, i, spaceTabCount, 0, true);
01020 }
01021 else if (ch == ')' || ch == ']')
01022 {
01023 parenDepth--;
01024 if (parenDepth == 0)
01025 {
01026 isInStatement = parenStatementStack->back();
01027 parenStatementStack->pop_back();
01028 ch = ' ';
01029
01030 isInConditional = false;
01031 }
01032
01033 if (!inStatementIndentStackSizeStack->empty())
01034 {
01035 int previousIndentStackSize = inStatementIndentStackSizeStack->back();
01036 inStatementIndentStackSizeStack->pop_back();
01037 while (previousIndentStackSize < (int)inStatementIndentStack->size())
01038 inStatementIndentStack->pop_back();
01039
01040 if (!parenIndentStack->empty())
01041 {
01042 int poppedIndent = parenIndentStack->back();
01043 parenIndentStack->pop_back();
01044
01045 if (i == 0)
01046 spaceTabCount = poppedIndent;
01047 }
01048 }
01049 }
01050
01051 continue;
01052 }
01053
01054
01055 if (ch == '{')
01056 {
01057 bool isBlockOpener = false;
01058
01059
01060 isBlockOpener = ( (prevNonSpaceCh == '{' && bracketBlockStateStack->back())
01061 || prevNonSpaceCh == '}'
01062 || prevNonSpaceCh == ')'
01063 || prevNonSpaceCh == ';'
01064 || isInClassHeader
01065 || isBlockOpener
01066 || isImmediatelyAfterConst
01067 || (isInDefine &&
01068 (prevNonSpaceCh == '('
01069 || prevNonSpaceCh == '_'
01070 || isalnum(prevNonSpaceCh))) );
01071
01072 isInClassHeader = false;
01073 if (!isBlockOpener && currentHeader != NULL)
01074 {
01075 for (int n=0; n < (int)nonParenHeaders.size(); n++)
01076 if (currentHeader == nonParenHeaders[n])
01077 {
01078 isBlockOpener = true;
01079 break;
01080 }
01081 }
01082 bracketBlockStateStack->push_back(isBlockOpener);
01083 if (!isBlockOpener)
01084 {
01085 inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
01086 registerInStatementIndent(line, i, spaceTabCount, 0, true);
01087 parenDepth++;
01088 if (i == 0)
01089 shouldIndentBrackettedLine = false;
01090
01091 continue;
01092 }
01093
01094
01095
01096 ++lineOpeningBlocksNum;
01097
01098 if (isInClassHeader)
01099 isInClassHeader = false;
01100 if (isInClassHeaderTab)
01101 {
01102 isInClassHeaderTab = false;
01103 tabCount -= 2;
01104 }
01105
01106 blockParenDepthStack->push_back(parenDepth);
01107 blockStatementStack->push_back(isInStatement);
01108
01109 inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
01110
01111 blockTabCount += isInStatement? 1 : 0;
01112 parenDepth = 0;
01113 isInStatement = false;
01114
01115 tempStacks->push_back(new vector<const string*>);
01116 headerStack->push_back(&AS_OPEN_BRACKET);
01117 lastLineHeader = &AS_OPEN_BRACKET;
01118
01119 continue;
01120 }
01121
01122
01123 if (prevCh == ' ')
01124 {
01125 bool isIndentableHeader = true;
01126 const string *newHeader = findHeader(line, i, headers);
01127 if (newHeader != NULL)
01128 {
01129
01130 isInHeader = true;
01131
01132 vector<const string*> *lastTempStack;
01133 if (tempStacks->empty())
01134 lastTempStack = NULL;
01135 else
01136 lastTempStack = tempStacks->back();
01137
01138
01139
01140
01141
01142 if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
01143 {
01144
01145 headerStack->pop_back();
01146 }
01147
01148
01149 else if (newHeader == &AS_ELSE)
01150 {
01151 if (lastTempStack != NULL)
01152 {
01153 int indexOfIf = indexOf(*lastTempStack, &AS_IF);
01154 if (indexOfIf != -1)
01155 {
01156
01157
01158 int restackSize = lastTempStack->size() - indexOfIf - 1;
01159 for (int r=0; r<restackSize; r++)
01160 {
01161 headerStack->push_back(lastTempStack->back());
01162 lastTempStack->pop_back();
01163 }
01164 if (!closingBracketReached)
01165 tabCount += restackSize;
01166 }
01167
01168
01169
01170
01171
01172 }
01173 }
01174
01175
01176 else if (newHeader == &AS_WHILE)
01177 {
01178 if (lastTempStack != NULL)
01179 {
01180 int indexOfDo = indexOf(*lastTempStack, &AS_DO);
01181 if (indexOfDo != -1)
01182 {
01183
01184
01185 int restackSize = lastTempStack->size() - indexOfDo - 1;
01186 for (int r=0; r<restackSize; r++)
01187 {
01188 headerStack->push_back(lastTempStack->back());
01189 lastTempStack->pop_back();
01190 }
01191 if (!closingBracketReached)
01192 tabCount += restackSize;
01193 }
01194 }
01195 }
01196
01197 else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
01198 {
01199 if (lastTempStack != NULL)
01200 {
01201 int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
01202 if (indexOfTry == -1)
01203 indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
01204 if (indexOfTry != -1)
01205 {
01206
01207
01208 int restackSize = lastTempStack->size() - indexOfTry - 1;
01209 for (int r=0; r<restackSize; r++)
01210 {
01211 headerStack->push_back(lastTempStack->back());
01212 lastTempStack->pop_back();
01213 }
01214
01215 if (!closingBracketReached)
01216 tabCount += restackSize;
01217 }
01218 }
01219 }
01220 else if (newHeader == &AS_CASE)
01221 {
01222 isInCase = true;
01223 if (!caseIndent)
01224 --tabCount;
01225 }
01226 else if(newHeader == &AS_DEFAULT)
01227 {
01228 isInCase = true;
01229 if (!caseIndent)
01230 --tabCount;
01231 }
01232 else if (newHeader == &AS_PUBLIC || newHeader == &AS_PROTECTED || newHeader == &AS_PRIVATE)
01233 {
01234 if (isCStyle && !isInClassHeader)
01235 --tabCount;
01236 isIndentableHeader = false;
01237 }
01238
01239
01240
01241
01242
01243
01244 else if (newHeader == &AS_STATIC
01245 || newHeader == &AS_SYNCHRONIZED
01246 || (newHeader == &AS_CONST && isCStyle))
01247 {
01248 if (!headerStack->empty() &&
01249 (headerStack->back() == &AS_STATIC
01250 || headerStack->back() == &AS_SYNCHRONIZED
01251 || headerStack->back() == &AS_CONST))
01252 {
01253 isIndentableHeader = false;
01254 }
01255 else
01256 {
01257 isIndentableHeader = false;
01258 probationHeader = newHeader;
01259 }
01260 }
01261 else if (newHeader == &AS_CONST)
01262 {
01263
01264
01265
01266
01267
01268 isIndentableHeader = false;
01269 }
01270
01271
01272
01273
01274
01275
01276
01277
01278 else if (newHeader == &AS_TEMPLATE)
01279 {
01280 if (isCStyle)
01281 isInTemplate = true;
01282 isIndentableHeader = false;
01283 }
01284
01285
01286 if (isIndentableHeader)
01287 {
01288
01289
01290 headerStack->push_back(newHeader);
01291 isInStatement = false;
01292 if (indexOf(nonParenHeaders, newHeader) == -1)
01293 {
01294 isInConditional = true;
01295 }
01296 lastLineHeader = newHeader;
01297 }
01298 else
01299 isInHeader = false;
01300
01301
01302
01303 outBuffer.append(newHeader->substr(1));
01304 i += newHeader->length() - 1;
01305
01306 continue;
01307 }
01308 }
01309
01310 if (isCStyle && !isalpha(prevCh)
01311 && line.COMPARE(i, 8, AS_OPERATOR) == 0 && !isalnum(line[i+8]))
01312 {
01313 isInOperator = true;
01314 outBuffer.append(AS_OPERATOR.substr(1));
01315 i += 7;
01316 continue;
01317 }
01318
01319 if (ch == '?')
01320 isInQuestion = true;
01321
01322
01323
01324 if (ch == ':')
01325 {
01326 if ((int)line.length() > i+1 && line[i+1] == ':')
01327 {
01328 ++i;
01329 outBuffer.append(1, ':');
01330 ch = ' ';
01331 continue;
01332 }
01333
01334 else if (isCStyle && isInClass && prevNonSpaceCh != ')')
01335 {
01336 --tabCount;
01337
01338
01339 }
01340
01341 else if (isCStyle && isInClassHeader)
01342 {
01343
01344
01345
01346 }
01347
01348 else if (isInQuestion)
01349 {
01350 isInQuestion = false;
01351 }
01352 else if (isCStyle && prevNonSpaceCh == ')')
01353 {
01354 isInClassHeader = true;
01355 if (i==0)
01356 tabCount += 2;
01357 }
01358 else
01359 {
01360 currentNonSpaceCh = ';';
01361 if (isInCase)
01362 {
01363 isInCase = false;
01364 ch = ';';
01365 }
01366
01367
01368 else
01369 {
01370 if (labelIndent)
01371 --tabCount;
01372 else
01373 tabCount = 0;
01374 }
01375
01376
01377
01378 }
01379 }
01380
01381 if ((ch == ';' || (parenDepth>0 && ch == ',')) && !inStatementIndentStackSizeStack->empty())
01382 while (inStatementIndentStackSizeStack->back() + (parenDepth>0 ? 1 : 0) < (int)inStatementIndentStack->size())
01383 inStatementIndentStack->pop_back();
01384
01385
01386
01387 if ( (ch == ';' && parenDepth == 0) || ch == '}')
01388 {
01389 if (ch == '}')
01390 {
01391
01392 if (!bracketBlockStateStack->empty())
01393 {
01394 bool bracketBlockState = bracketBlockStateStack->back();
01395 bracketBlockStateStack->pop_back();
01396 if (!bracketBlockState)
01397 {
01398 if (!inStatementIndentStackSizeStack->empty())
01399 {
01400
01401
01402 int previousIndentStackSize = inStatementIndentStackSizeStack->back();
01403 inStatementIndentStackSizeStack->pop_back();
01404 while (previousIndentStackSize < (int)inStatementIndentStack->size())
01405 inStatementIndentStack->pop_back();
01406 parenDepth--;
01407 if (i == 0)
01408 shouldIndentBrackettedLine = false;
01409
01410 if (!parenIndentStack->empty())
01411 {
01412 int poppedIndent = parenIndentStack->back();
01413 parenIndentStack->pop_back();
01414 if (i == 0)
01415 spaceTabCount = poppedIndent;
01416 }
01417 }
01418 continue;
01419 }
01420 }
01421
01422
01423
01424 ++lineClosingBlocksNum;
01425
01426 if(!inStatementIndentStackSizeStack->empty())
01427 inStatementIndentStackSizeStack->pop_back();
01428
01429 if (!blockParenDepthStack->empty())
01430 {
01431 parenDepth = blockParenDepthStack->back();
01432 blockParenDepthStack->pop_back();
01433 isInStatement = blockStatementStack->back();
01434 blockStatementStack->pop_back();
01435
01436 if (isInStatement)
01437 blockTabCount--;
01438 }
01439
01440 closingBracketReached = true;
01441 int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET);
01442 if (headerPlace != -1)
01443 {
01444 const string *popped = headerStack->back();
01445 while (popped != &AS_OPEN_BRACKET)
01446 {
01447 headerStack->pop_back();
01448 popped = headerStack->back();
01449 }
01450 headerStack->pop_back();
01451
01452 if (!tempStacks->empty())
01453 {
01454 vector<const string*> *temp = tempStacks->back();
01455 tempStacks->pop_back();
01456 delete temp;
01457 }
01458 }
01459
01460
01461 ch = ' ';
01462 }
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473 if (!tempStacks->back()->empty())
01474 while (!tempStacks->back()->empty())
01475 tempStacks->back()->pop_back();
01476 while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET)
01477 {
01478 tempStacks->back()->push_back(headerStack->back());
01479 headerStack->pop_back();
01480 }
01481
01482 if (parenDepth == 0 && ch == ';')
01483 isInStatement=false;
01484
01485 isInClassHeader = false;
01486
01487 continue;
01488 }
01489
01490
01491
01492
01493 if (prevCh == ' ' && !isInTemplate && parenDepth == 0)
01494 {
01495 const string *newHeader = findHeader(line, i, preBlockStatements);
01496 if (newHeader != NULL)
01497 {
01498 isInClassHeader = true;
01499 outBuffer.append(newHeader->substr(1));
01500 i += newHeader->length() - 1;
01501
01502 headerStack->push_back(newHeader);
01503 }
01504 }
01505
01506
01507
01508
01513
01514 const string *foundAssignmentOp = NULL;
01515 const string *foundNonAssignmentOp = NULL;
01516
01517 immediatelyPreviousAssignmentOp = NULL;
01518
01519
01520 foundAssignmentOp = findHeader(line, i, assignmentOperators, false);
01521 foundNonAssignmentOp = findHeader(line, i, nonAssignmentOperators, false);
01522
01523
01524
01525
01526
01527 if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL)
01528 if (foundAssignmentOp->length() < foundNonAssignmentOp->length())
01529 foundAssignmentOp = NULL;
01530 else
01531 foundNonAssignmentOp = NULL;
01532
01533 if (foundNonAssignmentOp != NULL)
01534 {
01535 if (foundNonAssignmentOp->length() > 1)
01536 {
01537 outBuffer.append(foundNonAssignmentOp->substr(1));
01538 i += foundNonAssignmentOp->length() - 1;
01539 }
01540 }
01541
01542 else if (foundAssignmentOp != NULL)
01543 {
01544 if (foundAssignmentOp->length() > 1)
01545 {
01546 outBuffer.append(foundAssignmentOp->substr(1));
01547 i += foundAssignmentOp->length() - 1;
01548 }
01549
01550 if (!isInOperator && !isInTemplate)
01551 {
01552 registerInStatementIndent(line, i, spaceTabCount, 0, false);
01553 immediatelyPreviousAssignmentOp = foundAssignmentOp;
01554 isInStatement = true;
01555 }
01556 }
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594 if (isInOperator)
01595 isInOperator = false;
01596 }
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612 if (!lineStartsInComment
01613 && !blockIndent
01614 && outBuffer.length()>0
01615 && outBuffer[0]=='{'
01616 && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
01617 && !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET)
01618 && shouldIndentBrackettedLine)
01619 --tabCount;
01620
01621 else if (!lineStartsInComment
01622 && outBuffer.length()>0
01623 && outBuffer[0]=='}'
01624 && shouldIndentBrackettedLine )
01625 --tabCount;
01626
01627
01628 else if (!lineStartsInComment
01629 && outBuffer.length()>0
01630 && lineOpeningBlocksNum > 0
01631 && lineOpeningBlocksNum == lineClosingBlocksNum
01632 && previousLastLineHeader != NULL
01633 && previousLastLineHeader != &AS_OPEN_BRACKET)
01634 tabCount -= 1;
01635
01636 if (tabCount < 0)
01637 tabCount = 0;
01638
01639
01640 if (bracketIndent && outBuffer.length()>0 && shouldIndentBrackettedLine)
01641 if (outBuffer[0]=='{' || outBuffer[0]=='}')
01642 tabCount++;
01643
01644
01645 if (isInDefine)
01646 {
01647 if (outBuffer[0] == '#')
01648 {
01649 string preproc = trim(string(outBuffer.c_str() + 1));
01650 if (preproc.COMPARE(0, 6, string("define")) == 0)
01651 {
01652 if (!inStatementIndentStack->empty()
01653 && inStatementIndentStack->back() > 0)
01654 {
01655 defineTabCount = tabCount;
01656 }
01657 else
01658 {
01659 defineTabCount = tabCount - 1;
01660 tabCount--;
01661 }
01662 }
01663 }
01664
01665 tabCount -= defineTabCount;
01666 }
01667
01668 if (tabCount < 0)
01669 tabCount = 0;
01670
01671
01672
01673
01674 prevFinalLineSpaceTabCount = spaceTabCount;
01675 prevFinalLineTabCount = tabCount;
01676
01677 if (shouldForceTabIndentation) {
01678 tabCount += spaceTabCount / indentLength;
01679 spaceTabCount = spaceTabCount % indentLength;
01680 }
01681
01682 outBuffer = preLineWS(spaceTabCount,tabCount) + outBuffer;
01683
01684 if (lastLineHeader != NULL)
01685 previousLastLineHeader = lastLineHeader;
01686
01687 return outBuffer;
01688 }
01689
01690
01691 string ASBeautifier::preLineWS(int spaceTabCount, int tabCount)
01692 {
01693 string ws;
01694
01695 for (int i=0; i<tabCount; i++)
01696 ws += indentString;
01697
01698 while ((spaceTabCount--) > 0)
01699 ws += string(" ");
01700
01701 return ws;
01702
01703 }
01704
01708 void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount,
01709 int minIndent, bool updateParenStack)
01710 {
01711 int inStatementIndent;
01712 int remainingCharNum = line.length() - i;
01713 int nextNonWSChar = 1;
01714
01715 nextNonWSChar = getNextProgramCharDistance(line, i);
01716
01717
01718 if (nextNonWSChar == remainingCharNum)
01719 {
01720 int previousIndent = spaceTabCount;
01721 if (!inStatementIndentStack->empty())
01722 previousIndent = inStatementIndentStack->back();
01723
01724 inStatementIndentStack->push_back( indentLength + previousIndent );
01725 if (updateParenStack)
01726 parenIndentStack->push_back( previousIndent );
01727 return;
01728 }
01729
01730 if (updateParenStack)
01731 parenIndentStack->push_back(i+spaceTabCount);
01732
01733 inStatementIndent = i + nextNonWSChar + spaceTabCount;
01734
01735 if (i + nextNonWSChar < minIndent)
01736 inStatementIndent = minIndent + spaceTabCount;
01737
01738 if (i + nextNonWSChar > maxInStatementIndent)
01739 inStatementIndent = indentLength*2 + spaceTabCount;
01740
01741
01742
01743 if (!inStatementIndentStack->empty() &&
01744 inStatementIndent < inStatementIndentStack->back())
01745 inStatementIndent = inStatementIndentStack->back();
01746
01747 inStatementIndentStack->push_back(inStatementIndent);
01748 }
01749
01754 int ASBeautifier::getNextProgramCharDistance(const string &line, int i)
01755 {
01756 bool inComment = false;
01757 int remainingCharNum = line.length() - i;
01758 int charDistance = 1;
01759 int ch;
01760
01761 for (charDistance = 1; charDistance < remainingCharNum; charDistance++)
01762 {
01763 ch = line[i + charDistance];
01764 if (inComment)
01765 {
01766 if (line.COMPARE(i + charDistance, 2, AS_CLOSE_COMMENT) == 0)
01767 {
01768 charDistance++;
01769 inComment = false;
01770 }
01771 continue;
01772 }
01773 else if (isWhiteSpace(ch))
01774 continue;
01775 else if (ch == '/')
01776 {
01777 if (line.COMPARE(i + charDistance, 2, AS_OPEN_LINE_COMMENT) == 0)
01778 return remainingCharNum;
01779 else if (line.COMPARE(i + charDistance, 2, AS_OPEN_COMMENT) == 0)
01780 {
01781 charDistance++;
01782 inComment = true;
01783 }
01784 }
01785 else
01786 return charDistance;
01787 }
01788
01789 return charDistance;
01790 }
01791
01792
01799 bool ASBeautifier::isLegalNameChar(char ch) const
01800 {
01801 return (isalnum(ch)
01802 || ch=='.' || ch=='_' || (!isCStyle && ch=='$') || (isCStyle && ch=='~'));
01803 }
01804
01805
01811 const string *ASBeautifier::findHeader(const string &line, int i, const vector<const string*> &possibleHeaders, bool checkBoundry)
01812 {
01813 int maxHeaders = possibleHeaders.size();
01814 const string *header = NULL;
01815 int p;
01816
01817 for (p=0; p < maxHeaders; p++)
01818 {
01819 header = possibleHeaders[p];
01820
01821 if (line.COMPARE(i, header->length(), *header) == 0)
01822 {
01823
01824
01825
01826 int lineLength = line.length();
01827 int headerEnd = i + header->length();
01828 char startCh = (*header)[0];
01829 char endCh = 0;
01830 char prevCh = 0;
01831
01832 if (headerEnd < lineLength)
01833 {
01834 endCh = line[headerEnd];
01835 }
01836 if (i > 0)
01837 {
01838 prevCh = line[i-1];
01839 }
01840
01841 if (!checkBoundry)
01842 {
01843 return header;
01844 }
01845 else if (prevCh != 0
01846 && isLegalNameChar(startCh)
01847 && isLegalNameChar(prevCh))
01848 {
01849 return NULL;
01850 }
01851 else if (headerEnd >= lineLength
01852 || !isLegalNameChar(startCh)
01853 || !isLegalNameChar(endCh))
01854 {
01855 return header;
01856 }
01857 else
01858 {
01859 return NULL;
01860 }
01861 }
01862 }
01863
01864 return NULL;
01865 }
01866
01867
01874 bool ASBeautifier::isWhiteSpace(char ch) const
01875 {
01876 return (ch == ' ' || ch == '\t');
01877 }
01878
01886 int ASBeautifier::indexOf(vector<const string*> &container, const string *element)
01887 {
01888 vector<const string*>::const_iterator where;
01889
01890 where= find(container.begin(), container.end(), element);
01891 if (where == container.end())
01892 return -1;
01893 else
01894 return where - container.begin();
01895 }
01896
01903 string ASBeautifier::trim(const string &str)
01904 {
01905
01906 int start = 0;
01907 int end = str.length() - 1;
01908
01909 while (start < end && isWhiteSpace(str[start]))
01910 start++;
01911
01912 while (start <= end && isWhiteSpace(str[end]))
01913 end--;
01914
01915 string returnStr(str, start, end+1-start);
01916 return returnStr;
01917 }
01918
01919 #ifdef USES_NAMESPACE
01920 }
01921 #endif
01922