summaryrefslogtreecommitdiffstats
path: root/lib/astyle/astyle.h
blob: 445aacf66d6fe52fa4845373cdcef0b57b15d24b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *   astyle.h
 *
 *   This file is a part of "Artistic Style" - an indentation and
 *   reformatting tool for C, C++, C# and Java source files.
 *   http://astyle.sourceforge.net
 *
 *   The "Artistic Style" project, including all files needed to
 *   compile it, is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later
 *   version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this project; if not, write to the
 *   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *   Boston, MA  02110-1301, USA.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 */

#ifndef ASTYLE_H
#define ASTYLE_H

#ifdef __VMS
#define __USE_STD_IOSTREAM 1
#include <sstream>
#endif

#include <string>
#include <vector>
#include <cctype>

#include <string.h>

using namespace std;


// 4996 - secure version deprecation warnings for .NET 2005
// 4267 - 64 bit signed/unsigned loss of data
#ifdef _MSC_VER
#pragma warning(disable: 4996)
#pragma warning(disable: 4267)
#endif

namespace astyle
{

enum FileType      { C_TYPE=0, JAVA_TYPE=1, SHARP_TYPE=2 };

/* The enums below are not recognized by 'vectors' in Microsoft Visual C++
   V5 when they are part of a namespace!!!  Use Visual C++ V6 or higher.
*/
enum BracketMode   { NONE_MODE, ATTACH_MODE, BREAK_MODE, BDAC_MODE };

enum BracketType   { NULL_TYPE = 0,
                     NAMESPACE_TYPE = 1,		// also a DEFINITION_TYPE
                     CLASS_TYPE = 2,			// also a DEFINITION_TYPE
                     DEFINITION_TYPE = 4,
                     COMMAND_TYPE = 8,
                     ARRAY_TYPE  = 16,          // arrays and enums
                     SINGLE_LINE_TYPE = 32
                   };

class ASSourceIterator
{
	public:
		int eolWindows;
		int eolLinux;
		int eolMacOld;
		char outputEOL[4];    // output end of line char
		ASSourceIterator() { eolWindows = eolLinux = eolMacOld = 0; }
		virtual ~ASSourceIterator() {}
		virtual bool hasMoreLines() const = 0;
		virtual string nextLine() = 0;
};

class ASResource
{
	public:
		void buildAssignmentOperators(vector<const string*> &assignmentOperators);
		void buildCastOperators(vector<const string*> &castOperators);
		void buildHeaders(vector<const string*> &headers, int fileType, bool beautifier=false);
		void buildNonAssignmentOperators(vector<const string*> &nonAssignmentOperators);
		void buildNonParenHeaders(vector<const string*> &nonParenHeaders, int fileType, bool beautifier=false);
		void buildOperators(vector<const string*> &operators);
		void buildPreBlockStatements(vector<const string*> &preBlockStatements);
		void buildPreCommandHeaders(vector<const string*> &preCommandHeaders);
		void buildPreDefinitionHeaders(vector<const string*> &preDefinitionHeaders);

