1 // astyle.h 2 // Copyright (c) 2018 by Jim Pattee <jimp03@email.com>. 3 // This code is licensed under the MIT License. 4 // License.md describes the conditions under which this software may be distributed. 5 6 #ifndef ASTYLE_H 7 #define ASTYLE_H 8 9 //----------------------------------------------------------------------------- 10 // headers 11 //----------------------------------------------------------------------------- 12 13 #ifdef __VMS 14 #define __USE_STD_IOSTREAM 1 15 #include <assert> 16 #else 17 #include <cassert> 18 #endif 19 20 #include <cctype> 21 #include <iostream> // for cout 22 #include <memory> 23 #include <string> 24 #include <vector> 25 26 #ifdef __GNUC__ 27 #include <cstring> // need both string and cstring for GCC 28 #endif 29 30 //----------------------------------------------------------------------------- 31 // declarations 32 //----------------------------------------------------------------------------- 33 34 #ifdef _MSC_VER 35 #pragma warning(disable: 4267) // conversion from size_t to int 36 #endif 37 38 #ifdef __BORLANDC__ 39 #pragma warn -8004 // variable is assigned a value that is never used 40 #endif 41 42 #ifdef __GNUC__ 43 #pragma GCC diagnostic ignored "-Wconversion" 44 #endif 45 46 #ifdef __INTEL_COMPILER 47 #pragma warning(disable: 383) // value copied to temporary, reference to temporary used 48 #pragma warning(disable: 981) // operands are evaluated in unspecified order 49 #endif 50 51 #ifdef __clang__ 52 #pragma clang diagnostic ignored "-Wshorten-64-to-32" 53 #endif 54 55 //----------------------------------------------------------------------------- 56 // astyle namespace 57 //----------------------------------------------------------------------------- 58 59 namespace astyle { 60 // 61 using namespace std; 62 63 //---------------------------------------------------------------------------- 64 // definitions 65 //---------------------------------------------------------------------------- 66 67 enum FileType { C_TYPE = 0, JAVA_TYPE = 1, SHARP_TYPE = 2 }; 68 69 /* The enums below are not recognized by 'vectors' in Microsoft Visual C++ 70 V5 when they are part of a namespace!!! Use Visual C++ V6 or higher. 71 */ 72 enum FormatStyle 73 { 74 STYLE_NONE, 75 STYLE_ALLMAN, 76 STYLE_JAVA, 77 STYLE_KR, 78 STYLE_STROUSTRUP, 79 STYLE_WHITESMITH, 80 STYLE_VTK, 81 STYLE_RATLIFF, 82 STYLE_GNU, 83 STYLE_LINUX, 84 STYLE_HORSTMANN, 85 STYLE_1TBS, 86 STYLE_GOOGLE, 87 STYLE_MOZILLA, 88 STYLE_PICO, 89 STYLE_LISP 90 }; 91 92 enum BraceMode 93 { 94 NONE_MODE, 95 ATTACH_MODE, 96 BREAK_MODE, 97 LINUX_MODE, 98 RUN_IN_MODE // broken braces 99 }; 100 101 // maximum value for int is 16,384 (total value of 32,767) 102 enum BraceType 103 { 104 NULL_TYPE = 0, 105 NAMESPACE_TYPE = 1, // also a DEFINITION_TYPE 106 CLASS_TYPE = 2, // also a DEFINITION_TYPE 107 STRUCT_TYPE = 4, // also a DEFINITION_TYPE 108 INTERFACE_TYPE = 8, // also a DEFINITION_TYPE 109 DEFINITION_TYPE = 16, 110 COMMAND_TYPE = 32, 111 ARRAY_NIS_TYPE = 64, // also an ARRAY_TYPE 112 ENUM_TYPE = 128, // also an ARRAY_TYPE 113 INIT_TYPE = 256, // also an ARRAY_TYPE 114 ARRAY_TYPE = 512, 115 EXTERN_TYPE = 1024, // extern "C", not a command type extern 116 EMPTY_BLOCK_TYPE = 2048, // also a SINGLE_LINE_TYPE 117 BREAK_BLOCK_TYPE = 4096, // also a SINGLE_LINE_TYPE 118 SINGLE_LINE_TYPE = 8192 119 }; 120 121 enum MinConditional 122 { 123 MINCOND_ZERO, 124 MINCOND_ONE, 125 MINCOND_TWO, 126 MINCOND_ONEHALF, 127 MINCOND_END 128 }; 129 130 enum ObjCColonPad 131 { 132 COLON_PAD_NO_CHANGE, 133 COLON_PAD_NONE, 134 COLON_PAD_ALL, 135 COLON_PAD_AFTER, 136 COLON_PAD_BEFORE 137 }; 138 139 enum PointerAlign 140 { 141 PTR_ALIGN_NONE, 142 PTR_ALIGN_TYPE, 143 PTR_ALIGN_MIDDLE, 144 PTR_ALIGN_NAME 145 }; 146 147 enum ReferenceAlign 148 { 149 REF_ALIGN_NONE = PTR_ALIGN_NONE, 150 REF_ALIGN_TYPE = PTR_ALIGN_TYPE, 151 REF_ALIGN_MIDDLE = PTR_ALIGN_MIDDLE, 152 REF_ALIGN_NAME = PTR_ALIGN_NAME, 153 REF_SAME_AS_PTR 154 }; 155 156 enum FileEncoding 157 { 158 ENCODING_8BIT, // includes UTF-8 without BOM 159 UTF_8BOM, // UTF-8 with BOM 160 UTF_16BE, 161 UTF_16LE, // Windows default 162 UTF_32BE, 163 UTF_32LE 164 }; 165 166 enum LineEndFormat 167 { 168 LINEEND_DEFAULT, // Use line break that matches most of the file 169 LINEEND_WINDOWS, 170 LINEEND_LINUX, 171 LINEEND_MACOLD, 172 LINEEND_CRLF = LINEEND_WINDOWS, 173 LINEEND_LF = LINEEND_LINUX, 174 LINEEND_CR = LINEEND_MACOLD 175 }; 176 177 //----------------------------------------------------------------------------- 178 // Class ASSourceIterator 179 // A pure virtual class is used by ASFormatter and ASBeautifier instead of 180 // ASStreamIterator. This allows programs using AStyle as a plug-in to define 181 // their own ASStreamIterator. The ASStreamIterator class must inherit 182 // this class. 183 //----------------------------------------------------------------------------- 184 185 class ASSourceIterator 186 { 187 public: ASSourceIterator()188 ASSourceIterator() {} ~ASSourceIterator()189 virtual ~ASSourceIterator() {} 190 virtual streamoff getPeekStart() const = 0; 191 virtual int getStreamLength() const = 0; 192 virtual bool hasMoreLines() const = 0; 193 virtual string nextLine(bool emptyLineWasDeleted = false) = 0; 194 virtual string peekNextLine() = 0; 195 virtual void peekReset() = 0; 196 virtual streamoff tellg() = 0; 197 }; 198 199 //----------------------------------------------------------------------------- 200 // Class ASPeekStream 201 // A small class using RAII to peek ahead in the ASSourceIterator stream 202 // and to reset the ASSourceIterator pointer in the destructor. 203 // It enables a return from anywhere in the method. 204 //----------------------------------------------------------------------------- 205 206 class ASPeekStream 207 { 208 private: 209 ASSourceIterator* sourceIterator; 210 bool needReset; // reset sourceIterator to the original position 211 212 public: ASPeekStream(ASSourceIterator * sourceIterator_)213 explicit ASPeekStream(ASSourceIterator* sourceIterator_) 214 { sourceIterator = sourceIterator_; needReset = false; } 215 ~ASPeekStream()216 ~ASPeekStream() 217 { if (needReset) sourceIterator->peekReset(); } 218 hasMoreLines()219 bool hasMoreLines() const 220 { return sourceIterator->hasMoreLines(); } 221 peekNextLine()222 string peekNextLine() 223 { needReset = true; return sourceIterator->peekNextLine(); } 224 }; 225 226 227 //----------------------------------------------------------------------------- 228 // Class ASResource 229 //----------------------------------------------------------------------------- 230 231 class ASResource 232 { 233 public: 234 void buildAssignmentOperators(vector<const string*>* assignmentOperators); 235 void buildCastOperators(vector<const string*>* castOperators); 236 void buildHeaders(vector<const string*>* headers, int fileType, bool beautifier = false); 237 void buildIndentableMacros(vector<const pair<const string, const string>* >* indentableMacros); 238 void buildIndentableHeaders(vector<const string*>* indentableHeaders); 239 void buildNonAssignmentOperators(vector<const string*>* nonAssignmentOperators); 240 void buildNonParenHeaders(vector<const string*>* nonParenHeaders, int fileType, bool beautifier = false); 241 void buildOperators(vector<const string*>* operators, int fileType); 242 void buildPreBlockStatements(vector<const string*>* preBlockStatements, int fileType); 243 void buildPreCommandHeaders(vector<const string*>* preCommandHeaders, int fileType); 244 void buildPreDefinitionHeaders(vector<const string*>* preDefinitionHeaders, int fileType); 245 246 public: 247 static const string AS_IF, AS_ELSE; 248 static const string AS_DO, AS_WHILE; 249 static const string AS_FOR; 250 static const string AS_SWITCH, AS_CASE, AS_DEFAULT; 251 static const string AS_TRY, AS_CATCH, AS_THROW, AS_THROWS, AS_FINALLY, AS_USING; 252 static const string _AS_TRY, _AS_FINALLY, _AS_EXCEPT; 253 static const string AS_PUBLIC, AS_PROTECTED, AS_PRIVATE; 254 static const string AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE; 255 static const string AS_MODULE; 256 static const string AS_END; 257 static const string AS_SELECTOR; 258 static const string AS_EXTERN, AS_ENUM; 259 static const string AS_FINAL, AS_OVERRIDE; 260 static const string AS_STATIC, AS_CONST, AS_SEALED, AS_VOLATILE, AS_NEW, AS_DELETE; 261 static const string AS_NOEXCEPT, AS_INTERRUPT, AS_AUTORELEASEPOOL; 262 static const string AS_WHERE, AS_LET, AS_SYNCHRONIZED; 263 static const string AS_OPERATOR, AS_TEMPLATE; 264 static const string AS_OPEN_BRACE, AS_CLOSE_BRACE; 265 static const string AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT; 266 static const string AS_BAR_DEFINE, AS_BAR_INCLUDE, AS_BAR_IF, AS_BAR_EL, AS_BAR_ENDIF; 267 static const string AS_AUTO, AS_RETURN; 268 static const string AS_CIN, AS_COUT, AS_CERR; 269 static const string AS_ASSIGN, AS_PLUS_ASSIGN, AS_MINUS_ASSIGN, AS_MULT_ASSIGN; 270 static const string AS_DIV_ASSIGN, AS_MOD_ASSIGN, AS_XOR_ASSIGN, AS_OR_ASSIGN, AS_AND_ASSIGN; 271 static const string AS_GR_GR_ASSIGN, AS_LS_LS_ASSIGN, AS_GR_GR_GR_ASSIGN, AS_LS_LS_LS_ASSIGN; 272 static const string AS_GCC_MIN_ASSIGN, AS_GCC_MAX_ASSIGN; 273 static const string AS_EQUAL, AS_PLUS_PLUS, AS_MINUS_MINUS, AS_NOT_EQUAL, AS_GR_EQUAL; 274 static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS, AS_GR_GR_GR, AS_GR_GR; 275 static const string AS_QUESTION_QUESTION, AS_LAMBDA; 276 static const string AS_ARROW, AS_AND, AS_OR; 277 static const string AS_SCOPE_RESOLUTION; 278 static const string AS_PLUS, AS_MINUS, AS_MULT, AS_DIV, AS_MOD, AS_GR, AS_LS; 279 static const string AS_NOT, AS_BIT_XOR, AS_BIT_OR, AS_BIT_AND, AS_BIT_NOT; 280 static const string AS_QUESTION, AS_COLON, AS_SEMICOLON, AS_COMMA; 281 static const string AS_ASM, AS__ASM__, AS_MS_ASM, AS_MS__ASM; 282 static const string AS_QFOREACH, AS_QFOREVER, AS_FOREVER; 283 static const string AS_FOREACH, AS_LOCK, AS_UNSAFE, AS_FIXED; 284 static const string AS_GET, AS_SET, AS_ADD, AS_REMOVE; 285 static const string AS_DELEGATE, AS_UNCHECKED; 286 static const string AS_CONST_CAST, AS_DYNAMIC_CAST, AS_REINTERPRET_CAST, AS_STATIC_CAST; 287 static const string AS_NS_DURING, AS_NS_HANDLER; 288 }; // Class ASResource 289 290 //----------------------------------------------------------------------------- 291 // Class ASBase 292 // Functions definitions are at the end of ASResource.cpp. 293 //----------------------------------------------------------------------------- 294 295 class ASBase : protected ASResource 296 { 297 private: 298 // all variables should be set by the "init" function 299 int baseFileType; // a value from enum FileType 300 301 protected: ASBase()302 ASBase() : baseFileType(C_TYPE) { } 303 304 protected: // inline functions init(int fileTypeArg)305 void init(int fileTypeArg) { baseFileType = fileTypeArg; } isCStyle()306 bool isCStyle() const { return (baseFileType == C_TYPE); } isJavaStyle()307 bool isJavaStyle() const { return (baseFileType == JAVA_TYPE); } isSharpStyle()308 bool isSharpStyle() const { return (baseFileType == SHARP_TYPE); } isWhiteSpace(char ch)309 bool isWhiteSpace(char ch) const { return (ch == ' ' || ch == '\t'); } 310 311 protected: // functions definitions are at the end of ASResource.cpp 312 const string* findHeader(const string& line, int i, 313 const vector<const string*>* possibleHeaders) const; 314 bool findKeyword(const string& line, int i, const string& keyword) const; 315 const string* findOperator(const string& line, int i, 316 const vector<const string*>* possibleOperators) const; 317 string getCurrentWord(const string& line, size_t index) const; 318 bool isDigit(char ch) const; 319 bool isLegalNameChar(char ch) const; 320 bool isCharPotentialHeader(const string& line, size_t i) const; 321 bool isCharPotentialOperator(char ch) const; 322 bool isDigitSeparator(const string& line, int i) const; 323 char peekNextChar(const string& line, int i) const; 324 325 }; // Class ASBase 326 327 //----------------------------------------------------------------------------- 328 // Class ASBeautifier 329 //----------------------------------------------------------------------------- 330 331 class ASBeautifier : protected ASBase 332 { 333 public: 334 ASBeautifier(); 335 virtual ~ASBeautifier(); 336 virtual void init(ASSourceIterator* iter); 337 virtual string beautify(const string& originalLine); 338 void setCaseIndent(bool state); 339 void setClassIndent(bool state); 340 void setContinuationIndentation(int indent = 1); 341 void setCStyle(); 342 void setDefaultTabLength(); 343 void setEmptyLineFill(bool state); 344 void setForceTabXIndentation(int length); 345 void setAfterParenIndent(bool state); 346 void setJavaStyle(); 347 void setLabelIndent(bool state); 348 void setMaxContinuationIndentLength(int max); 349 void setMaxInStatementIndentLength(int max); 350 void setMinConditionalIndentOption(int min); 351 void setMinConditionalIndentLength(); 352 void setModeManuallySet(bool state); 353 void setModifierIndent(bool state); 354 void setNamespaceIndent(bool state); 355 void setAlignMethodColon(bool state); 356 void setSharpStyle(); 357 void setSpaceIndentation(int length = 4); 358 void setSwitchIndent(bool state); 359 void setTabIndentation(int length = 4, bool forceTabs = false); 360 void setPreprocDefineIndent(bool state); 361 void setPreprocConditionalIndent(bool state); 362 int getBeautifierFileType() const; 363 int getFileType() const; 364 int getIndentLength() const; 365 int getTabLength() const; 366 string getIndentString() const; 367 string getNextWord(const string& line, size_t currPos) const; 368 bool getAlignMethodColon() const; 369 bool getBraceIndent() const; 370 bool getBlockIndent() const; 371 bool getCaseIndent() const; 372 bool getClassIndent() const; 373 bool getEmptyLineFill() const; 374 bool getForceTabIndentation() const; 375 bool getModeManuallySet() const; 376 bool getModifierIndent() const; 377 bool getNamespaceIndent() const; 378 bool getPreprocDefineIndent() const; 379 bool getSwitchIndent() const; 380 381 protected: 382 void deleteBeautifierVectors(); 383 int getNextProgramCharDistance(const string& line, int i) const; 384 int indexOf(const vector<const string*>& container, const string* element) const; 385 void setBlockIndent(bool state); 386 void setBraceIndent(bool state); 387 void setBraceIndentVtk(bool state); 388 string extractPreprocessorStatement(const string& line) const; 389 string trim(const string& str) const; 390 string rtrim(const string& str) const; 391 392 // variables set by ASFormatter - must be updated in activeBeautifierStack 393 int inLineNumber; 394 int runInIndentContinuation; 395 int nonInStatementBrace; 396 int objCColonAlignSubsequent; // for subsequent lines not counting indent 397 bool lineCommentNoBeautify; 398 bool isElseHeaderIndent; 399 bool isCaseHeaderCommentIndent; 400 bool isNonInStatementArray; 401 bool isSharpAccessor; 402 bool isSharpDelegate; 403 bool isInExternC; 404 bool isInBeautifySQL; 405 bool isInIndentableStruct; 406 bool isInIndentablePreproc; 407 408 private: // functions 409 ASBeautifier(const ASBeautifier& other); // inline functions 410 ASBeautifier& operator=(ASBeautifier&); // not to be implemented 411 412 void adjustObjCMethodDefinitionIndentation(const string& line_); 413 void adjustObjCMethodCallIndentation(const string& line_); 414 void adjustParsedLineIndentation(size_t iPrelim, bool isInExtraHeaderIndent); 415 void computePreliminaryIndentation(); 416 void parseCurrentLine(const string& line); 417 void popLastContinuationIndent(); 418 void processPreprocessor(const string& preproc, const string& line); 419 void registerContinuationIndent(const string& line, int i, int spaceIndentCount_, 420 int tabIncrementIn, int minIndent, bool updateParenStack); 421 void registerContinuationIndentColon(const string& line, int i, int tabIncrementIn); 422 void initVectors(); 423 void initTempStacksContainer(vector<vector<const string*>*>*& container, 424 vector<vector<const string*>*>* value); 425 void clearObjCMethodDefinitionAlignment(); 426 void deleteBeautifierContainer(vector<ASBeautifier*>*& container); 427 void deleteTempStacksContainer(vector<vector<const string*>*>*& container); 428 int adjustIndentCountForBreakElseIfComments() const; 429 int computeObjCColonAlignment(const string& line, int colonAlignPosition) const; 430 int convertTabToSpaces(int i, int tabIncrementIn) const; 431 int findObjCColonAlignment(const string& line) const; 432 int getContinuationIndentAssign(const string& line, size_t currPos) const; 433 int getContinuationIndentComma(const string& line, size_t currPos) const; 434 int getObjCFollowingKeyword(const string& line, int bracePos) const; 435 bool isIndentedPreprocessor(const string& line, size_t currPos) const; 436 bool isLineEndComment(const string& line, int startPos) const; 437 bool isPreprocessorConditionalCplusplus(const string& line) const; 438 bool isInPreprocessorUnterminatedComment(const string& line); 439 bool isTopLevel() const; 440 bool statementEndsWithComma(const string& line, int index) const; 441 const string& getIndentedLineReturn(const string& newLine, const string& originalLine) const; 442 string getIndentedSpaceEquivalent(const string& line_) const; 443 string preLineWS(int lineIndentCount, int lineSpaceIndentCount) const; 444 template<typename T> void deleteContainer(T& container); 445 template<typename T> void initContainer(T& container, T value); 446 vector<vector<const string*>*>* copyTempStacks(const ASBeautifier& other) const; 447 pair<int, int> computePreprocessorIndent(); 448 449 private: // variables 450 int beautifierFileType; 451 vector<const string*>* headers; 452 vector<const string*>* nonParenHeaders; 453 vector<const string*>* preBlockStatements; 454 vector<const string*>* preCommandHeaders; 455 vector<const string*>* assignmentOperators; 456 vector<const string*>* nonAssignmentOperators; 457 vector<const string*>* indentableHeaders; 458 459 vector<ASBeautifier*>* waitingBeautifierStack; 460 vector<ASBeautifier*>* activeBeautifierStack; 461 vector<int>* waitingBeautifierStackLengthStack; 462 vector<int>* activeBeautifierStackLengthStack; 463 vector<const string*>* headerStack; 464 vector<vector<const string*>* >* tempStacks; 465 vector<int>* parenDepthStack; 466 vector<bool>* blockStatementStack; 467 vector<bool>* parenStatementStack; 468 vector<bool>* braceBlockStateStack; 469 vector<int>* continuationIndentStack; 470 vector<int>* continuationIndentStackSizeStack; 471 vector<int>* parenIndentStack; 472 vector<pair<int, int> >* preprocIndentStack; 473 474 ASSourceIterator* sourceIterator; 475 const string* currentHeader; 476 const string* previousLastLineHeader; 477 const string* probationHeader; 478 const string* lastLineHeader; 479 string indentString; 480 string verbatimDelimiter; 481 bool isInQuote; 482 bool isInVerbatimQuote; 483 bool haveLineContinuationChar; 484 bool isInAsm; 485 bool isInAsmOneLine; 486 bool isInAsmBlock; 487 bool isInComment; 488 bool isInPreprocessorComment; 489 bool isInRunInComment; 490 bool isInCase; 491 bool isInQuestion; 492 bool isContinuation; 493 bool isInHeader; 494 bool isInTemplate; 495 bool isInDefine; 496 bool isInDefineDefinition; 497 bool classIndent; 498 bool isIndentModeOff; 499 bool isInClassHeader; // is in a class before the opening brace 500 bool isInClassHeaderTab; // is in an indentable class header line 501 bool isInClassInitializer; // is in a class after the ':' initializer 502 bool isInClass; // is in a class after the opening brace 503 bool isInObjCMethodDefinition; 504 bool isInObjCMethodCall; 505 bool isInObjCMethodCallFirst; 506 bool isImmediatelyPostObjCMethodDefinition; 507 bool isImmediatelyPostObjCMethodCall; 508 bool isInIndentablePreprocBlock; 509 bool isInObjCInterface; 510 bool isInEnum; 511 bool isInEnumTypeID; 512 bool isInLet; 513 bool isInTrailingReturnType; 514 bool modifierIndent; 515 bool switchIndent; 516 bool caseIndent; 517 bool namespaceIndent; 518 bool blockIndent; 519 bool braceIndent; 520 bool braceIndentVtk; 521 bool shouldIndentAfterParen; 522 bool labelIndent; 523 bool shouldIndentPreprocDefine; 524 bool isInConditional; 525 bool isModeManuallySet; 526 bool shouldForceTabIndentation; 527 bool emptyLineFill; 528 bool backslashEndsPrevLine; 529 bool lineOpensWithLineComment; 530 bool lineOpensWithComment; 531 bool lineStartsInComment; 532 bool blockCommentNoIndent; 533 bool blockCommentNoBeautify; 534 bool previousLineProbationTab; 535 bool lineBeginsWithOpenBrace; 536 bool lineBeginsWithCloseBrace; 537 bool lineBeginsWithComma; 538 bool lineIsCommentOnly; 539 bool lineIsLineCommentOnly; 540 bool shouldIndentBracedLine; 541 bool isInSwitch; 542 bool foundPreCommandHeader; 543 bool foundPreCommandMacro; 544 bool shouldAlignMethodColon; 545 bool shouldIndentPreprocConditional; 546 int indentCount; 547 int spaceIndentCount; 548 int spaceIndentObjCMethodAlignment; 549 int bracePosObjCMethodAlignment; 550 int colonIndentObjCMethodAlignment; 551 int lineOpeningBlocksNum; 552 int lineClosingBlocksNum; 553 int fileType; 554 int minConditionalOption; 555 int minConditionalIndent; 556 int parenDepth; 557 int indentLength; 558 int tabLength; 559 int continuationIndent; 560 int blockTabCount; 561 int maxContinuationIndent; 562 int classInitializerIndents; 563 int templateDepth; 564 int squareBracketCount; 565 int prevFinalLineSpaceIndentCount; 566 int prevFinalLineIndentCount; 567 int defineIndentCount; 568 int preprocBlockIndent; 569 char quoteChar; 570 char prevNonSpaceCh; 571 char currentNonSpaceCh; 572 char currentNonLegalCh; 573 char prevNonLegalCh; 574 }; // Class ASBeautifier 575 576 //----------------------------------------------------------------------------- 577 // Class ASEnhancer 578 //----------------------------------------------------------------------------- 579 580 class ASEnhancer : protected ASBase 581 { 582 public: // functions 583 ASEnhancer(); 584 virtual ~ASEnhancer(); 585 void init(int, int, int, bool, bool, bool, bool, bool, bool, bool, 586 vector<const pair<const string, const string>* >*); 587 void enhance(string& line, bool isInNamespace, bool isInPreprocessor, bool isInSQL); 588 589 private: // functions 590 void convertForceTabIndentToSpaces(string& line) const; 591 void convertSpaceIndentToForceTab(string& line) const; 592 size_t findCaseColon(const string& line, size_t caseIndex) const; 593 int indentLine(string& line, int indent) const; 594 bool isBeginDeclareSectionSQL(const string& line, size_t index) const; 595 bool isEndDeclareSectionSQL(const string& line, size_t index) const; 596 bool isOneLineBlockReached(const string& line, int startChar) const; 597 void parseCurrentLine(string& line, bool isInPreprocessor, bool isInSQL); 598 size_t processSwitchBlock(string& line, size_t index); 599 int unindentLine(string& line, int unindent) const; 600 601 private: 602 // options from command line or options file 603 int indentLength; 604 int tabLength; 605 bool useTabs; 606 bool forceTab; 607 bool namespaceIndent; 608 bool caseIndent; 609 bool preprocBlockIndent; 610 bool preprocDefineIndent; 611 bool emptyLineFill; 612 613 // parsing variables 614 int lineNumber; 615 bool isInQuote; 616 bool isInComment; 617 char quoteChar; 618 619 // unindent variables 620 int braceCount; 621 int switchDepth; 622 int eventPreprocDepth; 623 bool lookingForCaseBrace; 624 bool unindentNextLine; 625 bool shouldUnindentLine; 626 bool shouldUnindentComment; 627 628 // struct used by ParseFormattedLine function 629 // contains variables used to unindent the case blocks 630 struct SwitchVariables 631 { 632 int switchBraceCount; 633 int unindentDepth; 634 bool unindentCase; 635 }; 636 637 SwitchVariables sw; // switch variables struct 638 vector<SwitchVariables> switchStack; // stack vector of switch variables 639 640 // event table variables 641 bool nextLineIsEventIndent; // begin event table indent is reached 642 bool isInEventTable; // need to indent an event table 643 vector<const pair<const string, const string>* >* indentableMacros; 644 645 // SQL variables 646 bool nextLineIsDeclareIndent; // begin declare section indent is reached 647 bool isInDeclareSection; // need to indent a declare section 648 649 }; // Class ASEnhancer 650 651 //----------------------------------------------------------------------------- 652 // Class ASFormatter 653 //----------------------------------------------------------------------------- 654 655 class ASFormatter : public ASBeautifier 656 { 657 public: // functions 658 ASFormatter(); 659 virtual ~ASFormatter(); 660 virtual void init(ASSourceIterator* si); 661 virtual bool hasMoreLines() const; 662 virtual string nextLine(); 663 LineEndFormat getLineEndFormat() const; 664 bool getIsLineReady() const; 665 void setFormattingStyle(FormatStyle style); 666 void setAddBracesMode(bool state); 667 void setAddOneLineBracesMode(bool state); 668 void setRemoveBracesMode(bool state); 669 void setAttachClass(bool state); 670 void setAttachClosingWhile(bool state); 671 void setAttachExternC(bool state); 672 void setAttachNamespace(bool state); 673 void setAttachInline(bool state); 674 void setBraceFormatMode(BraceMode mode); 675 void setBreakAfterMode(bool state); 676 void setBreakClosingHeaderBracesMode(bool state); 677 void setBreakBlocksMode(bool state); 678 void setBreakClosingHeaderBlocksMode(bool state); 679 void setBreakElseIfsMode(bool state); 680 void setBreakOneLineBlocksMode(bool state); 681 void setBreakOneLineHeadersMode(bool state); 682 void setBreakOneLineStatementsMode(bool state); 683 void setMethodPrefixPaddingMode(bool state); 684 void setMethodPrefixUnPaddingMode(bool state); 685 void setReturnTypePaddingMode(bool state); 686 void setReturnTypeUnPaddingMode(bool state); 687 void setParamTypePaddingMode(bool state); 688 void setParamTypeUnPaddingMode(bool state); 689 void setCloseTemplatesMode(bool state); 690 void setCommaPaddingMode(bool state); 691 void setDeleteEmptyLinesMode(bool state); 692 void setBreakReturnType(bool state); 693 void setBreakReturnTypeDecl(bool state); 694 void setAttachReturnType(bool state); 695 void setAttachReturnTypeDecl(bool state); 696 void setIndentCol1CommentsMode(bool state); 697 void setLineEndFormat(LineEndFormat fmt); 698 void setMaxCodeLength(int max); 699 void setObjCColonPaddingMode(ObjCColonPad mode); 700 void setOperatorPaddingMode(bool state); 701 void setParensOutsidePaddingMode(bool state); 702 void setParensFirstPaddingMode(bool state); 703 void setParensInsidePaddingMode(bool state); 704 void setParensHeaderPaddingMode(bool state); 705 void setParensUnPaddingMode(bool state); 706 void setPointerAlignment(PointerAlign alignment); 707 void setPreprocBlockIndent(bool state); 708 void setReferenceAlignment(ReferenceAlign alignment); 709 void setStripCommentPrefix(bool state); 710 void setTabSpaceConversionMode(bool state); 711 size_t getChecksumIn() const; 712 size_t getChecksumOut() const; 713 int getChecksumDiff() const; 714 int getFormatterFileType() const; 715 // retained for compatibility with release 2.06 716 // "Brackets" have been changed to "Braces" in 3.0 717 // they are referenced only by the old "bracket" options 718 void setAddBracketsMode(bool state); 719 void setAddOneLineBracketsMode(bool state); 720 void setRemoveBracketsMode(bool state); 721 void setBreakClosingHeaderBracketsMode(bool state); 722 723 724 private: // functions 725 ASFormatter(const ASFormatter& copy); // not to be implemented 726 ASFormatter& operator=(ASFormatter&); // not to be implemented 727 template<typename T> void deleteContainer(T& container); 728 template<typename T> void initContainer(T& container, T value); 729 char peekNextChar() const; 730 BraceType getBraceType(); 731 bool adjustChecksumIn(int adjustment); 732 bool computeChecksumIn(const string& currentLine_); 733 bool computeChecksumOut(const string& beautifiedLine); 734 bool addBracesToStatement(); 735 bool removeBracesFromStatement(); 736 bool commentAndHeaderFollows(); 737 bool getNextChar(); 738 bool getNextLine(bool emptyLineWasDeleted = false); 739 bool isArrayOperator() const; 740 bool isBeforeComment() const; 741 bool isBeforeAnyComment() const; 742 bool isBeforeAnyLineEndComment(int startPos) const; 743 bool isBeforeMultipleLineEndComments(int startPos) const; 744 bool isBraceType(BraceType a, BraceType b) const; 745 bool isClassInitializer() const; 746 bool isClosingHeader(const string* header) const; 747 bool isCurrentBraceBroken() const; 748 bool isDereferenceOrAddressOf() const; 749 bool isExecSQL(const string& line, size_t index) const; 750 bool isEmptyLine(const string& line) const; 751 bool isExternC() const; 752 bool isMultiStatementLine() const; 753 bool isNextWordSharpNonParenHeader(int startChar) const; 754 bool isNonInStatementArrayBrace() const; 755 bool isNumericVariable(string word) const; 756 bool isOkToSplitFormattedLine(); 757 bool isPointerOrReference() const; 758 bool isPointerOrReferenceCentered() const; 759 bool isPointerOrReferenceVariable(const string& word) const; 760 bool isPointerToPointer(const string& line, int currPos) const; 761 bool isSharpStyleWithParen(const string* header) const; 762 bool isStructAccessModified(const string& firstLine, size_t index) const; 763 bool isIndentablePreprocessorBlock(const string& firstLine, size_t index); 764 bool isNDefPreprocStatement(const string& nextLine_, const string& preproc) const; 765 bool isUnaryOperator() const; 766 bool isUniformInitializerBrace() const; 767 bool isImmediatelyPostCast() const; 768 bool isInExponent() const; 769 bool isInSwitchStatement() const; 770 bool isNextCharOpeningBrace(int startChar) const; 771 bool isOkToBreakBlock(BraceType braceType) const; 772 bool isOperatorPaddingDisabled() const; 773 bool pointerSymbolFollows() const; 774 int findObjCColonAlignment() const; 775 int getCurrentLineCommentAdjustment(); 776 int getNextLineCommentAdjustment(); 777 int isOneLineBlockReached(const string& line, int startChar) const; 778 void adjustComments(); 779 void appendChar(char ch, bool canBreakLine); 780 void appendCharInsideComments(); 781 void appendClosingHeader(); 782 void appendOperator(const string& sequence, bool canBreakLine = true); 783 void appendSequence(const string& sequence, bool canBreakLine = true); 784 void appendSpacePad(); 785 void appendSpaceAfter(); 786 void breakLine(bool isSplitLine = false); 787 void buildLanguageVectors(); 788 void updateFormattedLineSplitPoints(char appendedChar); 789 void updateFormattedLineSplitPointsOperator(const string& sequence); 790 void checkIfTemplateOpener(); 791 void clearFormattedLineSplitPoints(); 792 void convertTabToSpaces(); 793 void deleteContainer(vector<BraceType>*& container); 794 void findReturnTypeSplitPoint(const string& firstLine); 795 void formatArrayRunIn(); 796 void formatRunIn(); 797 void formatArrayBraces(BraceType braceType, bool isOpeningArrayBrace); 798 void formatClosingBrace(BraceType braceType); 799 void formatCommentBody(); 800 void formatCommentOpener(); 801 void formatCommentCloser(); 802 void formatLineCommentBody(); 803 void formatLineCommentOpener(); 804 void formatOpeningBrace(BraceType braceType); 805 void formatQuoteBody(); 806 void formatQuoteOpener(); 807 void formatPointerOrReference(); 808 void formatPointerOrReferenceCast(); 809 void formatPointerOrReferenceToMiddle(); 810 void formatPointerOrReferenceToName(); 811 void formatPointerOrReferenceToType(); 812 void fixOptionVariableConflicts(); 813 void goForward(int i); 814 void isLineBreakBeforeClosingHeader(); 815 void initContainer(vector<BraceType>*& container, vector<BraceType>* value); 816 void initNewLine(); 817 void padObjCMethodColon(); 818 void padObjCMethodPrefix(); 819 void padObjCParamType(); 820 void padObjCReturnType(); 821 void padOperators(const string* newOperator); 822 void padParens(); 823 void processPreprocessor(); 824 void resetEndOfStatement(); 825 void setAttachClosingBraceMode(bool state); 826 void stripCommentPrefix(); 827 void testForTimeToSplitFormattedLine(); 828 void trimContinuationLine(); 829 void updateFormattedLineSplitPointsPointerOrReference(size_t index); 830 size_t findFormattedLineSplitPoint() const; 831 size_t findNextChar(const string& line, char searchChar, int searchStart = 0) const; 832 const string* checkForHeaderFollowingComment(const string& firstLine) const; 833 const string* getFollowingOperator() const; 834 string getPreviousWord(const string& line, int currPos) const; 835 string peekNextText(const string& firstLine, 836 bool endOnEmptyLine = false, 837 shared_ptr<ASPeekStream> streamArg = nullptr) const; 838 839 private: // variables 840 int formatterFileType; 841 vector<const string*>* headers; 842 vector<const string*>* nonParenHeaders; 843 vector<const string*>* preDefinitionHeaders; 844 vector<const string*>* preCommandHeaders; 845 vector<const string*>* operators; 846 vector<const string*>* assignmentOperators; 847 vector<const string*>* castOperators; 848 vector<const pair<const string, const string>* >* indentableMacros; // for ASEnhancer 849 850 ASSourceIterator* sourceIterator; 851 ASEnhancer* enhancer; 852 853 vector<const string*>* preBraceHeaderStack; 854 vector<BraceType>* braceTypeStack; 855 vector<int>* parenStack; 856 vector<bool>* structStack; 857 vector<bool>* questionMarkStack; 858 859 string currentLine; 860 string formattedLine; 861 string readyFormattedLine; 862 string verbatimDelimiter; 863 const string* currentHeader; 864 char currentChar; 865 char previousChar; 866 char previousNonWSChar; 867 char previousCommandChar; 868 char quoteChar; 869 streamoff preprocBlockEnd; 870 int charNum; 871 int runInIndentChars; 872 int nextLineSpacePadNum; 873 int objCColonAlign; 874 int preprocBraceTypeStackSize; 875 int spacePadNum; 876 int tabIncrementIn; 877 int templateDepth; 878 int squareBracketCount; 879 size_t checksumIn; 880 size_t checksumOut; 881 size_t currentLineFirstBraceNum; // first brace location on currentLine 882 size_t formattedLineCommentNum; // comment location on formattedLine 883 size_t leadingSpaces; 884 size_t maxCodeLength; 885 size_t methodAttachCharNum; 886 size_t methodAttachLineNum; 887 size_t methodBreakCharNum; 888 size_t methodBreakLineNum; 889 890 // possible split points 891 size_t maxSemi; // probably a 'for' statement 892 size_t maxAndOr; // probably an 'if' statement 893 size_t maxComma; 894 size_t maxParen; 895 size_t maxWhiteSpace; 896 size_t maxSemiPending; 897 size_t maxAndOrPending; 898 size_t maxCommaPending; 899 size_t maxParenPending; 900 size_t maxWhiteSpacePending; 901 902 size_t previousReadyFormattedLineLength; 903 FormatStyle formattingStyle; 904 BraceMode braceFormatMode; 905 BraceType previousBraceType; 906 PointerAlign pointerAlignment; 907 ReferenceAlign referenceAlignment; 908 ObjCColonPad objCColonPadMode; 909 LineEndFormat lineEnd; 910 bool isVirgin; 911 bool isInVirginLine; 912 bool shouldPadCommas; 913 bool shouldPadOperators; 914 bool shouldPadParensOutside; 915 bool shouldPadFirstParen; 916 bool shouldPadParensInside; 917 bool shouldPadHeader; 918 bool shouldStripCommentPrefix; 919 bool shouldUnPadParens; 920 bool shouldConvertTabs; 921 bool shouldIndentCol1Comments; 922 bool shouldIndentPreprocBlock; 923 bool shouldCloseTemplates; 924 bool shouldAttachExternC; 925 bool shouldAttachNamespace; 926 bool shouldAttachClass; 927 bool shouldAttachClosingWhile; 928 bool shouldAttachInline; 929 bool isInLineComment; 930 bool isInComment; 931 bool isInCommentStartLine; 932 bool noTrimCommentContinuation; 933 bool isInPreprocessor; 934 bool isInPreprocessorBeautify; 935 bool isInTemplate; 936 bool doesLineStartComment; 937 bool lineEndsInCommentOnly; 938 bool lineIsCommentOnly; 939 bool lineIsLineCommentOnly; 940 bool lineIsEmpty; 941 bool isImmediatelyPostCommentOnly; 942 bool isImmediatelyPostEmptyLine; 943 bool isInClassInitializer; 944 bool isInQuote; 945 bool isInVerbatimQuote; 946 bool haveLineContinuationChar; 947 bool isInQuoteContinuation; 948 bool isHeaderInMultiStatementLine; 949 bool isSpecialChar; 950 bool isNonParenHeader; 951 bool foundQuestionMark; 952 bool foundPreDefinitionHeader; 953 bool foundNamespaceHeader; 954 bool foundClassHeader; 955 bool foundStructHeader; 956 bool foundInterfaceHeader; 957 bool foundPreCommandHeader; 958 bool foundPreCommandMacro; 959 bool foundTrailingReturnType; 960 bool foundCastOperator; 961 bool isInLineBreak; 962 bool endOfAsmReached; 963 bool endOfCodeReached; 964 bool lineCommentNoIndent; 965 bool isFormattingModeOff; 966 bool isInEnum; 967 bool isInExecSQL; 968 bool isInAsm; 969 bool isInAsmOneLine; 970 bool isInAsmBlock; 971 bool isLineReady; 972 bool elseHeaderFollowsComments; 973 bool caseHeaderFollowsComments; 974 bool isPreviousBraceBlockRelated; 975 bool isInPotentialCalculation; 976 bool isCharImmediatelyPostComment; 977 bool isPreviousCharPostComment; 978 bool isCharImmediatelyPostLineComment; 979 bool isCharImmediatelyPostOpenBlock; 980 bool isCharImmediatelyPostCloseBlock; 981 bool isCharImmediatelyPostTemplate; 982 bool isCharImmediatelyPostReturn; 983 bool isCharImmediatelyPostThrow; 984 bool isCharImmediatelyPostNewDelete; 985 bool isCharImmediatelyPostOperator; 986 bool isCharImmediatelyPostPointerOrReference; 987 bool isInObjCMethodDefinition; 988 bool isInObjCInterface; 989 bool isInObjCReturnType; 990 bool isInObjCParam; 991 bool isInObjCSelector; 992 bool breakCurrentOneLineBlock; 993 bool shouldRemoveNextClosingBrace; 994 bool isInBraceRunIn; 995 bool returnTypeChecked; 996 bool currentLineBeginsWithBrace; 997 bool attachClosingBraceMode; 998 bool shouldBreakOneLineBlocks; 999 bool shouldBreakOneLineHeaders; 1000 bool shouldBreakOneLineStatements; 1001 bool shouldBreakClosingHeaderBraces; 1002 bool shouldBreakElseIfs; 1003 bool shouldBreakLineAfterLogical; 1004 bool shouldAddBraces; 1005 bool shouldAddOneLineBraces; 1006 bool shouldRemoveBraces; 1007 bool shouldPadMethodColon; 1008 bool shouldPadMethodPrefix; 1009 bool shouldReparseCurrentChar; 1010 bool shouldUnPadMethodPrefix; 1011 bool shouldPadReturnType; 1012 bool shouldUnPadReturnType; 1013 bool shouldPadParamType; 1014 bool shouldUnPadParamType; 1015 bool shouldDeleteEmptyLines; 1016 bool shouldBreakReturnType; 1017 bool shouldBreakReturnTypeDecl; 1018 bool shouldAttachReturnType; 1019 bool shouldAttachReturnTypeDecl; 1020 bool needHeaderOpeningBrace; 1021 bool shouldBreakLineAtNextChar; 1022 bool shouldKeepLineUnbroken; 1023 bool passedSemicolon; 1024 bool passedColon; 1025 bool isImmediatelyPostNonInStmt; 1026 bool isCharImmediatelyPostNonInStmt; 1027 bool isImmediatelyPostComment; 1028 bool isImmediatelyPostLineComment; 1029 bool isImmediatelyPostEmptyBlock; 1030 bool isImmediatelyPostObjCMethodPrefix; 1031 bool isImmediatelyPostPreprocessor; 1032 bool isImmediatelyPostReturn; 1033 bool isImmediatelyPostThrow; 1034 bool isImmediatelyPostNewDelete; 1035 bool isImmediatelyPostOperator; 1036 bool isImmediatelyPostTemplate; 1037 bool isImmediatelyPostPointerOrReference; 1038 bool shouldBreakBlocks; 1039 bool shouldBreakClosingHeaderBlocks; 1040 bool isPrependPostBlockEmptyLineRequested; 1041 bool isAppendPostBlockEmptyLineRequested; 1042 bool isIndentableProprocessor; 1043 bool isIndentableProprocessorBlock; 1044 bool prependEmptyLine; 1045 bool appendOpeningBrace; 1046 bool foundClosingHeader; 1047 bool isInHeader; 1048 bool isImmediatelyPostHeader; 1049 bool isInCase; 1050 bool isFirstPreprocConditional; 1051 bool processedFirstConditional; 1052 bool isJavaStaticConstructor; 1053 1054 private: // inline functions 1055 // append the CURRENT character (curentChar) to the current formatted line. 1056 void appendCurrentChar(bool canBreakLine = true) 1057 { appendChar(currentChar, canBreakLine); } 1058 1059 // check if a specific sequence exists in the current placement of the current line isSequenceReached(const char * sequence)1060 bool isSequenceReached(const char* sequence) const 1061 { return currentLine.compare(charNum, strlen(sequence), sequence) == 0; } 1062 1063 // call ASBase::findHeader for the current character findHeader(const vector<const string * > * headers_)1064 const string* findHeader(const vector<const string*>* headers_) 1065 { return ASBase::findHeader(currentLine, charNum, headers_); } 1066 1067 // call ASBase::findOperator for the current character findOperator(const vector<const string * > * operators_)1068 const string* findOperator(const vector<const string*>* operators_) 1069 { return ASBase::findOperator(currentLine, charNum, operators_); } 1070 }; // Class ASFormatter 1071 1072 //----------------------------------------------------------------------------- 1073 // astyle namespace global declarations 1074 //----------------------------------------------------------------------------- 1075 // sort comparison functions for ASResource 1076 bool sortOnLength(const string* a, const string* b); 1077 bool sortOnName(const string* a, const string* b); 1078 1079 } // namespace astyle 1080 1081 // end of astyle namespace -------------------------------------------------- 1082 1083 #endif // closes ASTYLE_H 1084