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