	public:
		static const string AS_IF, AS_ELSE;
		static const string AS_DO, AS_WHILE;
		static const string AS_FOR;
		static const string AS_SWITCH, AS_CASE, AS_DEFAULT;
		static const string AS_TRY, AS_CATCH, AS_THROWS, AS_FINALLY;
		static const string AS_PUBLIC, AS_PROTECTED, AS_PRIVATE;
		static const string AS_CLASS, AS_STRUCT, AS_UNION, AS_INTERFACE, AS_NAMESPACE, AS_EXTERN;
		static const string AS_STATIC;
		static const string AS_CONST;
		static const string AS_SYNCHRONIZED;
		static const string AS_OPERATOR, AS_TEMPLATE;
		static const string AS_OPEN_BRACKET, AS_CLOSE_BRACKET;
		static const string AS_OPEN_LINE_COMMENT, AS_OPEN_COMMENT, AS_CLOSE_COMMENT;
		static const string AS_BAR_DEFINE, AS_BAR_INCLUDE, AS_BAR_IF, AS_BAR_EL, AS_BAR_ENDIF;
		static const string AS_RETURN;
		static const string AS_ASSIGN, AS_PLUS_ASSIGN, AS_MINUS_ASSIGN, AS_MULT_ASSIGN;
		static const string AS_DIV_ASSIGN, AS_MOD_ASSIGN, AS_XOR_ASSIGN, AS_OR_ASSIGN, AS_AND_ASSIGN;
		static const string AS_GR_GR_ASSIGN, AS_LS_LS_ASSIGN, AS_GR_GR_GR_ASSIGN, AS_LS_LS_LS_ASSIGN;
		static const string AS_EQUAL, AS_PLUS_PLUS, AS_MINUS_MINUS, AS_NOT_EQUAL, AS_GR_EQUAL, AS_GR_GR_GR, AS_GR_GR;
		static const string AS_LS_EQUAL, AS_LS_LS_LS, AS_LS_LS, AS_ARROW, AS_AND, AS_OR;
		static const string AS_COLON_COLON, AS_PAREN_PAREN, AS_BLPAREN_BLPAREN;
		static const string AS_PLUS, AS_MINUS, AS_MULT, AS_DIV, AS_MOD, AS_GR, AS_LS;
		static const string AS_NOT, AS_BIT_XOR, AS_BIT_OR, AS_BIT_AND, AS_BIT_NOT;
		static const string AS_QUESTION, AS_COLON, AS_SEMICOLON, AS_COMMA;
		static const string AS_ASM;
		static const string AS_FOREACH, AS_LOCK, AS_UNSAFE, AS_FIXED;
		static const string AS_GET, AS_SET, AS_ADD, AS_REMOVE;
		static const string AS_CONST_CAST, AS_DYNAMIC_CAST, AS_REINTERPRET_CAST, AS_STATIC_CAST;
};

class ASBeautifier : protected ASResource
{
	public:
		ASBeautifier();
		virtual ~ASBeautifier();
		virtual void init(ASSourceIterator* iter); // pointer to dynamically created iterator.
		void init();
		virtual bool hasMoreLines() const;
		virtual string nextLine();
		virtual string beautify(const string &line);
		void setTabIndentation(int length = 4, bool forceTabs = false);
		void setSpaceIndentation(int length = 4);
		void setMaxInStatementIndentLength(int max);
		void setMinConditionalIndentLength(int min);
		void setClassIndent(bool state);
		void setSwitchIndent(bool state);
		void setCaseIndent(bool state);
		void setBracketIndent(bool state);
		void setBlockIndent(bool state);
		void setNamespaceIndent(bool state);
		void setLabelIndent(bool state);
		void setCStyle();
		void setJavaStyle();
		void setSharpStyle();
		void setEmptyLineFill(bool state);
		void setPreprocessorIndent(bool state);
		int  getIndentLength(void);
		string getIndentString(void);
		bool getCaseIndent(void);
		bool getCStyle(void);
		bool getJavaStyle(void);
		bool getSharpStyle(void);
		bool getEmptyLineFill(void);

	protected:
		int getNextProgramCharDistance(const string &line, int i);
//		bool isLegalNameChar(char ch) const;
		const string *findHeader(const string &line, int i,
		                         const vector<const string*> &possibleHeaders,
		                         bool checkBoundry = true);
		string trim(const string &str);
		int  indexOf(vector<const string*> &container, const string *element);
		int  fileType;
		bool isCStyle;
		bool isJavaStyle;
		bool isSharpStyle;

		// variables set by ASFormatter - must be updated in preprocessor
		int  inLineNumber;              // for debugging
		int  outLineNumber;				// for debugging
		bool lineCommentNoBeautify;
		bool isNonInStatementArray;

	private:
		ASBeautifier(const ASBeautifier &copy);
		void operator=(ASBeautifier&); // not to be implemented

		void initStatic();
		void registerInStatementIndent(const string &line, int i, int spaceTabCount,
		                               int minIndent, bool updateParenStack);
		string preLineWS(int spaceTabCount, int tabCount);

		static vector<const string*> headers;
		static vector<const string*> nonParenHeaders;
		static vector<const string*> preBlockStatements;
		static vector<const string*> assignmentOperators;
		static vector<const string*> nonAssignmentOperators;

