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