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