		ASSourceIterator *sourceIterator;
		vector<ASBeautifier*> *waitingBeautifierStack;
		vector<ASBeautifier*> *activeBeautifierStack;
		vector<int> *waitingBeautifierStackLengthStack;
		vector<int> *activeBeautifierStackLengthStack;
		vector<const string*> *headerStack;
		vector< vector<const string*>* > *tempStacks;
		vector<int> *blockParenDepthStack;
		vector<bool> *blockStatementStack;
		vector<bool> *parenStatementStack;
		vector<int> *inStatementIndentStack;
		vector<int> *inStatementIndentStackSizeStack;
		vector<int> *parenIndentStack;
		vector<bool> *bracketBlockStateStack;
		string indentString;
		const string *currentHeader;
		const string *previousLastLineHeader;
		const string *immediatelyPreviousAssignmentOp;
		const string *probationHeader;
		bool isInQuote;
		bool isInComment;
		bool isInCase;
		bool isInQuestion;
		bool isInStatement;
		bool isInHeader;
		bool isInOperator;
		bool isInTemplate;
		bool isInDefine;
		bool isInDefineDefinition;
		bool classIndent;
		bool isInClassHeader;
		bool isInClassHeaderTab;
		bool switchIndent;
		bool caseIndent;
		bool namespaceIndent;
		bool bracketIndent;
		bool blockIndent;
		bool labelIndent;
		bool preprocessorIndent;
		bool isInConditional;
		bool isMinimalConditinalIndentSet;
		bool shouldForceTabIndentation;
		bool emptyLineFill;
		bool backslashEndsPrevLine;
		bool blockCommentNoIndent;
		bool blockCommentNoBeautify;
		bool previousLineProbationTab;
		int  minConditionalIndent;
		int  parenDepth;
		int  indentLength;
		int  blockTabCount;
		int  leadingWhiteSpaces;
		int  maxInStatementIndent;
		int  templateDepth;
		int  prevFinalLineSpaceTabCount;
		int  prevFinalLineTabCount;
		int  defineTabCount;
		char quoteChar;
		char prevNonSpaceCh;
		char currentNonSpaceCh;
		char currentNonLegalCh;
		char prevNonLegalCh;
		char peekNextChar(string &line, int i);

	protected:    // inline functions
		// check if a specific character can be used in a legal variable/method/class name
		inline bool isLegalNameChar(char ch) const {
			return (isalnum(ch) || ch == '.' || ch == '_' || (isJavaStyle && ch == '$') || (isCStyle && ch == '~'));
		}

		// check if a specific character is a whitespace character
		inline bool isWhiteSpace(char ch) const {
			return (ch == ' ' || ch == '\t');
		}
};


class ASEnhancer
{
	public:
		// functions
		ASEnhancer();
		~ASEnhancer();
		void init(int, string, bool, bool, bool, bool, bool);
		void enhance(string &line);

	private:
		// set by init function
		int    indentLength;
		bool   useTabs;
		bool   isCStyle;
		bool   isJavaStyle;
		bool   isSharpStyle;
		bool   caseIndent;
		bool   emptyLineFill;

		// parsing variables
		int  lineNumber;
		bool isInQuote;
		bool isInComment;
		char quoteChar;

		// unindent variables
		int  bracketCount;
		int  switchDepth;
		bool lookingForCaseBracket;
		bool unindentNextLine;

		// stringstream for trace
		stringstream *traceOut;

	private:    // private functions
		bool findKeyword(const string &line, int i, const char *header) const;
		int  indentLine(string  &line, const int indent) const;
		int  unindentLine(string  &line, const int unindent) const;

	private:
		// struct used by ParseFormattedLine function
		// contains variables used to unindent the case blocks
		struct switchVariables {
			int  switchBracketCount;
			int  unindentDepth;
			bool unindentCase;

			switchVariables() {                 // constructor
				switchBracketCount = 0;
				unindentDepth = 0;
				unindentCase = false;
			}
		};

	private:    // inline functions
		// check if a specific character can be used in a legal variable/method/class name
		inline bool isLegalNameCharX(char ch) const {
			return (isalnum(ch) || ch == '.' || ch == '_' || (isJavaStyle && ch == '$') || (isCStyle && ch == '~'));
		}

		// check if a specific character is a whitespace character
		inline bool isWhiteSpaceX(char ch) const {
			return (ch == ' ' || ch == '\t');
		}
};


class ASFormatter : public ASBeautifier, private ASEnhancer
{
	public:
		ASFormatter();
		virtual ~ASFormatter();
		virtual void init(ASSourceIterator* iter);
		virtual bool hasMoreLines() const;
		virtual string nextLine();
		void setBracketFormatMode(BracketMode mode);
		void setBreakClosingHeaderBracketsMode(bool state);
		void setOperatorPaddingMode(bool mode);
		void setParensOutsidePaddingMode(bool mode);
		void setParensInsidePaddingMode(bool mode);
		void setParensUnPaddingMode(bool state);
		void setBreakOneLineBlocksMode(bool state);
		void setSingleStatementsMode(bool state);
		void setTabSpaceConversionMode(bool state);
		void setBreakBlocksMode(bool state);
		void setBreakClosingHeaderBlocksMode(bool state);
		void setBreakElseIfsMode(bool state);
		string fileName;

