1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * 3 * astyle.h 4 * 5 * This file is a part of "Artistic Style" - an indentation and 6 * reformatting tool for C, C++, C# and Java source files. 7 * http://astyle.sourceforge.net 8 * 9 * The "Artistic Style" project, including all files needed to 10 * compile it, is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later 14 * version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this project; if not, write to the 23 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 * Boston, MA 02110-1301, USA. 25 * 26 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 27 */ 28 29 /* 30 2008-01-26 Patches by Massimo Del Fedele : 31 - modified sources to use Ultimate++ containers instead std:: ones 32 - fixed memory leaks based on bug report 1804791 submitted by Eran Ifrah 33 - modified to work with unicode 34 */ 35 36 #ifndef ASTYLE_H 37 #define ASTYLE_H 38 39 #include <Core/Core.h> 40 #include "ASStringTools.hpp" 41 42 // 4996 - secure version deprecation warnings for .NET 2005 43 // 4267 - 64 bit signed/unsigned loss of data 44 #ifdef _MSC_VER 45 #pragma warning(disable: 4996) 46 #pragma warning(disable: 4267) 47 #endif 48 49 namespace astyle 50 { 51 52 enum FileType { C_TYPE=0, JAVA_TYPE=1, SHARP_TYPE=2 }; 53 54 /* The enums below are not recognized by 'vectors' in Microsoft Visual C++ 55 V5 when they are part of a namespace!!! Use Visual C++ V6 or higher. 56 */ 57 enum BracketMode { NONE_MODE, ATTACH_MODE, BREAK_MODE, BDAC_MODE }; 58 59 // added by Massimo Del Fedele - just an helper for dialog setup 60 enum ParenthesisPad { PAD_NONE, PAD_INSIDE, PAD_OUTSIDE, PAD_BOTH }; 61 62 enum BracketType { NULL_TYPE = 0, 63 NAMESPACE_TYPE = 1, // also a DEFINITION_TYPE 64 CLASS_TYPE = 2, // also a DEFINITION_TYPE 65 DEFINITION_TYPE = 4, 66 COMMAND_TYPE = 8, 67 ARRAY_TYPE = 16, // arrays and enums 68 SINGLE_LINE_TYPE = 32 69 }; 70 class ASSourceIterator 71 { 72 public: 73 int eolWindows; 74 int eolLinux; 75 int eolMacOld; 76 char outputEOL[4]; // output end of line char ASSourceIterator()77 ASSourceIterator() { eolWindows = eolLinux = eolMacOld = 0; } ~ASSourceIterator()78 virtual ~ASSourceIterator() {} 79 virtual bool hasMoreLines() const = 0; 80 virtual WString nextLine() = 0; 81 }; 82 83 class ASResource 84 { 85 public: 86 void buildAssignmentOperators(Vector<const WString*> &assignmentOperators); 87 void buildCastOperators(Vector<const WString*> &castOperators); 88 void buildHeaders(Vector<const WString*> &headers, int fileType, bool beautifier=false); 89 void buildNonAssignmentOperators(Vector<const WString*> &nonAssignmentOperators); 90 void buildNonParenHeaders(Vector<const WString*> &nonParenHeaders, int fileType, bool beautifier=false); 91 void buildOperators(Vector<const WString*> &operators); 92 void buildPreBlockStatements(Vector<const WString*> &preBlockStatements); 93 void buildPreCommandHeaders(Vector<const WString*> &preCommandHeaders); 94 void buildPreDefinitionHeaders(Vector<const WString*> &preDefinitionHeaders); 95 96 public: 97 static const WString AS_IF, AS_ELSE; 98 static const WString AS_DO, AS_WHILE; 99 static const WString AS_FOR; 100 static const WString AS_SWITCH, AS_CASE, AS_DEFAULT; 101 static const WString AS_TRY, AS_CATCH, AS_THROWS, AS_FINALLY; 102 static const WString AS_PUBLIC, AS_PROTECTED, AS_PRIVATE; 103 static const WString AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE, AS_EXTERN; 104 static const WString AS_STATIC; 105 static const WString AS_CONST; 106 static const WString AS_SYNCHRONIZED; 107 static const WString AS_OPERATOR, AS_TEMPLATE; 108 static const WString AS_OPEN_BRACKET, AS_CLOSE_BRACKET; 109 static const WString AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT; 110 static const WString AS_BAR_DEFINE, AS_BAR_INCLUDE, AS_BAR_IF, AS_BAR_EL, AS_BAR_ENDIF; 111 static const WString AS_RETURN; 112 static const WString AS_ASSIGN, AS_PLUS_ASSIGN, AS_MINUS_ASSIGN, AS_MULT_ASSIGN; 113 static const WString AS_DIV_ASSIGN, AS_MOD_ASSIGN, AS_XOR_ASSIGN, AS_OR_ASSIGN, AS_AND_ASSIGN; 114 static const WString AS_GR_GR_ASSIGN, AS_LS_LS_ASSIGN, AS_GR_GR_GR_ASSIGN, AS_LS_LS_LS_ASSIGN; 115 static const WString AS_EQUAL, AS_PLUS_PLUS, AS_MINUS_MINUS, AS_NOT_EQUAL, AS_GR_EQUAL, AS_GR_GR_GR, AS_GR_GR; 116 static const WString AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS, AS_ARROW, AS_AND, AS_OR; 117 static const WString AS_COLON_COLON, AS_PAREN_PAREN, AS_BLPAREN_BLPAREN; 118 static const WString AS_PLUS, AS_MINUS, AS_MULT, AS_DIV, AS_MOD, AS_GR, AS_LS; 119 static const WString AS_NOT, AS_BIT_XOR, AS_BIT_OR, AS_BIT_AND, AS_BIT_NOT; 120 static const WString AS_QUESTION, AS_COLON, AS_SEMICOLON, AS_COMMA; 121 static const WString AS_ASM; 122 static const WString AS_FOREACH, AS_LOCK, AS_UNSAFE, AS_FIXED; 123 static const WString AS_GET, AS_SET, AS_ADD, AS_REMOVE; 124 static const WString AS_CONST_CAST, AS_DYNAMIC_CAST, AS_REINTERPRET_CAST, AS_STATIC_CAST; 125 }; 126 127 class ASBeautifier : protected ASResource 128 { 129 public: 130 ASBeautifier(); 131 virtual ~ASBeautifier(); 132 virtual void init(ASSourceIterator* iter); // pointer to dynamically created iterator. 133 void init(); 134 virtual bool hasMoreLines() const; 135 virtual WString nextLine(); 136 virtual WString beautify(const WString &line); 137 void setTabIndentation(int length = 4, bool forceTabs = false); 138 void setSpaceIndentation(int length = 4); 139 void setMaxInStatementIndentLength(int max); 140 void setMinConditionalIndentLength(int min); 141 void setClassIndent(bool state); 142 void setSwitchIndent(bool state); 143 void setCaseIndent(bool state); 144 void setBracketIndent(bool state); 145 void setBlockIndent(bool state); 146 void setNamespaceIndent(bool state); 147 void setLabelIndent(bool state); 148 void setCStyle(); 149 void setJavaStyle(); 150 void setSharpStyle(); 151 void setEmptyLineFill(bool state); 152 void setPreprocessorIndent(bool state); 153 int getIndentLength(void); 154 WString getIndentString(void); 155 bool getCaseIndent(void); 156 bool getCStyle(void); 157 bool getJavaStyle(void); 158 bool getSharpStyle(void); 159 bool getEmptyLineFill(void); 160 161 protected: 162 int getNextProgramCharDistance(const WString &line, int i); 163 // bool isLegalNameChar(char ch) const; 164 const WString *findHeader(const WString &line, int i, 165 const Vector<const WString*> &possibleHeaders, 166 bool checkBoundry = true); 167 WString trim(const WString &str); 168 int indexOf(Vector<const WString*> &container, const WString *element); 169 int fileType; 170 bool isCStyle; 171 bool isJavaStyle; 172 bool isSharpStyle; 173 174 // variables set by ASFormatter - must be updated in preprocessor 175 int inLineNumber; // for debugging 176 int outLineNumber; // for debugging 177 bool lineCommentNoBeautify; 178 bool isNonInStatementArray; 179 180 private: 181 ASBeautifier(const ASBeautifier ©); 182 void operator=(ASBeautifier&); // not to be implemented 183 184 void initStatic(); 185 void registerInStatementIndent(const WString &line, int i, int spaceTabCount, 186 int minIndent, bool updateParenStack); 187 WString preLineWS(int spaceTabCount, int tabCount); 188 189 static Vector<const WString*> headers; 190 static Vector<const WString*> nonParenHeaders; 191 static Vector<const WString*> preBlockStatements; 192 static Vector<const WString*> assignmentOperators; 193 static Vector<const WString*> nonAssignmentOperators; 194 195 ASSourceIterator *sourceIterator; 196 Vector<ASBeautifier*> *waitingBeautifierStack; 197 Vector<ASBeautifier*> *activeBeautifierStack; 198 Vector<int> *waitingBeautifierStackLengthStack; 199 Vector<int> *activeBeautifierStackLengthStack; 200 WithDeepCopy<Vector<const WString*> > *headerStack; 201 WithDeepCopy<Vector< Vector<const WString*>* > >*tempStacks; 202 WithDeepCopy<Vector<int> > *blockParenDepthStack; 203 WithDeepCopy<Vector<bool> > *blockStatementStack; 204 WithDeepCopy<Vector<bool> >*parenStatementStack; 205 WithDeepCopy<Vector<int> > *inStatementIndentStack; 206 WithDeepCopy<Vector<int> > *inStatementIndentStackSizeStack; 207 WithDeepCopy<Vector<int> > *parenIndentStack; 208 WithDeepCopy<Vector<bool> >*bracketBlockStateStack; 209 WString indentString; 210 const WString *currentHeader; 211 const WString *previousLastLineHeader; 212 const WString *immediatelyPreviousAssignmentOp; 213 const WString *probationHeader; 214 bool isInQuote; 215 bool isInComment; 216 bool isInCase; 217 bool isInQuestion; 218 bool isInStatement; 219 bool isInHeader; 220 bool isInOperator; 221 bool isInTemplate; 222 bool isInDefine; 223 bool isInDefineDefinition; 224 bool classIndent; 225 bool isInClassHeader; 226 bool isInClassHeaderTab; 227 bool switchIndent; 228 bool caseIndent; 229 bool namespaceIndent; 230 bool bracketIndent; 231 bool blockIndent; 232 bool labelIndent; 233 bool preprocessorIndent; 234 bool isInConditional; 235 bool isMinimalConditinalIndentSet; 236 bool shouldForceTabIndentation; 237 bool emptyLineFill; 238 bool backslashEndsPrevLine; 239 bool blockCommentNoIndent; 240 bool blockCommentNoBeautify; 241 bool previousLineProbationTab; 242 int minConditionalIndent; 243 int parenDepth; 244 int indentLength; 245 int blockTabCount; 246 int leadingWhiteSpaces; 247 int maxInStatementIndent; 248 int templateDepth; 249 int prevFinalLineSpaceTabCount; 250 int prevFinalLineTabCount; 251 int defineTabCount; 252 wchar quoteChar; 253 wchar prevNonSpaceCh; 254 wchar currentNonSpaceCh; 255 wchar currentNonLegalCh; 256 wchar prevNonLegalCh; 257 wchar peekNextChar(WString &line, int i); 258 259 protected: // inline functions 260 // check if a specific character can be used in a legal variable/method/class name isLegalNameChar(wchar ch)261 inline bool isLegalNameChar(wchar ch) const { 262 return (isalnum(ch) || ch == '.' || ch == '_' || (isJavaStyle && ch == '$') || (isCStyle && ch == '~')); 263 } 264 265 // check if a specific character is a whitespace character isWhiteSpace(wchar ch)266 inline bool isWhiteSpace(wchar ch) const { 267 return (ch == ' ' || ch == '\t'); 268 } 269 }; 270 271 272 class ASEnhancer 273 { 274 public: 275 // functions 276 ASEnhancer(); 277 ~ASEnhancer(); 278 void init(int, WString, bool, bool, bool, bool, bool); 279 void enhance(WString &line); 280 281 private: 282 // set by init function 283 int indentLength; 284 bool useTabs; 285 bool isCStyle; 286 bool isJavaStyle; 287 bool isSharpStyle; 288 bool caseIndent; 289 bool emptyLineFill; 290 291 // parsing variables 292 int lineNumber; 293 bool isInQuote; 294 bool isInComment; 295 wchar quoteChar; 296 297 // unindent variables 298 int bracketCount; 299 int switchDepth; 300 bool lookingForCaseBracket; 301 bool unindentNextLine; 302 303 // StringStream for trace 304 StringStream *traceOut; 305 306 private: // private functions 307 bool findKeyword(const WString &line, int i, const char *header) const; 308 int indentLine(WString &line, const int indent) const; 309 int unindentLine(WString &line, const int unindent) const; 310 311 private: 312 // struct used by ParseFormattedLine function 313 // contains variables used to unindent the case blocks 314 struct switchVariables { 315 int switchBracketCount; 316 int unindentDepth; 317 bool unindentCase; 318 switchVariablesswitchVariables319 switchVariables() { // constructor 320 switchBracketCount = 0; 321 unindentDepth = 0; 322 unindentCase = false; 323 } 324 }; 325 326 private: // inline functions 327 // check if a specific character can be used in a legal variable/method/class name isLegalNameCharX(wchar ch)328 inline bool isLegalNameCharX(wchar ch) const { 329 return (isalnum(ch) || ch == '.' || ch == '_' || (isJavaStyle && ch == '$') || (isCStyle && ch == '~')); 330 } 331 332 // check if a specific character is a whitespace character isWhiteSpaceX(wchar ch)333 inline bool isWhiteSpaceX(wchar ch) const { 334 return (ch == ' ' || ch == '\t'); 335 } 336 }; 337 338 339 class ASFormatter : public ASBeautifier, private ASEnhancer 340 { 341 public: 342 ASFormatter(); 343 virtual ~ASFormatter(); 344 virtual void init(ASSourceIterator* iter); 345 virtual bool hasMoreLines() const; 346 virtual WString nextLine(); 347 void setBracketFormatMode(BracketMode mode); 348 void setBreakClosingHeaderBracketsMode(bool state); 349 void setOperatorPaddingMode(bool mode); 350 void setParensOutsidePaddingMode(bool mode); 351 void setParensInsidePaddingMode(bool mode); 352 void setParensUnPaddingMode(bool state); 353 void setBreakOneLineBlocksMode(bool state); 354 void setSingleStatementsMode(bool state); 355 void setTabSpaceConversionMode(bool state); 356 void setBreakBlocksMode(bool state); 357 void setBreakClosingHeaderBlocksMode(bool state); 358 void setBreakElseIfsMode(bool state); 359 WString fileName; 360 361 private: 362 void ASformatter(ASFormatter ©); // not to be imlpemented 363 void operator=(ASFormatter&); // not to be implemented 364 void staticInit(); 365 void goForward(int i); 366 void trimNewLine(); 367 wchar peekNextChar() const; 368 BracketType getBracketType() const; 369 bool getNextChar(); 370 bool isBeforeComment() const; 371 bool isBeforeLineEndComment(int startPos) const; 372 bool isPointerOrReference() const; 373 bool isUnaryMinus() const; 374 bool isInExponent() const; 375 bool isOneLineBlockReached() const; 376 // bool isNextCharWhiteSpace() const; 377 bool lineBeginsWith(wchar charToCheck) const; 378 void appendChar(wchar ch, bool canBreakLine = true); 379 void appendCharInsideComments(); 380 void appendSequence(const WString &sequence, bool canBreakLine = true); 381 void appendSpacePad(); 382 void appendSpaceAfter(); 383 void breakLine(); 384 void padOperators(const WString *newOperator); 385 void padParens(); 386 void formatBrackets(BracketType bracketType); 387 void formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket); 388 void adjustComments(); 389 const WString *findHeader(const Vector<const WString*> &headers, bool checkBoundry = true); 390 391 static Vector<const WString*> headers; 392 static Vector<const WString*> nonParenHeaders; 393 static Vector<const WString*> preDefinitionHeaders; 394 static Vector<const WString*> preCommandHeaders; 395 static Vector<const WString*> operators; 396 static Vector<const WString*> assignmentOperators; 397 static Vector<const WString*> castOperators; 398 399 ASSourceIterator *sourceIterator; 400 Vector<const WString*> *preBracketHeaderStack; 401 Vector<BracketType> *bracketTypeStack; 402 Vector<int> *parenStack; 403 WString readyFormattedLine; 404 WString currentLine; 405 WString formattedLine; 406 const WString *currentHeader; 407 const WString *previousOperator; // used ONLY by pad=oper 408 wchar currentChar; 409 wchar previousChar; 410 wchar previousNonWSChar; 411 wchar previousCommandChar; 412 wchar quoteChar; 413 int charNum; 414 int spacePadNum; 415 int templateDepth; 416 int traceFileNumber; 417 int formattedLineCommentNum; // comment location on formattedLine 418 int previousReadyFormattedLineLength; 419 BracketMode bracketFormatMode; 420 BracketType previousBracketType; 421 bool isVirgin; 422 bool shouldPadOperators; 423 bool shouldPadParensOutside; 424 bool shouldPadParensInside; 425 bool shouldUnPadParens; 426 bool shouldConvertTabs; 427 bool isInLineComment; 428 bool isInComment; 429 bool isInPreprocessor; 430 bool isInTemplate; // true both in template definitions (e.g. template<class A>) and template usage (e.g. F<int>). 431 bool doesLineStartComment; 432 bool isInQuote; 433 bool isInBlParen; 434 bool isSpecialChar; 435 bool isNonParenHeader; 436 bool foundQuestionMark; 437 bool foundPreDefinitionHeader; 438 bool foundNamespaceHeader; 439 bool foundClassHeader; 440 bool foundPreCommandHeader; 441 bool foundCastOperator; 442 bool isInLineBreak; 443 // bool isInClosingBracketLineBreak; 444 bool endOfCodeReached; 445 bool lineCommentNoIndent; 446 bool isLineReady; 447 bool isPreviousBracketBlockRelated; 448 bool isInPotentialCalculation; 449 bool isCharImmediatelyPostComment; 450 bool isPreviousCharPostComment; 451 bool isCharImmediatelyPostLineComment; 452 bool isCharImmediatelyPostOpenBlock; 453 bool isCharImmediatelyPostCloseBlock; 454 bool isCharImmediatelyPostTemplate; 455 bool shouldBreakOneLineBlocks; 456 bool shouldReparseCurrentChar; 457 bool shouldBreakOneLineStatements; 458 bool shouldBreakLineAfterComments; 459 bool shouldBreakClosingHeaderBrackets; 460 bool shouldBreakElseIfs; 461 bool passedSemicolon; 462 bool passedColon; 463 bool isImmediatelyPostComment; 464 bool isImmediatelyPostLineComment; 465 bool isImmediatelyPostEmptyBlock; 466 bool isImmediatelyPostPreprocessor; 467 468 bool shouldBreakBlocks; 469 bool shouldBreakClosingHeaderBlocks; 470 bool isPrependPostBlockEmptyLineRequested; 471 bool isAppendPostBlockEmptyLineRequested; 472 473 bool prependEmptyLine; 474 bool appendOpeningBracket; 475 bool foundClosingHeader; 476 477 bool isInHeader; 478 bool isImmediatelyPostHeader; 479 480 private: // inline functions 481 // append the CURRENT character (curentChar)to the current formatted line. 482 inline void appendCurrentChar(bool canBreakLine = true) { 483 appendChar(currentChar, canBreakLine); 484 } 485 486 // check if a specific sequence exists in the current placement of the current line isSequenceReached(const char * sequence)487 inline bool isSequenceReached(const char *sequence) const { 488 // return currentLine.compare(charNum, strlen(sequence), sequence) == 0; 489 return currentLine.Mid(charNum, strlen(sequence)) == WString(sequence); 490 } 491 }; 492 493 } // end of namespace astyle 494 495 // NEEDED FOR Upp::Vector<> 496 // marks enum BracketType as moveable so it can be used by Upp containers 497 namespace Upp 498 { 499 NTL_MOVEABLE(astyle::BracketType); 500 501 } // end namespace Upp 502 503 #endif // closes ASTYLE_H 504 505