Clover coverage report - net.sourceforge.astyleclipse Coverage Report
Coverage timestamp: 星期六 九月 23 2006 23:19:47 CST
file stats: LOC: 1,702   Methods: 48
NCLOC: 1,001   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ASFormatter.java 0% 0% 0% 0%
coverage
 1    /*
 2    * :tabSize=8:indentSize=4:noTabs=true:maxLineLen=0:
 3    *
 4    * Copyright (c) 1998,1999,2000,2001 Tal Davidson. All rights reserved.
 5    *
 6    * ASFormatter.java
 7    * by Tal Davidson (davidsont@bigfoot.com)
 8    * This file is a part of "Artistic Style" - an indentater and reformatter
 9    * of C++, C, and Java source files.
 10    *
 11    * Ported from C++ to Java by Dirk Moebius (dmoebius@gmx.net).
 12    *
 13    * The "Artistic Style" project, including all files needed to compile it,
 14    * is free software; you can redistribute it and/or use it and/or modify it
 15    * under the terms of EITHER the "Artistic License" OR
 16    * the GNU Library General Public License as published by the Free Software
 17    * Foundation; either version 2 of the License, or (at your option) any later
 18    * version.
 19    *
 20    * This program is distributed in the hope that it will be useful,
 21    * but WITHOUT ANY WARRANTY; without even the implied warranty of
 22    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 23    *
 24    * You should have received a copy of EITHER the "Artistic License" or
 25    * the GNU Library General Public License along with this program.
 26    */
 27   
 28    package net.sourceforge.astyleclipse.astyle;
 29   
 30    import java.util.*;
 31    import java.io.*;
 32    import net.sourceforge.astyleclipse.astyle.util.*;
 33   
 34    /**
 35    * A C/C++/Java source code indenter, formatter and beautifier.
 36    */
 37    public class ASFormatter extends ASBeautifier {
 38   
 39    /**
 40    * Constructor of ASFormatter
 41    */
 42  0 public ASFormatter() {
 43  0 staticInit();
 44   
 45  0 preBracketHeaderStack = null;
 46  0 bracketTypeStack = null;
 47  0 parenStack = null;
 48   
 49  0 sourceIterator = null;
 50  0 bracketFormatMode = NONE_MODE;
 51  0 shouldPadOperators = false;
 52  0 shouldPadParenthesies = false;
 53  0 shouldBreakOneLineBlocks = true;
 54  0 shouldBreakOneLineStatements = true;
 55  0 shouldConvertTabs = false;
 56  0 shouldBreakBlocks = false;
 57  0 shouldBreakClosingHeaderBlocks = false;
 58  0 shouldBreakClosingHeaderBrackets = false;
 59  0 shouldBreakElseIfs = false;
 60    }
 61   
 62    /**
 63    * initialize the ASFormatter. This method should be called every time a
 64    * ASFormatter object is to start formatting a new source file.
 65    * <code>init()</code> receives a reference to a ASSourceIterator object
 66    * that will be used to iterate through the source code.
 67    *
 68    * @param iter
 69    * the ASSourceIterator object.
 70    */
 71  0 public void init(ASSourceIterator si) {
 72  0 super.init(si);
 73  0 sourceIterator = si;
 74   
 75  0 preBracketHeaderStack = new StringStack();
 76  0 bracketTypeStack = new IntegerStack(); // = new vector<BracketType>;
 77  0 bracketTypeStack.push_back(DEFINITION_TYPE);
 78  0 parenStack = new IntegerStack();
 79  0 parenStack.push_back(0);
 80   
 81  0 currentHeader = null;
 82  0 currentLine = "";
 83  0 formattedLine = new StringBuffer();
 84  0 currentChar = ' ';
 85  0 previousCommandChar = ' ';
 86  0 previousNonWSChar = ' ';
 87  0 quoteChar = '"';
 88  0 charNum = 0;
 89  0 previousOperator = null;
 90   
 91  0 isVirgin = true;
 92  0 isInLineComment = false;
 93  0 isInComment = false;
 94  0 isInPreprocessor = false;
 95  0 doesLineStartComment = false;
 96  0 isInQuote = false;
 97  0 isSpecialChar = false;
 98  0 isNonParenHeader = true;
 99  0 foundPreDefinitionHeader = false;
 100  0 foundPreCommandHeader = false;
 101  0 foundQuestionMark = false;
 102  0 isInLineBreak = false;
 103  0 endOfCodeReached = false;
 104  0 isLineReady = false;
 105  0 isPreviousBracketBlockRelated = true;
 106  0 isInPotentialCalculation = false;
 107    // foundOneLineBlock = false;
 108  0 shouldReparseCurrentChar = false;
 109  0 passedSemicolon = false;
 110  0 passedColon = false;
 111  0 isInTemplate = false;
 112  0 shouldBreakLineAfterComments = false;
 113  0 isImmediatelyPostComment = false;
 114  0 isImmediatelyPostEmptyBlock = false;
 115   
 116  0 isPrependPostBlockEmptyLineRequested = false;
 117  0 isAppendPostBlockEmptyLineRequested = false;
 118  0 prependEmptyLine = false;
 119   
 120  0 foundClosingHeader = false;
 121  0 previousReadyFormattedLineLength = 0;
 122   
 123  0 isImmediatelyPostHeader = false;
 124  0 isInHeader = false;
 125    }
 126   
 127    /**
 128    * get the bracket formatting mode.
 129    *
 130    * @see #setBracketFormatMode(int)
 131    */
 132  0 public int getBracketFormatMode() {
 133  0 return bracketFormatMode;
 134    }
 135   
 136    /**
 137    * set the bracket formatting mode. The <code>mode</code> must be one of:
 138    * <ul>
 139    * <li>ASResource.NONE_MODE: no formatting of brackets.</li>
 140    * <li>ASResource.ATTACH_MODE: Java, K&R style bracket placement.</li>
 141    * <li>ASResource.BREAK_MODE: ANSI C/C++ style bracket placement.</li>
 142    * <li>ASResource.BDAC_MODE: Linux style bracket placement.</li>
 143    * </ul>
 144    * </p>
 145    *
 146    * @param mode
 147    * the bracket formatting mode.
 148    * @see astyle.ASResource#NONE_MODE
 149    * @see astyle.ASResource#ATTACH_MODE
 150    * @see astyle.ASResource#BREAK_MODE
 151    * @see astyle.ASResource#BDAC_MODE
 152    */
 153  0 public void setBracketFormatMode(int mode) {
 154  0 bracketFormatMode = mode;
 155    }
 156   
 157    /**
 158    * get closing header bracket breaking mode.
 159    *
 160    * @see #setBreakClosingHeaderBracketsMode(boolean)
 161    */
 162  0 public boolean getBreakClosingHeaderBracketsMode() {
 163  0 return shouldBreakClosingHeaderBrackets;
 164    }
 165   
 166    /**
 167    * set closing header bracket breaking mode. Options:
 168    * <ul>
 169    * <li><code>true</code> brackets just before closing headers (e.g.
 170    * 'else', 'catch') will be broken, even if standard brackets are attached.</li>
 171    * <li><code>false</code> closing header brackets will be treated as
 172    * standard brackets.</li>
 173    * </ul>
 174    *
 175    * @param mode
 176    * the closing header bracket breaking mode.
 177    */
 178  0 public void setBreakClosingHeaderBracketsMode(boolean state) {
 179  0 shouldBreakClosingHeaderBrackets = state;
 180    }
 181   
 182    /**
 183    * get 'else if()' breaking mode. If true, 'else' headers will be broken
 184    * from their succeeding 'if' headers, otherwise 'else' headers will be
 185    * attached to their succeeding 'if' headers.
 186    */
 187  0 public boolean getBreakElseIfsMode() {
 188  0 return shouldBreakElseIfs;
 189    }
 190   
 191    /**
 192    * set 'else if()' breaking mode. If true, 'else' headers will be broken
 193    * from their succeeding 'if' headers, otherwise 'else' headers will be
 194    * attached to their succeeding 'if' headers.
 195    *
 196    * @param mode
 197    * the 'else if()' breaking mode.
 198    */
 199  0 public void setBreakElseIfsMode(boolean state) {
 200  0 shouldBreakElseIfs = state;
 201    }
 202   
 203    /**
 204    * get operator padding mode. If true, statement operators will be padded
 205    * with spaces around them, otherwise statement operators will not be
 206    * padded.
 207    */
 208  0 public boolean getOperatorPaddingMode() {
 209  0 return shouldPadOperators;
 210    }
 211   
 212    /**
 213    * set operator padding mode. If true, statement operators will be padded
 214    * with spaces around them, otherwise statement operators will not be
 215    * padded.
 216    *
 217    * @param mode
 218    * the padding mode.
 219    */
 220  0 public void setOperatorPaddingMode(boolean state) {
 221  0 shouldPadOperators = state;
 222    }
 223   
 224    /**
 225    * get parenthesis padding mode. If true, statement parenthesis will be
 226    * padded with spaces around them, otherwise statement parenthesis will not
 227    * be padded.
 228    */
 229  0 public boolean getParenthesisPaddingMode() {
 230  0 return shouldPadParenthesies;
 231    }
 232   
 233    /**
 234    * set parenthesis padding mode. If true, statement parenthesis will be
 235    * padded with spaces around them, otherwise statement parenthesis will not
 236    * be padded.
 237    *
 238    * @param mode
 239    * the padding mode.
 240    */
 241  0 public void setParenthesisPaddingMode(boolean state) {
 242  0 shouldPadParenthesies = state;
 243    }
 244   
 245    /**
 246    * get option to break/not break one-line blocks.
 247    */
 248  0 public boolean getBreakOneLineBlocksMode() {
 249  0 return shouldBreakOneLineBlocks;
 250    }
 251   
 252    /**
 253    * set option to break/not break one-line blocks.
 254    *
 255    * @param state
 256    * true = break, false = don't break.
 257    */
 258  0 public void setBreakOneLineBlocksMode(boolean state) {
 259  0 shouldBreakOneLineBlocks = state;
 260    }
 261   
 262    /**
 263    * get option to break/not break lines consisting of multiple statements.
 264    */
 265  0 public boolean getSingleStatementsMode() {
 266  0 return shouldBreakOneLineStatements;
 267    }
 268   
 269    /**
 270    * set option to break/not break lines consisting of multiple statements.
 271    *
 272    * @param state
 273    * true = break, false = don't break.
 274    */
 275  0 public void setSingleStatementsMode(boolean state) {
 276  0 shouldBreakOneLineStatements = state;
 277    }
 278   
 279    /**
 280    * get option to convert tabs to spaces.
 281    */
 282  0 public boolean getTabSpaceConversionMode() {
 283  0 return shouldConvertTabs;
 284    }
 285   
 286    /**
 287    * set option to convert tabs to spaces.
 288    *
 289    * @param state
 290    * true = convert, false = don't convert.
 291    */
 292  0 public void setTabSpaceConversionMode(boolean state) {
 293  0 shouldConvertTabs = state;
 294    }
 295   
 296    /**
 297    * get option to break unrelated blocks of code with empty lines.
 298    */
 299  0 public boolean getBreakBlocksMode() {
 300  0 return shouldBreakBlocks;
 301    }
 302   
 303    /**
 304    * set option to break unrelated blocks of code with empty lines.
 305    *
 306    * @param state
 307    * true = convert, false = don't convert.
 308    */
 309  0 public void setBreakBlocksMode(boolean state) {
 310  0 shouldBreakBlocks = state;
 311    }
 312   
 313    /**
 314    * <p>
 315    * get option to break closing header blocks of code (such as 'else',
 316    * 'catch', ...) with empty lines.
 317    * </p>
 318    */
 319  0 public boolean getBreakClosingHeaderBlocksMode() {
 320  0 return shouldBreakClosingHeaderBlocks;
 321    }
 322   
 323    /**
 324    * <p>
 325    * set option to break closing header blocks of code (such as 'else',
 326    * 'catch', ...) with empty lines.
 327    * </p>
 328    *
 329    * @param state
 330    * true = convert, false = don't convert.
 331    */
 332  0 public void setBreakClosingHeaderBlocksMode(boolean state) {
 333  0 shouldBreakClosingHeaderBlocks = state;
 334    }
 335   
 336    /**
 337    * check if there are any indented lines ready to be read by nextLine()
 338    *
 339    * @return are there any indented lines ready?
 340    */
 341  0 public boolean hasMoreLines() {
 342  0 if (!isFormattingEnabled())
 343  0 return super.hasMoreLines();
 344    else
 345  0 return !endOfCodeReached;
 346    }
 347   
 348    /**
 349    * get the next formatted line.
 350    *
 351    * @return a formatted line.
 352    */
 353  0 public String nextLine() {
 354  0 String newHeader;
 355  0 boolean isCharImmediatelyPostComment = false;
 356  0 boolean isPreviousCharPostComment = false;
 357  0 boolean isInVirginLine = isVirgin;
 358  0 boolean isCharImmediatelyPostOpenBlock = false;
 359  0 boolean isCharImmediatelyPostCloseBlock = false;
 360  0 boolean isCharImmediatelyPostTemplate = false;
 361   
 362  0 if (!isFormattingEnabled())
 363  0 return super.nextLine();
 364   
 365  0 while (!isLineReady) {
 366  0 if (shouldReparseCurrentChar)
 367  0 shouldReparseCurrentChar = false;
 368  0 else if (!getNextChar()) {
 369  0 breakLine();
 370  0 return beautify(readyFormattedLine);
 371    } else {
 372    // stuff to do when reading a new character...
 373    // make sure that a virgin '{' at the begining of the file will
 374    // be treated as a block...
 375  0 if (isInVirginLine && currentChar == '{')
 376  0 previousCommandChar = '{';
 377  0 isPreviousCharPostComment = isCharImmediatelyPostComment;
 378  0 isCharImmediatelyPostComment = false;
 379  0 isCharImmediatelyPostTemplate = false;
 380    }
 381   
 382  0 if (isInLineComment) {
 383  0 appendCurrentChar();
 384   
 385    // explicitely break a line when a line comment's end is found.
 386  0 if ( /* bracketFormatMode == ATTACH_MODE && */charNum + 1 == currentLine
 387    .length()) {
 388  0 isInLineBreak = true;
 389  0 isInLineComment = false;
 390  0 isImmediatelyPostComment = true;
 391    // /currentChar = '{'; // danson, commented out this line
 392   
 393    // / danson, explanation of above --
 394    /*
 395    * with code like this:
 396    *
 397    * if (true) {}
 398    * // some comment int i = 0;
 399    *
 400    * after beautifying, it would look like this:
 401    *
 402    * if (true) {}
 403    * // some comment
 404    *
 405    * int i = 0;
 406    *
 407    * with an extra line between the comment and the next line.
 408    * Beautifying again would cause another blank line to be
 409    * inserted. I narrowed the problem down to this block of
 410    * code, and commenting out the above line seems to have
 411    * made it work correctly now.
 412    *
 413    */
 414    // / end comments by danson
 415    }
 416  0 continue;
 417  0 } else if (isInComment) {
 418  0 if (isSequenceReached(AS_CLOSE_COMMENT)) {
 419  0 isInComment = false;
 420  0 isImmediatelyPostComment = true;
 421  0 appendSequence(AS_CLOSE_COMMENT);
 422  0 goForward(1);
 423    } else
 424  0 appendCurrentChar();
 425   
 426  0 continue;
 427    }
 428    // not in line comment or comment
 429  0 else if (isInQuote) {
 430  0 if (isSpecialChar) {
 431  0 isSpecialChar = false;
 432  0 appendCurrentChar();
 433  0 } else if (currentChar == '\\') {
 434  0 isSpecialChar = true;
 435  0 appendCurrentChar();
 436  0 } else if (quoteChar == currentChar) {
 437  0 isInQuote = false;
 438  0 appendCurrentChar();
 439    } else
 440  0 appendCurrentChar();
 441   
 442  0 continue;
 443    }
 444   
 445    // handle white space - needed to simplify the rest.
 446  0 if (isWhiteSpace(currentChar) || isInPreprocessor) {
 447    // DEVEL: if (isLegalNameChar(previousChar) &&
 448    // isLegalNameChar(peekNextChar()))
 449  0 appendCurrentChar();
 450  0 continue;
 451    }
 452   
 453    // not in MIDDLE of quote or comment or white-space of any type...
 454  0 if (isSequenceReached(AS_OPEN_LINE_COMMENT)) {
 455  0 isInLineComment = true;
 456  0 if (shouldPadOperators)
 457  0 appendSpacePad();
 458  0 appendSequence(AS_OPEN_LINE_COMMENT);
 459  0 goForward(1);
 460  0 continue;
 461  0 } else if (isSequenceReached(AS_OPEN_COMMENT)) {
 462  0 isInComment = true;
 463  0 if (shouldPadOperators)
 464  0 appendSpacePad();
 465  0 appendSequence(AS_OPEN_COMMENT);
 466  0 goForward(1);
 467  0 continue;
 468  0 } else if (currentChar == '"' || currentChar == '\'') {
 469  0 isInQuote = true;
 470  0 quoteChar = currentChar;
 471    // if (shouldPadOperators) // BUGFIX: these two lines removed.
 472    // seem to be unneeded, and interfere with L"
 473    // appendSpacePad(); // BUFFIX: TODO make sure the removal of
 474    // these lines doesn't reopen old bugs...
 475  0 appendCurrentChar();
 476  0 continue;
 477    }
 478   
 479    // not in quote or comment or white-space of any type...
 480   
 481    // check if in preprocessor
 482    // isInPreprocessor will be automatically reset at the beginning
 483    // of a new line in getNextChar()
 484  0 if (currentChar == '#')
 485  0 isInPreprocessor = true;
 486   
 487  0 if (isInPreprocessor) {
 488  0 appendCurrentChar();
 489  0 continue;
 490    }
 491   
 492    // not in preprocessor...
 493  0 if (isImmediatelyPostComment) {
 494  0 isImmediatelyPostComment = false;
 495  0 isCharImmediatelyPostComment = true;
 496    }
 497   
 498  0 if (shouldBreakLineAfterComments) {
 499  0 shouldBreakLineAfterComments = false;
 500  0 shouldReparseCurrentChar = true;
 501  0 breakLine();
 502  0 continue;
 503    }
 504   
 505    // reset isImmediatelyPosHeader information
 506  0 if (isImmediatelyPostHeader) {
 507  0 isImmediatelyPostHeader = false;
 508   
 509    // Make sure headers are broken from their succeeding blocks
 510    // (e.g.
 511    // if (isFoo) DoBar();
 512    // should become
 513    // if (isFoo)
 514    // DoBar;
 515    // )
 516    // But treat else if() as a special case which should not be
 517    // broken!
 518  0 if (shouldBreakOneLineStatements) {
 519    // if may break 'else if()'s, then simply break the line
 520  0 if (shouldBreakElseIfs)
 521  0 isInLineBreak = true;
 522    else {
 523    // make sure 'else if()'s are not broken.
 524  0 boolean isInElseIf = false;
 525  0 String upcomingHeader;
 526   
 527  0 upcomingHeader = findHeader(headers);
 528  0 if (currentHeader == AS_ELSE && upcomingHeader == AS_IF)
 529  0 isInElseIf = true;
 530   
 531  0 if (!isInElseIf)
 532  0 isInLineBreak = true; // BUGFIX: SHOULD NOT BE
 533    // breakLine() !!!
 534    }
 535    }
 536    }
 537   
 538  0 if (passedSemicolon) {
 539  0 passedSemicolon = false;
 540  0 if (parenStack.back() == 0) {
 541  0 shouldReparseCurrentChar = true;
 542  0 isInLineBreak = true;
 543  0 continue;
 544    }
 545    }
 546   
 547  0 if (passedColon) {
 548  0 passedColon = false;
 549  0 if (parenStack.back() == 0) {
 550  0 shouldReparseCurrentChar = true;
 551  0 isInLineBreak = true;
 552  0 continue;
 553    }
 554    }
 555   
 556    // Check if in template declaration, e.g. foo<bar> or foo<bar,fig>
 557    // If so, set isInTemplate to true
 558   
 559  0 if (!isInTemplate && currentChar == '<') {
 560  0 int templateDepth = 0;
 561  0 String oper;
 562  0 for (int i = charNum; i < currentLine.length(); i += (oper != null ? oper
 563    .length()
 564    : 1)) {
 565  0 oper = super.findHeader(currentLine, i, operators);
 566   
 567  0 if (oper == AS_LS)
 568  0 templateDepth++;
 569  0 else if (oper == AS_GR) {
 570  0 templateDepth--;
 571  0 if (templateDepth == 0) {
 572    // this is a template!
 573  0 isInTemplate = true;
 574  0 break;
 575    }
 576  0 } else if (oper == AS_COMMA // comma, e.g. A<int, char>
 577    || oper == AS_BIT_AND // reference, e.g. A<int&>
 578    || oper == AS_MULT // pointer, e.g. A<int*>
 579    || oper == AS_COLON_COLON) // ::, e.g. std::string
 580  0 continue;
 581  0 else if (!isLegalNameChar(currentLine.charAt(i))
 582    && !isWhiteSpace(currentLine.charAt(i))) {
 583    // this is not a template -> leave...
 584  0 isInTemplate = false;
 585  0 break;
 586    }
 587    }
 588    }
 589   
 590    // handle parenthesies
 591   
 592  0 if (currentChar == '(' || currentChar == '['
 593    || (isInTemplate && currentChar == '<'))
 594  0 parenStack.incBack();
 595  0 else if (currentChar == ')' || currentChar == ']'
 596    || (isInTemplate && currentChar == '>')) {
 597  0 parenStack.decBack();
 598  0 if (isInTemplate && parenStack.back() == 0) {
 599  0 isInTemplate = false;
 600  0 isCharImmediatelyPostTemplate = true;
 601    }
 602   
 603    // check if this parenthesis closes a header, e.g. ig (...),
 604    // while (...)
 605  0 if (isInHeader && parenStack.back() == 0) {
 606  0 isInHeader = false;
 607  0 isImmediatelyPostHeader = true;
 608    }
 609    }
 610   
 611    // handle brackets
 612   
 613  0 int bracketType = 0;
 614   
 615  0 if (currentChar == '{') {
 616  0 bracketType = getBracketType();
 617  0 foundPreDefinitionHeader = false;
 618  0 foundPreCommandHeader = false;
 619  0 bracketTypeStack.push_back(bracketType);
 620  0 preBracketHeaderStack.push_back(currentHeader);
 621  0 currentHeader = null;
 622  0 isPreviousBracketBlockRelated = !IS_A(bracketType, ARRAY_TYPE);
 623  0 } else if (currentChar == '}') {
 624    // if a request has been made to append a post block empty line,
 625    // but the block exists immediately before a closing bracket,
 626    // then there is not need for the post block empty line.
 627  0 isAppendPostBlockEmptyLineRequested = false;
 628  0 if (!bracketTypeStack.empty()) {
 629  0 bracketType = bracketTypeStack.back();
 630  0 bracketTypeStack.pop_back();
 631  0 isPreviousBracketBlockRelated = !IS_A(bracketType,
 632    ARRAY_TYPE);
 633    }
 634  0 if (!preBracketHeaderStack.empty()) {
 635  0 currentHeader = preBracketHeaderStack.back();
 636  0 preBracketHeaderStack.pop_back();
 637    } else
 638  0 currentHeader = null;
 639    }
 640   
 641  0 if (!IS_A(bracketType, ARRAY_TYPE)) {
 642  0 if (currentChar == '{')
 643  0 parenStack.push_back(0);
 644  0 else if (currentChar == '}')
 645  0 if (!parenStack.empty())
 646  0 parenStack.pop_back();
 647   
 648  0 if (bracketFormatMode != NONE_MODE) {
 649  0 if (currentChar == '{') {
 650  0 if (bracketFormatMode == ATTACH_MODE
 651    || (bracketFormatMode == BDAC_MODE
 652    && bracketTypeStack.size() >= 2 && IS_A(
 653    bracketTypeStack.at(bracketTypeStack
 654    .size() - 2), COMMAND_TYPE)
 655    /* && isInLineBreak */)) {
 656  0 appendSpacePad();
 657  0 if (previousCommandChar != '{'
 658    && previousCommandChar != '}'
 659    && previousCommandChar != ';') // '}', ';'
 660    // chars
 661    // added for
 662    // proper
 663    // handling
 664    // of '{'
 665    // immediately
 666    // after a
 667    // '}' or
 668    // ';'
 669  0 appendCurrentChar(false);
 670    else
 671  0 appendCurrentChar(true);
 672  0 continue;
 673  0 } else if (bracketFormatMode == BREAK_MODE
 674    || (bracketFormatMode == BDAC_MODE
 675    && bracketTypeStack.size() >= 2 && IS_A(
 676    bracketTypeStack.at(bracketTypeStack
 677    .size() - 2), DEFINITION_TYPE))) {
 678  0 if (shouldBreakOneLineBlocks
 679    || !IS_A(bracketType, SINGLE_LINE_TYPE))
 680  0 breakLine();
 681  0 appendCurrentChar();
 682  0 continue;
 683    }
 684  0 } else if (currentChar == '}') {
 685    // boolean origLineBreak = isInLineBreak;
 686   
 687    // mark state of immediately after empty block
 688    // this state will be used for locating brackets that
 689    // appear immedately AFTER an empty block (e.g. '{}
 690    // \n}').
 691  0 if (previousCommandChar == '{')
 692  0 isImmediatelyPostEmptyBlock = true;
 693   
 694  0 if ((!(previousCommandChar == '{' && isPreviousBracketBlockRelated)) // this
 695    // '{'
 696    // does
 697    // not
 698    // close
 699    // an
 700    // empty
 701    // block
 702    && (shouldBreakOneLineBlocks || !IS_A(
 703    bracketType, SINGLE_LINE_TYPE)) // astyle
 704    // is
 705    // allowed
 706    // to
 707    // break
 708    // on
 709    // line
 710    // blocks
 711    && !isImmediatelyPostEmptyBlock) // this '}'
 712    // does not
 713    // immediately
 714    // follow an
 715    // empty
 716    // block
 717    {
 718  0 breakLine();
 719  0 appendCurrentChar();
 720    } else {
 721  0 if (!isCharImmediatelyPostComment)
 722  0 isInLineBreak = false;
 723  0 appendCurrentChar();
 724  0 if (shouldBreakOneLineBlocks
 725    || !IS_A(bracketType, SINGLE_LINE_TYPE))
 726  0 shouldBreakLineAfterComments = true;
 727    }
 728  0 if (shouldBreakBlocks)
 729  0 isAppendPostBlockEmptyLineRequested = true;
 730   
 731  0 continue;
 732    }
 733    }
 734    }
 735   
 736  0 if (((previousCommandChar == '{' && isPreviousBracketBlockRelated) || (previousCommandChar == '}'
 737    && !isImmediatelyPostEmptyBlock // <--
 738    && isPreviousBracketBlockRelated
 739    && !isPreviousCharPostComment // <-- Fixes wrongly
 740    // appended newlines after
 741    // '}' immediately after
 742    // comments...
 743    && peekNextChar() != ' '))
 744    && (shouldBreakOneLineBlocks || !IS_A(bracketTypeStack
 745    .back(), SINGLE_LINE_TYPE))) {
 746  0 isCharImmediatelyPostOpenBlock = (previousCommandChar == '{');
 747  0 isCharImmediatelyPostCloseBlock = (previousCommandChar == '}');
 748  0 previousCommandChar = ' ';
 749  0 isInLineBreak = true; // <----
 750    }
 751   
 752    // reset block handling flags
 753  0 isImmediatelyPostEmptyBlock = false;
 754   
 755    // look for headers
 756  0 if (!isInTemplate) {
 757  0 if ((newHeader = findHeader(headers)) != null) {
 758  0 foundClosingHeader = false;
 759  0 String previousHeader;
 760    // recognize closing headers of do..while and if..else
 761  0 if ((newHeader == AS_ELSE && currentHeader == AS_IF)
 762    || (newHeader == AS_WHILE && currentHeader == AS_DO)
 763    || (newHeader == AS_CATCH && currentHeader == AS_TRY)
 764    || (newHeader == AS_FINALLY && currentHeader == AS_CATCH))
 765  0 foundClosingHeader = true;
 766   
 767  0 previousHeader = currentHeader;
 768  0 currentHeader = newHeader;
 769   
 770    // If in ATTACH or LINUX bracket modes, attach closing
 771    // headers
 772    // (e.g. 'else', 'catch') to their preceding bracket,
 773    // but do not perform the attachment if the
 774    // shouldBreakClosingHeaderBrackets is set!
 775  0 if (!shouldBreakClosingHeaderBrackets
 776    && foundClosingHeader
 777    && (bracketFormatMode == ATTACH_MODE || bracketFormatMode == BDAC_MODE)
 778    && previousNonWSChar == '}') {
 779  0 isInLineBreak = false;
 780  0 appendSpacePad();
 781  0 if (shouldBreakBlocks) {
 782  0 isAppendPostBlockEmptyLineRequested = false;
 783    }
 784    }
 785   
 786    // Check if a template definition as been reached, e.g.
 787    // template<class A>
 788  0 if (newHeader == AS_TEMPLATE)
 789  0 isInTemplate = true;
 790   
 791    // check if the found header is non-paren header
 792  0 isNonParenHeader = nonParenHeaders.contains(newHeader);
 793  0 appendSequence(currentHeader);
 794  0 goForward(currentHeader.length() - 1);
 795    // if padding is on, and a paren-header is found,
 796    // then add a space pad after it.
 797  0 if (shouldPadOperators && !isNonParenHeader)
 798  0 appendSpacePad();
 799   
 800    // Signal that a header has been reached
 801    // *** But treat a closing while() (as in do...while)
 802    // as if it where NOT a header since a closing while()
 803    // should never have a block after it!
 804  0 if (!(foundClosingHeader && currentHeader == AS_WHILE)) {
 805  0 isInHeader = true;
 806  0 if (isNonParenHeader) {
 807  0 isImmediatelyPostHeader = true;
 808  0 isInHeader = false;
 809    }
 810    }
 811   
 812  0 if (currentHeader == AS_IF && previousHeader == AS_ELSE)
 813  0 isInLineBreak = false;
 814   
 815  0 if (shouldBreakBlocks) {
 816  0 if (previousHeader == null && !foundClosingHeader
 817    && !isCharImmediatelyPostOpenBlock) {
 818  0 isPrependPostBlockEmptyLineRequested = true;
 819    }
 820   
 821  0 if (currentHeader == AS_ELSE
 822    || currentHeader == AS_CATCH
 823    || currentHeader == AS_FINALLY
 824    || foundClosingHeader) {
 825  0 isPrependPostBlockEmptyLineRequested = false;
 826    }
 827   
 828  0 if (shouldBreakClosingHeaderBlocks
 829    && isCharImmediatelyPostCloseBlock) {
 830  0 isPrependPostBlockEmptyLineRequested = true;
 831    }
 832    }
 833   
 834  0 continue;
 835  0 } else if ((newHeader = findHeader(preDefinitionHeaders)) != null) {
 836  0 foundPreDefinitionHeader = true;
 837  0 appendSequence(newHeader);
 838  0 goForward(newHeader.length() - 1);
 839  0 if (shouldBreakBlocks) {
 840  0 isPrependPostBlockEmptyLineRequested = true;
 841    }
 842  0 continue;
 843  0 } else if ((newHeader = findHeader(preCommandHeaders)) != null) {
 844  0 foundPreCommandHeader = true;
 845  0 appendSequence(newHeader);
 846  0 goForward(newHeader.length() - 1);
 847  0 continue;
 848    }
 849    }
 850   
 851  0 if (previousNonWSChar == '}' || currentChar == ';') {
 852  0 if (shouldBreakOneLineStatements
 853    && currentChar == ';'
 854    && (shouldBreakOneLineBlocks || !IS_A(bracketTypeStack
 855    .back(), SINGLE_LINE_TYPE))) {
 856  0 passedSemicolon = true;
 857    }
 858   
 859  0 if (shouldBreakBlocks && currentHeader != null
 860    && parenStack.back() == 0) {
 861  0 isAppendPostBlockEmptyLineRequested = true;
 862    }
 863   
 864  0 if (currentChar != ';')
 865  0 currentHeader = null; // DEVEL: is this ok?
 866   
 867  0 foundQuestionMark = false;
 868  0 foundPreDefinitionHeader = false;
 869  0 foundPreCommandHeader = false;
 870  0 isInPotentialCalculation = false;
 871    }
 872   
 873  0 if (currentChar == ':' && shouldBreakOneLineStatements && !isInFor // not
 874    // in a
 875    // for(...
 876    // :
 877    // ...)
 878    // sequence
 879    && !foundQuestionMark // not in a ... ? ... : ... sequence
 880    && !foundPreDefinitionHeader // not in a definition block
 881    // (e.g. class foo : public
 882    // bar
 883    && previousCommandChar != ')' // not immediately after
 884    // closing paren of a method
 885    // header, e.g.
 886    // ASFormatter::ASFormatter(...)
 887    // : ASBeautifier(...)
 888    && previousChar != ':' // not part of '::'
 889    && peekNextChar() != ':') // not part of '::'
 890    {
 891  0 passedColon = true;
 892  0 if (shouldBreakBlocks) {
 893  0 isPrependPostBlockEmptyLineRequested = true;
 894    }
 895    }
 896   
 897  0 if (currentChar == '?') {
 898  0 foundQuestionMark = true;
 899    }
 900   
 901  0 if (shouldPadOperators) {
 902  0 if ((newHeader = findHeader(operators)) != null) {
 903  0 boolean shouldPad = (newHeader != AS_COLON_COLON
 904    && newHeader != AS_PAREN_PAREN
 905    && newHeader != AS_BLPAREN_BLPAREN
 906    && newHeader != AS_PLUS_PLUS
 907    && newHeader != AS_MINUS_MINUS
 908    && newHeader != AS_NOT
 909    && newHeader != AS_BIT_NOT
 910    && newHeader != AS_ARROW
 911    && newHeader != AS_OPERATOR
 912    && !(newHeader == AS_MINUS && isInExponent())
 913    && !(newHeader == AS_PLUS && isInExponent())
 914    && previousOperator != AS_OPERATOR
 915    && !((newHeader == AS_MULT || newHeader == AS_BIT_AND) && isPointerOrReference()) && !((isInTemplate || isCharImmediatelyPostTemplate) && (newHeader == AS_LS || newHeader == AS_GR)));
 916   
 917  0 if (!isInPotentialCalculation)
 918  0 if (assignmentOperators.contains(newHeader))
 919  0 isInPotentialCalculation = true;
 920   
 921    // pad before operator
 922  0 if (shouldPad
 923    && !(newHeader == AS_COLON && !foundQuestionMark)
 924    && newHeader != AS_SEMICOLON
 925    && newHeader != AS_COMMA) {
 926  0 appendSpacePad();
 927    }
 928  0 appendSequence(newHeader);
 929  0 goForward(newHeader.length() - 1);
 930   
 931    // since this block handles '()' and '[]',
 932    // the parenStack must be updated here accordingly!
 933  0 if (newHeader == AS_PAREN_PAREN
 934    || newHeader == AS_BLPAREN_BLPAREN)
 935  0 parenStack.decBack();
 936   
 937  0 currentChar = newHeader.charAt(newHeader.length() - 1);
 938   
 939    // pad after operator
 940    // but do not pad after a '-' that is a urinary-minus.
 941  0 if (shouldPad
 942    && !(newHeader == AS_MINUS && isUrinaryMinus()))
 943  0 appendSpacePad();
 944   
 945  0 previousOperator = newHeader;
 946  0 continue;
 947    }
 948    }
 949   
 950  0 if (shouldPadParenthesies) {
 951  0 if (currentChar == '(' || currentChar == '[') {
 952  0 char peekedChar = peekNextChar();
 953  0 isInPotentialCalculation = true;
 954   
 955  0 appendCurrentChar();
 956   
 957  0 if (!(currentChar == '(' && peekedChar == ')')
 958    && !(currentChar == '[' && peekedChar == ']'))
 959  0 appendSpacePad();
 960  0 continue;
 961  0 } else if (currentChar == ')' || currentChar == ']') {
 962  0 char peekedChar = peekNextChar();
 963  0 if (!(previousChar == '(' && currentChar == ')')
 964    && !(previousChar == '[' && currentChar == ']'))
 965  0 appendSpacePad();
 966   
 967  0 appendCurrentChar();
 968   
 969  0 if (peekedChar != ';' && peekedChar != ','
 970    && peekedChar != '.'
 971    && !(currentChar == ']' && peekedChar == '['))
 972  0 appendSpacePad();
 973  0 continue;
 974    }
 975    }
 976   
 977  0 appendCurrentChar();
 978    }
 979   
 980    // return a beautified (i.e. correctly indented) line.
 981  0 String beautifiedLine;
 982  0 int readyFormattedLineLength = readyFormattedLine.trim().length();
 983   
 984  0 if (prependEmptyLine && readyFormattedLineLength > 0
 985    && previousReadyFormattedLineLength > 0) {
 986  0 isLineReady = true; // signal that a readyFormattedLine is still
 987    // waiting
 988  0 beautifiedLine = beautify("");
 989    } else {
 990  0 isLineReady = false;
 991  0 beautifiedLine = beautify(readyFormattedLine);
 992    }
 993   
 994  0 prependEmptyLine = false;
 995  0 previousReadyFormattedLineLength = readyFormattedLineLength;
 996  0 return beautifiedLine;
 997    }
 998   
 999  0 private static final boolean IS_A(int a, int b) {
 1000  0 return ((a & b) == b);
 1001    }
 1002   
 1003    /**
 1004    * check if formatting options are enabled, in addition to indentation.
 1005    *
 1006    * @return are formatting options enabled?
 1007    */
 1008  0 private boolean isFormattingEnabled() {
 1009  0 return bracketFormatMode != NONE_MODE || shouldPadOperators
 1010    || shouldConvertTabs;
 1011    }
 1012   
 1013    /**
 1014    * jump over several characters.
 1015    *
 1016    * @param i
 1017    * the number of characters to jump over.
 1018    */
 1019  0 private void goForward(int i) {
 1020  0 while (--i >= 0) {
 1021  0 getNextChar();
 1022    }
 1023    }
 1024   
 1025    /**
 1026    * get the next character, increasing the current placement in the process.
 1027    * the new character is inserted into the variable currentChar.
 1028    *
 1029    * @return whether succeded to recieve the new character.
 1030    */
 1031  0 private boolean getNextChar() {
 1032  0 isInLineBreak = false;
 1033  0 boolean isAfterFormattedWhiteSpace = false;
 1034   
 1035  0 if (shouldPadOperators && !isInComment && !isInLineComment
 1036    && !isInQuote && !doesLineStartComment && !isInPreprocessor
 1037    && !isBeforeComment()) {
 1038  0 int len = formattedLine.length();
 1039  0 if (len > 0 && isWhiteSpace(formattedLine.charAt(len - 1)))
 1040  0 isAfterFormattedWhiteSpace = true;
 1041    }
 1042   
 1043  0 previousChar = currentChar;
 1044  0 if (!isWhiteSpace(currentChar)) {
 1045  0 previousNonWSChar = currentChar;
 1046  0 if (!isInComment && !isInLineComment && !isInQuote
 1047    && !isSequenceReached(AS_OPEN_COMMENT)
 1048    && !isSequenceReached(AS_OPEN_LINE_COMMENT)) {
 1049  0 previousCommandChar = previousNonWSChar;
 1050    }
 1051    }
 1052   
 1053  0 int currentLineLength = currentLine.length();
 1054   
 1055  0 if (charNum + 1 < currentLineLength
 1056    && (!isWhiteSpace(peekNextChar()) || isInComment || isInLineComment)) {
 1057  0 currentChar = currentLine.charAt(++charNum);
 1058  0 if (isAfterFormattedWhiteSpace) {
 1059  0 while (isWhiteSpace(currentChar)
 1060    && charNum + 1 < currentLineLength) {
 1061  0 currentChar = currentLine.charAt(++charNum);
 1062    }
 1063    }
 1064   
 1065  0 if (shouldConvertTabs && currentChar == '\t') {
 1066  0 currentChar = ' ';
 1067    }
 1068   
 1069  0 return true;
 1070    } else {
 1071  0 if (sourceIterator.hasMoreLines()) {
 1072  0 currentLine = sourceIterator.nextLine();
 1073    // FIXME: once currentLine could get null
 1074  0 if (currentLine.length() == 0) {
 1075    // FIXME: think about it
 1076  0 currentLine = " ";
 1077    }
 1078   
 1079    // unless reading in the first line of the file,
 1080    // break a new line.
 1081  0 if (!isVirgin) {
 1082  0 isInLineBreak = true;
 1083    } else {
 1084  0 isVirgin = false;
 1085    }
 1086   
 1087  0 isInLineComment = false;
 1088   
 1089  0 trimNewLine();
 1090  0 currentChar = currentLine.charAt(charNum);
 1091   
 1092    // check if is in preprocessor right after the line break and
 1093    // line trimming
 1094  0 if (previousNonWSChar != '\\') {
 1095  0 isInPreprocessor = false;
 1096    }
 1097   
 1098  0 if (shouldConvertTabs && currentChar == '\t') {
 1099  0 currentChar = ' ';
 1100    }
 1101   
 1102  0 return true;
 1103    } else {
 1104  0 endOfCodeReached = true;
 1105  0 return false;
 1106    }
 1107    }
 1108    }
 1109   
 1110    /**
 1111    * peek at the next unread character.
 1112    *
 1113    * @return the next unread character.
 1114    */
 1115  0 private char peekNextChar() {
 1116  0 int peekNum = charNum + 1;
 1117  0 int len = currentLine.length();
 1118  0 char ch = ' ';
 1119   
 1120  0 while (peekNum < len) {
 1121  0 ch = currentLine.charAt(peekNum++);
 1122  0 if (!isWhiteSpace(ch)) {
 1123  0 return ch;
 1124    }
 1125    }
 1126   
 1127  0 if (shouldConvertTabs && ch == '\t') {
 1128  0 ch = ' ';
 1129    }
 1130   
 1131  0 return ch;
 1132    }
 1133   
 1134    /**
 1135    * check if current placement is before a comment or line-comment
 1136    *
 1137    * @return is before a comment or line-comment.
 1138    */
 1139  0 private boolean isBeforeComment() {
 1140  0 int peekNum = charNum + 1;
 1141  0 int len = currentLine.length();
 1142  0 boolean foundComment = false;
 1143   
 1144  0 for (peekNum = charNum + 1; peekNum < len
 1145    && isWhiteSpace(currentLine.charAt(peekNum)); ++peekNum)
 1146    ;
 1147   
 1148  0 if (peekNum < len) {
 1149  0 foundComment = currentLine.regionMatches(peekNum, AS_OPEN_COMMENT,
 1150    0, 2)
 1151    || currentLine.regionMatches(peekNum, AS_OPEN_LINE_COMMENT,
 1152    0, 2);
 1153    }
 1154  0 return foundComment;
 1155    }
 1156   
 1157    /**
 1158    * jump over the leading white space in the current line, IF the line does
 1159    * not begin a comment or is in a preprocessor definition.
 1160    */
 1161  0 private void trimNewLine() {
 1162  0 int len = currentLine.length();
 1163  0 charNum = 0;
 1164   
 1165  0 if (isInComment || isInPreprocessor)
 1166  0 return;
 1167   
 1168  0 while (isWhiteSpace(currentLine.charAt(charNum)) && charNum + 1 < len)
 1169  0 ++charNum;
 1170   
 1171  0 doesLineStartComment = false;
 1172  0 if (isSequenceReached("/*")) {
 1173  0 charNum = 0;
 1174  0 doesLineStartComment = true;
 1175    }
 1176    }
 1177   
 1178    /**
 1179    * check if the currently reached open-bracket (i.e. '{') opens a definition
 1180    * type block (such as a class or namespace), a command block (such as a
 1181    * method block) or a static array.
 1182    *
 1183    * This method takes for granted that the current character is an opening
 1184    * bracket.
 1185    *
 1186    * @return the type of the opened block.
 1187    */
 1188  0 private int getBracketType() {
 1189  0 int returnVal = 0;
 1190  0 if (foundPreDefinitionHeader) {
 1191  0 returnVal = DEFINITION_TYPE;
 1192    } else {
 1193  0 boolean isCommandType;
 1194  0 isCommandType = foundPreCommandHeader
 1195    || (currentHeader != null && isNonParenHeader)
 1196    || (previousCommandChar == ')')
 1197    || (previousCommandChar == ':' && !foundQuestionMark)
 1198    || (previousCommandChar == ';')
 1199    || ((previousCommandChar == '{' || previousCommandChar == '}') && isPreviousBracketBlockRelated);
 1200  0 returnVal = isCommandType ? COMMAND_TYPE : ARRAY_TYPE;
 1201    }
 1202  0 if (isOneLineBlockReached()) {
 1203  0 returnVal |= SINGLE_LINE_TYPE;
 1204    }
 1205  0 return returnVal;
 1206    }
 1207   
 1208    /**
 1209    * check if the currently reached '*' or '&' character is a pointer- or
 1210    * reference symbol, or another operator. This method takes for granted that
 1211    * the current character is either a '*' or '&'.
 1212    *
 1213    * @return whether current character is a pointer- or reference symbol.
 1214    */
 1215  0 private boolean isPointerOrReference() {
 1216  0 boolean isPR = !isInPotentialCalculation
 1217    || IS_A(bracketTypeStack.back(), DEFINITION_TYPE)
 1218    || (!isLegalNameChar(previousNonWSChar)
 1219    && previousNonWSChar != ')' && previousNonWSChar != ']');
 1220  0 if (!isPR) {
 1221  0 char nextChar = peekNextChar();
 1222  0 isPR |= !isWhiteSpace(nextChar) && nextChar != '-'
 1223    && nextChar != '(' && nextChar != '['
 1224    && !isLegalNameChar(nextChar);
 1225    }
 1226  0 return isPR;
 1227    }
 1228   
 1229    /**
 1230    * check if the currently reached '-' character is a urinary minus. This
 1231    * method takes for granted that the current character is a '-'.
 1232    *
 1233    * @return whether the current '-' is a urinary minus.
 1234    */
 1235  0 private boolean isUrinaryMinus() {
 1236  0 return (previousOperator == AS_RETURN || !Character
 1237    .isLetterOrDigit(previousCommandChar))
 1238    && previousCommandChar != '.'
 1239    && previousCommandChar != ')'
 1240    && previousCommandChar != ']';
 1241    }
 1242   
 1243    /**
 1244    * <p>
 1245    * check if the currently reached '-' or '+' character is part of an
 1246    * exponent, i.e. 0.2E-5.
 1247    * </p>
 1248    *
 1249    * This method takes for granted that the current character is a '-' or '+'.
 1250    *
 1251    * @return whether the current char is in an exponent.
 1252    */
 1253  0 private boolean isInExponent() {
 1254  0 int formattedLineLength = formattedLine.length();
 1255  0 if (formattedLineLength >= 2) {
 1256  0 char prevPrevFormattedChar = formattedLine
 1257    .charAt(formattedLineLength - 2);
 1258  0 char prevFormattedChar = formattedLine
 1259    .charAt(formattedLineLength - 1);
 1260  0 return ((prevFormattedChar == 'e' || prevFormattedChar == 'E'))
 1261    && (prevPrevFormattedChar == '.' || Character
 1262    .isDigit(prevPrevFormattedChar));
 1263    } else {
 1264  0 return false;
 1265    }
 1266    }
 1267   
 1268    /**
 1269    * <p>
 1270    * check if a one-line bracket has been reached, i.e. if the currently
 1271    * reached '{' character is closed with a complimentry '}' elsewhere on the
 1272    * current line.
 1273    * </p>
 1274    *
 1275    * @return has a one-line bracket been reached?
 1276    */
 1277  0 private boolean isOneLineBlockReached() {
 1278  0 boolean isInComment = false;
 1279  0 boolean isInQuote = false;
 1280  0 int bracketCount = 1;
 1281  0 int currentLineLength = currentLine.length();
 1282  0 int i = 0;
 1283  0 char ch = ' ';
 1284  0 char quoteChar = ' ';
 1285   
 1286  0 for (i = charNum + 1; i < currentLineLength; ++i) {
 1287  0 ch = currentLine.charAt(i);
 1288  0 if (isInComment) {
 1289  0 if (currentLine.startsWith("*/", i)) {
 1290  0 isInComment = false;
 1291  0 ++i;
 1292    }
 1293  0 continue;
 1294    }
 1295  0 if (ch == '\\') {
 1296  0 ++i;
 1297  0 continue;
 1298    }
 1299  0 if (isInQuote) {
 1300  0 if (ch == quoteChar) {
 1301  0 isInQuote = false;
 1302    }
 1303  0 continue;
 1304    }
 1305  0 if (ch == '"' || ch == '\'') {
 1306  0 isInQuote = true;
 1307  0 quoteChar = ch;
 1308  0 continue;
 1309    }
 1310  0 if (currentLine.startsWith("//", i)) {
 1311  0 break;
 1312    }
 1313  0 if (currentLine.startsWith("/*", i)) {
 1314  0 isInComment = true;
 1315  0 ++i;
 1316  0 continue;
 1317    }
 1318  0 if (ch == '{') {
 1319  0 ++bracketCount;
 1320  0 } else if (ch == '}') {
 1321  0 --bracketCount;
 1322    }
 1323  0 if (bracketCount == 0) {
 1324  0 return true;
 1325    }
 1326    } // for
 1327  0 return false;
 1328    }
 1329   
 1330  0 private void appendChar(char ch) {
 1331  0 appendChar(ch, true);
 1332    }
 1333   
 1334  0 private void appendCurrentChar() {
 1335  0 appendCurrentChar(true);
 1336    }
 1337   
 1338  0 private void appendSequence(String sequence) {
 1339  0 appendSequence(sequence, true);
 1340    }
 1341   
 1342    /**
 1343    * append a character to the current formatted line. Unless disabled (via
 1344    * canBreakLine == false), first check if a line-break has been registered,
 1345    * and if so break the formatted line, and only then append the character
 1346    * into the next formatted line.
 1347    *
 1348    * @param ch
 1349    * the character to append.
 1350    * @param canBreakLine
 1351    * if true, a registered line-break
 1352    */
 1353  0 private void appendChar(char ch, boolean canBreakLine) {
 1354  0 if (canBreakLine && isInLineBreak) {
 1355  0 breakLine();
 1356    }
 1357  0 formattedLine.append(ch);
 1358    }
 1359   
 1360    /**
 1361    * append the CURRENT character (curentChar) to the current formatted line.
 1362    *
 1363    * @param canBreakLine
 1364    * if true, a registered line-break
 1365    */
 1366  0 private void appendCurrentChar(boolean canBreakLine) {
 1367  0 appendChar(currentChar, canBreakLine);
 1368    }
 1369   
 1370    /**
 1371    * append a String sequence to the current formatted line. Unless disabled
 1372    * (via canBreakLine == false), first check if a line-break has been
 1373    * registered, and if so break the formatted line, and only then append the
 1374    * sequence into the next formatted line.
 1375    *
 1376    * @param sequence
 1377    * the sequence to append.
 1378    * @param canBreakLine
 1379    * if true, a registered line-break
 1380    */
 1381  0 private void appendSequence(String sequence, boolean canBreakLine) {
 1382  0 if (canBreakLine && isInLineBreak) {
 1383  0 breakLine();
 1384    }
 1385  0 formattedLine.append(sequence);
 1386    }
 1387   
 1388    /**
 1389    * append a space to the current formattedline, UNLESS the last character is
 1390    * already a white-space character.
 1391    */
 1392  0 private void appendSpacePad() {
 1393  0 int len = formattedLine.length();
 1394  0 if (len == 0 || !isWhiteSpace(formattedLine.charAt(len - 1))) {
 1395  0 formattedLine.append(' ');
 1396    }
 1397    }
 1398   
 1399    /**
 1400    * register a line break for the formatted line.
 1401    */
 1402  0 private void breakLine() {
 1403  0 isLineReady = true;
 1404  0 isInLineBreak = false;
 1405    // queue an empty line prepend request if one exists
 1406  0 prependEmptyLine = isPrependPostBlockEmptyLineRequested;
 1407  0 readyFormattedLine = formattedLine.toString();
 1408  0 if (isAppendPostBlockEmptyLineRequested) {
 1409  0 isAppendPostBlockEmptyLineRequested = false;
 1410  0 isPrependPostBlockEmptyLineRequested = true;
 1411    } else {
 1412  0 isPrependPostBlockEmptyLineRequested = false;
 1413    }
 1414  0 formattedLine = new StringBuffer();
 1415    }
 1416   
 1417    /**
 1418    * check if a specific sequence exists in the current placement of the
 1419    * current line.
 1420    *
 1421    * @param sequence
 1422    * the sequence to be checked
 1423    * @return whether sequence has been reached.
 1424    */
 1425  0 private final boolean isSequenceReached(String sequence) {
 1426  0 return currentLine.regionMatches(charNum, sequence, 0, sequence
 1427    .length());
 1428    }
 1429   
 1430  0 private String findHeader(StringStack headers) {
 1431  0 return findHeader(headers, true);
 1432    }
 1433   
 1434    /**
 1435    * check if one of a set of headers has been reached in the current position
 1436    * of the current line.
 1437    *
 1438    * @param headers
 1439    * a vector of headers
 1440    * @param checkBoundry
 1441    * @return a pointer to the found header, or a null if no header has been
 1442    * reached.
 1443    */
 1444  0 private String findHeader(StringStack headers, boolean checkBoundry) {
 1445  0 return super.findHeader(currentLine, charNum, headers, checkBoundry);
 1446    }
 1447   
 1448    /**
 1449    * initialization of static data of ASFormatter.
 1450    */
 1451  0 private void staticInit() {
 1452  0 if (calledInitStatic) {
 1453  0 return;
 1454    }
 1455   
 1456  0 calledInitStatic = true;
 1457   
 1458  0 headers.push_back(AS_IF);
 1459  0 headers.push_back(AS_ELSE);
 1460  0 headers.push_back(AS_DO);
 1461  0 headers.push_back(AS_WHILE);
 1462  0 headers.push_back(AS_FOR);
 1463  0 headers.push_back(AS_SYNCHRONIZED);
 1464  0 headers.push_back(AS_TRY);
 1465  0 headers.push_back(AS_CATCH);
 1466  0 headers.push_back(AS_FINALLY);
 1467  0 headers.push_back(AS_SWITCH);
 1468  0 headers.push_back(AS_TEMPLATE);
 1469   
 1470  0 nonParenHeaders.push_back(AS_ELSE);
 1471  0 nonParenHeaders.push_back(AS_DO);
 1472  0 nonParenHeaders.push_back(AS_TRY);
 1473  0 nonParenHeaders.push_back(AS_FINALLY);
 1474    // nonParenHeaders.push_back(AS_TEMPLATE);
 1475   
 1476  0 preDefinitionHeaders.push_back(AS_CLASS);
 1477  0 preDefinitionHeaders.push_back(AS_INTERFACE);
 1478  0 preDefinitionHeaders.push_back(AS_NAMESPACE);
 1479  0 preDefinitionHeaders.push_back(AS_STRUCT);
 1480   
 1481  0 preCommandHeaders.push_back(AS_EXTERN);
 1482  0 preCommandHeaders.push_back(AS_THROWS);
 1483  0 preCommandHeaders.push_back(AS_CONST);
 1484   
 1485  0 preprocessorHeaders.push_back(AS_BAR_DEFINE);
 1486    // DEVEL: removed the following lines
 1487    // preprocessorHeaders.push_back(AS_BAR_INCLUDE);
 1488    // preprocessorHeaders.push_back(AS_BAR_IF); // #if or #ifdef
 1489    // preprocessorHeaders.push_back(AS_BAR_EL); // #else or #elif
 1490    // preprocessorHeaders.push_back(AS_BAR_ENDIF);
 1491   
 1492  0 operators.push_back(AS_PLUS_ASSIGN);
 1493  0 operators.push_back(AS_MINUS_ASSIGN);
 1494  0 operators.push_back(AS_MULT_ASSIGN);
 1495  0 operators.push_back(AS_DIV_ASSIGN);
 1496  0 operators.push_back(AS_MOD_ASSIGN);
 1497  0 operators.push_back(AS_OR_ASSIGN);
 1498  0 operators.push_back(AS_AND_ASSIGN);
 1499  0 operators.push_back(AS_XOR_ASSIGN);
 1500  0 operators.push_back(AS_EQUAL);
 1501  0 operators.push_back(AS_PLUS_PLUS);
 1502  0 operators.push_back(AS_MINUS_MINUS);
 1503  0 operators.push_back(AS_NOT_EQUAL);
 1504  0 operators.push_back(AS_GR_EQUAL);
 1505  0 operators.push_back(AS_GR_GR_GR_ASSIGN);
 1506  0 operators.push_back(AS_GR_GR_ASSIGN);
 1507  0 operators.push_back(AS_GR_GR_GR);
 1508  0 operators.push_back(AS_GR_GR);
 1509  0 operators.push_back(AS_LS_EQUAL);
 1510  0 operators.push_back(AS_LS_LS_LS_ASSIGN);
 1511  0 operators.push_back(AS_LS_LS_ASSIGN);
 1512  0 operators.push_back(AS_LS_LS_LS);
 1513  0 operators.push_back(AS_LS_LS);
 1514  0 operators.push_back(AS_ARROW);
 1515  0 operators.push_back(AS_AND);
 1516  0 operators.push_back(AS_OR);
 1517  0 operators.push_back(AS_COLON_COLON);
 1518   
 1519    // BUGFIX: removed the following lines:
 1520    // operators.push_back(AS_PAREN_PAREN);
 1521    // operators.push_back(AS_BLPAREN_BLPAREN);
 1522   
 1523  0 operators.push_back(AS_PLUS);
 1524  0 operators.push_back(AS_MINUS);
 1525  0 operators.push_back(AS_MULT);
 1526  0 operators.push_back(AS_DIV);
 1527  0 operators.push_back(AS_MOD);
 1528  0 operators.push_back(AS_QUESTION);
 1529  0 operators.push_back(AS_COLON);
 1530  0 operators.push_back(AS_ASSIGN);
 1531  0 operators.push_back(AS_LS);
 1532  0 operators.push_back(AS_GR);
 1533  0 operators.push_back(AS_NOT);
 1534  0 operators.push_back(AS_BIT_OR);
 1535  0 operators.push_back(AS_BIT_AND);
 1536  0 operators.push_back(AS_BIT_NOT);
 1537  0 operators.push_back(AS_BIT_XOR);
 1538  0 operators.push_back(AS_OPERATOR);
 1539  0 operators.push_back(AS_COMMA);
 1540    // operators.push_back(AS_SEMICOLON);
 1541  0 operators.push_back(AS_RETURN);
 1542   
 1543  0 assignmentOperators.push_back(AS_PLUS_ASSIGN);
 1544  0 assignmentOperators.push_back(AS_MINUS_ASSIGN);
 1545  0 assignmentOperators.push_back(AS_MULT_ASSIGN);
 1546  0 assignmentOperators.push_back(AS_DIV_ASSIGN);
 1547  0 assignmentOperators.push_back(AS_MOD_ASSIGN);
 1548  0 assignmentOperators.push_back(AS_XOR_ASSIGN);
 1549  0 assignmentOperators.push_back(AS_OR_ASSIGN);
 1550  0 assignmentOperators.push_back(AS_AND_ASSIGN);
 1551  0 assignmentOperators.push_back(AS_GR_GR_GR_ASSIGN);
 1552  0 assignmentOperators.push_back(AS_LS_LS_LS_ASSIGN);
 1553  0 assignmentOperators.push_back(AS_ASSIGN);
 1554    }
 1555   
 1556    // STATIC FIELDS
 1557   
 1558    private static boolean calledInitStatic = false;
 1559   
 1560    private static StringStack headers = new StringStack();
 1561   
 1562    private static StringStack nonParenHeaders = new StringStack();
 1563   
 1564    private static StringStack preprocessorHeaders = new StringStack();
 1565   
 1566    private static StringStack preDefinitionHeaders = new StringStack();
 1567   
 1568    private static StringStack preCommandHeaders = new StringStack();
 1569   
 1570    private static StringStack operators = new StringStack();
 1571   
 1572    private static StringStack assignmentOperators = new StringStack();
 1573   
 1574    // MEMBER FIELDS
 1575   
 1576    private ASSourceIterator sourceIterator;
 1577   
 1578    private StringStack preBracketHeaderStack;
 1579   
 1580    private IntegerStack bracketTypeStack;
 1581   
 1582    private IntegerStack parenStack;
 1583   
 1584    private String readyFormattedLine;
 1585   
 1586    private String currentLine;
 1587   
 1588    private StringBuffer formattedLine;
 1589   
 1590    private String currentHeader;
 1591   
 1592    private String previousOperator;
 1593   
 1594    private char currentChar;
 1595   
 1596    private char previousChar;
 1597   
 1598    private char previousNonWSChar;
 1599   
 1600    private char previousCommandChar;
 1601   
 1602    private char quoteChar;
 1603   
 1604    private int charNum;
 1605   
 1606    private int bracketFormatMode;
 1607   
 1608    private boolean isVirgin;
 1609   
 1610    private boolean shouldPadOperators;
 1611   
 1612    private boolean shouldPadParenthesies;
 1613   
 1614    private boolean shouldConvertTabs;
 1615   
 1616    private boolean isInLineComment;
 1617   
 1618    private boolean isInComment;
 1619   
 1620    private boolean isInPreprocessor;
 1621   
 1622    private boolean isInTemplate; // true both in template definitions (e.g.
 1623    // template<class A>) and template usage
 1624    // (e.g. F<int>).
 1625   
 1626    private boolean doesLineStartComment;
 1627   
 1628    private boolean isInQuote;
 1629   
 1630    private boolean isSpecialChar;
 1631   
 1632    private boolean isNonParenHeader;
 1633   
 1634    private boolean foundQuestionMark;
 1635   
 1636    private boolean foundPreDefinitionHeader;
 1637   
 1638    private boolean foundPreCommandHeader;
 1639   
 1640    private boolean isInLineBreak;
 1641   
 1642    private boolean isInClosingBracketLineBreak;
 1643   
 1644    private boolean endOfCodeReached;
 1645   
 1646    private boolean isLineReady;
 1647   
 1648    private boolean isPreviousBracketBlockRelated;
 1649   
 1650    private boolean isInPotentialCalculation;
 1651   
 1652    // private boolean foundOneLineBlock;
 1653    private boolean shouldBreakOneLineBlocks;
 1654   
 1655    private boolean shouldReparseCurrentChar;
 1656   
 1657    private boolean shouldBreakOneLineStatements;
 1658   
 1659    private boolean shouldBreakLineAfterComments;
 1660   
 1661    private boolean shouldBreakClosingHeaderBrackets;
 1662   
 1663    private boolean shouldBreakElseIfs;
 1664   
 1665    private boolean passedSemicolon;
 1666   
 1667    private boolean passedColon;
 1668   
 1669    private boolean isImmediatelyPostComment;
 1670   
 1671    private boolean isImmediatelyPostEmptyBlock;
 1672   
 1673    private boolean shouldBreakBlocks;
 1674   
 1675    private boolean shouldBreakClosingHeaderBlocks;
 1676   
 1677    private boolean isPrependPostBlockEmptyLineRequested;
 1678   
 1679    private boolean isAppendPostBlockEmptyLineRequested;
 1680   
 1681    private boolean prependEmptyLine;
 1682   
 1683    private boolean foundClosingHeader;
 1684   
 1685    private int previousReadyFormattedLineLength;
 1686   
 1687    private boolean isInHeader;
 1688   
 1689    private boolean isImmediatelyPostHeader;
 1690   
 1691    // CONSTANTS
 1692   
 1693    // bracket types
 1694    private final static int DEFINITION_TYPE = 1;
 1695   
 1696    private final static int COMMAND_TYPE = 2;
 1697   
 1698    private final static int ARRAY_TYPE = 4;
 1699   
 1700    private final static int SINGLE_LINE_TYPE = 8;
 1701   
 1702    }