	private:
		void ASformatter(ASFormatter &copy);            // not to be imlpemented
		void operator=(ASFormatter&);                  // not to be implemented
		void staticInit();
		void goForward(int i);
		void trimNewLine();
		char peekNextChar() const;
		BracketType getBracketType() const;
		bool getNextChar();
		bool isBeforeComment() const;
		bool isBeforeLineEndComment(int startPos) const;
		bool isPointerOrReference() const;
		bool isUnaryMinus() const;
		bool isInExponent() const;
		bool isOneLineBlockReached() const;
//		bool isNextCharWhiteSpace() const;
		bool lineBeginsWith(char charToCheck) const;
		void appendChar(char ch, bool canBreakLine = true);
		void appendCharInsideComments();
		void appendSequence(const string &sequence, bool canBreakLine = true);
		void appendSpacePad();
		void appendSpaceAfter();
		void breakLine();
		void padOperators(const string *newOperator);
		void padParens();
		void formatBrackets(BracketType bracketType);
		void formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket);
		void adjustComments();
		const string *findHeader(const vector<const string*> &headers, bool checkBoundry = true);

		static vector<const string*> headers;
		static vector<const string*> nonParenHeaders;
		static vector<const string*> preDefinitionHeaders;
		static vector<const string*> preCommandHeaders;
		static vector<const string*> operators;
		static vector<const string*> assignmentOperators;
		static vector<const string*> castOperators;

		ASSourceIterator *sourceIterator;
		vector<const string*> *preBracketHeaderStack;
		vector<BracketType> *bracketTypeStack;
		vector<int> *parenStack;
		string readyFormattedLine;
		string currentLine;
		string formattedLine;
		const string *currentHeader;
		const string *previousOperator;    // used ONLY by pad=oper
		char currentChar;
		char previousChar;
		char previousNonWSChar;
		char previousCommandChar;
		char quoteChar;
		int  charNum;
		int  spacePadNum;
		int  templateDepth;
		int  traceFileNumber;
		size_t formattedLineCommentNum;		// comment location on formattedLine
		size_t previousReadyFormattedLineLength;
		BracketMode bracketFormatMode;
		BracketType previousBracketType;
		bool isVirgin;
		bool shouldPadOperators;
		bool shouldPadParensOutside;
		bool shouldPadParensInside;
		bool shouldUnPadParens;
		bool shouldConvertTabs;
		bool isInLineComment;
		bool isInComment;
		bool isInPreprocessor;
		bool isInTemplate;   // true both in template definitions (e.g. template<class A>) and template usage (e.g. F<int>).
		bool doesLineStartComment;
		bool isInQuote;
		bool isInBlParen;
		bool isSpecialChar;
		bool isNonParenHeader;
		bool foundQuestionMark;
		bool foundPreDefinitionHeader;
		bool foundNamespaceHeader;
		bool foundClassHeader;
		bool foundPreCommandHeader;
		bool foundCastOperator;
		bool isInLineBreak;
//		bool isInClosingBracketLineBreak;
		bool endOfCodeReached;
		bool lineCommentNoIndent;
		bool isLineReady;
		bool isPreviousBracketBlockRelated;
		bool isInPotentialCalculation;
		bool isCharImmediatelyPostComment;
		bool isPreviousCharPostComment;
		bool isCharImmediatelyPostLineComment;
		bool isCharImmediatelyPostOpenBlock;
		bool isCharImmediatelyPostCloseBlock;
		bool isCharImmediatelyPostTemplate;
		bool shouldBreakOneLineBlocks;
		bool shouldReparseCurrentChar;
		bool shouldBreakOneLineStatements;
		bool shouldBreakLineAfterComments;
		bool shouldBreakClosingHeaderBrackets;
		bool shouldBreakElseIfs;
		bool passedSemicolon;
		bool passedColon;
		bool isImmediatelyPostComment;
		bool isImmediatelyPostLineComment;
		bool isImmediatelyPostEmptyBlock;
		bool isImmediatelyPostPreprocessor;

		bool shouldBreakBlocks;
		bool shouldBreakClosingHeaderBlocks;
		bool isPrependPostBlockEmptyLineRequested;
		bool isAppendPostBlockEmptyLineRequested;

		bool prependEmptyLine;
		bool appendOpeningBracket;
		bool foundClosingHeader;

		bool isInHeader;
		bool isImmediatelyPostHeader;

	private:    // inline functions
		// append the CURRENT character (curentChar)to the current formatted line.
		inline void appendCurrentChar(bool canBreakLine = true) {
			appendChar(currentChar, canBreakLine);
		}

		// check if a specific sequence exists in the current placement of the current line
		inline bool isSequenceReached(const char *sequence) const {
			return currentLine.compare(charNum, strlen(sequence), sequence) == 0;
		}
};

}   // end of namespace astyle

#endif // closes ASTYLE_H