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