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 &copy);
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 &copy);            // 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