1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
5
* This file is a part of "Artistic Style" - an indentation and
6
* reformatting tool for C, C++, C# and Java source files.
7
* http://astyle.sourceforge.net
9
* The "Artistic Style" project, including all files needed to
10
* compile it, is free software; you can redistribute it and/or
11
* modify it under the terms of the GNU Lesser General Public
12
* License as published by the Free Software Foundation; either
13
* version 2.1 of the License, or (at your option) any later
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU Lesser General Public License for more details.
21
* You should have received a copy of the GNU Lesser General Public
22
* License along with this project; if not, write to the
23
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24
* Boston, MA 02110-1301, USA.
26
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
34
#define INIT_CONTAINER(container, value) {if ( (container) != NULL ) delete (container); (container) = (value); }
35
#define DELETE_CONTAINER(container) {if ( (container) != NULL ) delete (container); }
40
vector<const string*> ASBeautifier::headers;
41
vector<const string*> ASBeautifier::nonParenHeaders;
42
vector<const string*> ASBeautifier::preBlockStatements;
43
vector<const string*> ASBeautifier::assignmentOperators;
44
vector<const string*> ASBeautifier::nonAssignmentOperators;
48
* initialize the static vars
50
void ASBeautifier::initStatic()
52
static int beautifierFileType = 9; // initialized with an invalid type
54
if (fileType == beautifierFileType) // don't build unless necessary
57
beautifierFileType = fileType;
60
nonParenHeaders.clear();
61
assignmentOperators.clear();
62
nonAssignmentOperators.clear();
63
preBlockStatements.clear();
65
ASResource::buildHeaders(headers, fileType, true);
66
ASResource::buildNonParenHeaders(nonParenHeaders, fileType, true);
67
ASResource::buildAssignmentOperators(assignmentOperators);
68
ASResource::buildNonAssignmentOperators(nonAssignmentOperators);
69
ASResource::buildPreBlockStatements(preBlockStatements);
71
// cout << "beaut" << endl;
75
* ASBeautifier's constructor
77
ASBeautifier::ASBeautifier()
79
waitingBeautifierStack = NULL;
80
activeBeautifierStack = NULL;
81
waitingBeautifierStackLengthStack = NULL;
82
activeBeautifierStackLengthStack = NULL;
86
blockParenDepthStack = NULL;
87
blockStatementStack = NULL;
88
parenStatementStack = NULL;
89
bracketBlockStateStack = NULL;
90
inStatementIndentStack = NULL;
91
inStatementIndentStackSizeStack = NULL;
92
parenIndentStack = NULL;
93
sourceIterator = NULL;
95
isMinimalConditinalIndentSet = false;
96
shouldForceTabIndentation = false;
98
setSpaceIndentation(4);
99
setMaxInStatementIndentLength(40);
100
setClassIndent(false);
101
setSwitchIndent(false);
102
setCaseIndent(false);
103
setBlockIndent(false);
104
setBracketIndent(false);
105
setNamespaceIndent(false);
106
setLabelIndent(false);
107
setEmptyLineFill(false);
110
setPreprocessorIndent(false);
114
* ASBeautifier's copy constructor
116
ASBeautifier::ASBeautifier(const ASBeautifier &other)
118
waitingBeautifierStack = NULL;
119
activeBeautifierStack = NULL;
120
waitingBeautifierStackLengthStack = NULL;
121
activeBeautifierStackLengthStack = NULL;
123
headerStack = new vector<const string*>;
124
*headerStack = *other.headerStack;
126
tempStacks = new vector<vector<const string*>*>;
127
vector<vector<const string*>*>::iterator iter;
128
for (iter = other.tempStacks->begin();
129
iter != other.tempStacks->end();
132
vector<const string*> *newVec = new vector<const string*>;
134
tempStacks->push_back(newVec);
136
blockParenDepthStack = new vector<int>;
137
*blockParenDepthStack = *other.blockParenDepthStack;
139
blockStatementStack = new vector<bool>;
140
*blockStatementStack = *other.blockStatementStack;
142
parenStatementStack = new vector<bool>;
143
*parenStatementStack = *other.parenStatementStack;
145
bracketBlockStateStack = new vector<bool>;
146
*bracketBlockStateStack = *other.bracketBlockStateStack;
148
inStatementIndentStack = new vector<int>;
149
*inStatementIndentStack = *other.inStatementIndentStack;
151
inStatementIndentStackSizeStack = new vector<int>;
152
*inStatementIndentStackSizeStack = *other.inStatementIndentStackSizeStack;
154
parenIndentStack = new vector<int>;
155
*parenIndentStack = *other.parenIndentStack;
157
sourceIterator = other.sourceIterator;
159
// protected variables
160
fileType = other.fileType;
161
isCStyle = other.isCStyle;
162
isJavaStyle = other.isJavaStyle;
163
isSharpStyle = other.isSharpStyle;
165
// variables set by ASFormatter
166
// must also be updated in preprocessor
167
inLineNumber = other.inLineNumber;
168
outLineNumber = other.outLineNumber;
169
lineCommentNoBeautify = other.lineCommentNoBeautify;
170
isNonInStatementArray = other.isNonInStatementArray;
173
indentString = other.indentString;
174
currentHeader = other.currentHeader;
175
previousLastLineHeader = other.previousLastLineHeader;
176
immediatelyPreviousAssignmentOp = other.immediatelyPreviousAssignmentOp;
177
probationHeader = other.probationHeader;
178
isInQuote = other.isInQuote;
179
isInComment = other.isInComment;
180
isInCase = other.isInCase;
181
isInQuestion = other.isInQuestion;
182
isInStatement = other.isInStatement;
183
isInHeader = other.isInHeader;
184
isInOperator = other.isInOperator;
185
isInTemplate = other.isInTemplate;
186
isInDefine = other.isInDefine;
187
isInDefineDefinition = other.isInDefineDefinition;
188
classIndent = other.classIndent;
189
isInClassHeader = other.isInClassHeader;
190
isInClassHeaderTab = other.isInClassHeaderTab;
191
switchIndent = other.switchIndent;
192
caseIndent = other.caseIndent;
193
namespaceIndent = other.namespaceIndent;
194
bracketIndent = other.bracketIndent;
195
blockIndent = other.blockIndent;
196
labelIndent = other.labelIndent;
197
preprocessorIndent = other.preprocessorIndent;
198
isInConditional = other.isInConditional;
199
isMinimalConditinalIndentSet = other.isMinimalConditinalIndentSet;
200
shouldForceTabIndentation = other.shouldForceTabIndentation;
201
emptyLineFill = other.emptyLineFill;
202
backslashEndsPrevLine = other.backslashEndsPrevLine;
203
blockCommentNoIndent = other.blockCommentNoIndent;
204
blockCommentNoBeautify = other.blockCommentNoBeautify;
205
previousLineProbationTab = other.previousLineProbationTab;
206
minConditionalIndent = other.minConditionalIndent;
207
parenDepth = other.parenDepth;
208
indentLength = other.indentLength;
209
blockTabCount = other.blockTabCount;
210
leadingWhiteSpaces = other.leadingWhiteSpaces;
211
maxInStatementIndent = other.maxInStatementIndent;
212
templateDepth = other.templateDepth;
213
prevFinalLineSpaceTabCount = other.prevFinalLineSpaceTabCount;
214
prevFinalLineTabCount = other.prevFinalLineTabCount;
215
defineTabCount = other.defineTabCount;
216
quoteChar = other.quoteChar;
217
prevNonSpaceCh = other.prevNonSpaceCh;
218
currentNonSpaceCh = other.currentNonSpaceCh;
219
currentNonLegalCh = other.currentNonLegalCh;
220
prevNonLegalCh = other.prevNonLegalCh;
224
* ASBeautifier's destructor
226
ASBeautifier::~ASBeautifier()
228
DELETE_CONTAINER(headerStack);
229
DELETE_CONTAINER(blockParenDepthStack);
230
DELETE_CONTAINER(blockStatementStack);
231
DELETE_CONTAINER(parenStatementStack);
232
DELETE_CONTAINER(bracketBlockStateStack);
233
DELETE_CONTAINER(inStatementIndentStack);
234
DELETE_CONTAINER(inStatementIndentStackSizeStack);
235
DELETE_CONTAINER(parenIndentStack);
236
DELETE_CONTAINER(waitingBeautifierStackLengthStack);
237
DELETE_CONTAINER(activeBeautifierStackLengthStack);
240
vector< vector<const string*>* >::iterator iter = tempStacks->begin();
241
for(; iter != tempStacks->end(); iter++){
249
if(waitingBeautifierStack){
250
vector<ASBeautifier*>::iterator iter = waitingBeautifierStack->begin();
251
for(; iter != waitingBeautifierStack->end(); iter++){
254
waitingBeautifierStack->clear();
255
delete waitingBeautifierStack;
256
waitingBeautifierStack = NULL;
259
if(activeBeautifierStack){
260
vector<ASBeautifier*>::iterator iter = activeBeautifierStack->begin();
261
for(; iter != activeBeautifierStack->end(); iter++){
264
activeBeautifierStack->clear();
265
delete activeBeautifierStack;
266
activeBeautifierStack = NULL;
271
* initialize the ASBeautifier.
273
* init() should be called every time a ABeautifier object is to start
274
* beautifying a NEW source file.
275
* init() recieves a pointer to a DYNAMICALLY CREATED ASSourceIterator object
276
* that will be used to iterate through the source code. This object will be
277
* deleted during the ASBeautifier's destruction, and thus should not be
280
* @param iter a pointer to the DYNAMICALLY CREATED ASSourceIterator object.
282
void ASBeautifier::init(ASSourceIterator *iter)
284
sourceIterator = iter;
289
* initialize the ASBeautifier.
291
void ASBeautifier::init()
295
INIT_CONTAINER(waitingBeautifierStack, new vector<ASBeautifier*>);
296
INIT_CONTAINER(activeBeautifierStack, new vector<ASBeautifier*>);
298
INIT_CONTAINER(waitingBeautifierStackLengthStack, new vector<int>);
299
INIT_CONTAINER(activeBeautifierStackLengthStack, new vector<int>);
301
INIT_CONTAINER(headerStack, new vector<const string*>);
302
INIT_CONTAINER(tempStacks, new vector<vector<const string*>*>);
303
tempStacks->push_back(new vector<const string*>);
305
INIT_CONTAINER(blockParenDepthStack, new vector<int>);
306
INIT_CONTAINER(blockStatementStack, new vector<bool>);
307
INIT_CONTAINER(parenStatementStack, new vector<bool>);
309
INIT_CONTAINER(bracketBlockStateStack, new vector<bool>);
310
bracketBlockStateStack->push_back(true);
312
INIT_CONTAINER(inStatementIndentStack, new vector<int>);
313
INIT_CONTAINER(inStatementIndentStackSizeStack, new vector<int>);
314
inStatementIndentStackSizeStack->push_back(0);
315
INIT_CONTAINER(parenIndentStack, new vector<int>);
317
immediatelyPreviousAssignmentOp = NULL;
318
previousLastLineHeader = NULL;
319
currentHeader = NULL;
323
isInStatement = false;
325
isInQuestion = false;
326
isInClassHeader = false;
327
isInClassHeaderTab = false;
329
isInOperator = false;
330
isInTemplate = false;
331
isInConditional = false;
335
leadingWhiteSpaces = 0;
336
prevNonSpaceCh = '{';
337
currentNonSpaceCh = '{';
338
prevNonLegalCh = '{';
339
currentNonLegalCh = '{';
341
prevFinalLineSpaceTabCount = 0;
342
prevFinalLineTabCount = 0;
343
probationHeader = NULL;
344
backslashEndsPrevLine = false;
346
isInDefineDefinition = false;
348
lineCommentNoBeautify = false;
349
blockCommentNoIndent = false;
350
blockCommentNoBeautify = false;
351
previousLineProbationTab = false;
352
isNonInStatementArray = false;
353
inLineNumber = -1; // for debugging
354
outLineNumber = 0; // for debugging
358
* set indentation style to C/C++.
360
void ASBeautifier::setCStyle()
365
isSharpStyle = false;
369
* set indentation style to Java.
371
void ASBeautifier::setJavaStyle()
373
fileType = JAVA_TYPE;
376
isSharpStyle = false;
380
* set indentation style to C#.
382
void ASBeautifier::setSharpStyle()
384
fileType = SHARP_TYPE;
391
* indent using one tab per indentation
393
void ASBeautifier::setTabIndentation(int length, bool forceTabs)
396
indentLength = length;
397
shouldForceTabIndentation = forceTabs;
399
if (!isMinimalConditinalIndentSet)
400
minConditionalIndent = indentLength * 2;
404
* indent using a number of spaces per indentation.
406
* @param length number of spaces per indent.
408
void ASBeautifier::setSpaceIndentation(int length)
410
indentString = string(length, ' ');
411
indentLength = length;
413
if (!isMinimalConditinalIndentSet)
414
minConditionalIndent = indentLength * 2;
418
* set the maximum indentation between two lines in a multi-line statement.
420
* @param max maximum indentation length.
422
void ASBeautifier::setMaxInStatementIndentLength(int max)
424
maxInStatementIndent = max;
428
* set the minimum indentation between two lines in a multi-line condition.
430
* @param min minimal indentation length.
432
void ASBeautifier::setMinConditionalIndentLength(int min)
434
minConditionalIndent = min;
435
isMinimalConditinalIndentSet = true;
439
* set the state of the bracket indentation option. If true, brackets will
440
* be indented one additional indent.
442
* @param state state of option.
444
void ASBeautifier::setBracketIndent(bool state)
446
bracketIndent = state;
450
* set the state of the block indentation option. If true, entire blocks
451
* will be indented one additional indent, similar to the GNU indent style.
453
* @param state state of option.
455
void ASBeautifier::setBlockIndent(bool state)
458
setBracketIndent(false); // so that we don't have both bracket and block indent
463
* set the state of the class indentation option. If true, C++ class
464
* definitions will be indented one additional indent.
466
* @param state state of option.
468
void ASBeautifier::setClassIndent(bool state)
474
* set the state of the switch indentation option. If true, blocks of 'switch'
475
* statements will be indented one additional indent.
477
* @param state state of option.
479
void ASBeautifier::setSwitchIndent(bool state)
481
switchIndent = state;
485
* set the state of the case indentation option. If true, lines of 'case'
486
* statements will be indented one additional indent.
488
* @param state state of option.
490
void ASBeautifier::setCaseIndent(bool state)
496
* set the state of the namespace indentation option.
497
* If true, blocks of 'namespace' statements will be indented one
498
* additional indent. Otherwise, NO indentation will be added.
500
* @param state state of option.
502
void ASBeautifier::setNamespaceIndent(bool state)
504
namespaceIndent = state;
508
* set the state of the label indentation option.
509
* If true, labels will be indented one indent LESS than the
510
* current indentation level.
511
* If false, labels will be flushed to the left with NO
514
* @param state state of option.
516
void ASBeautifier::setLabelIndent(bool state)
522
* set the state of the preprocessor indentation option.
523
* If true, multiline #define statements will be indented.
525
* @param state state of option.
527
void ASBeautifier::setPreprocessorIndent(bool state)
529
preprocessorIndent = state;
533
* set the state of the empty line fill option.
534
* If true, empty lines will be filled with the whitespace.
535
* of their previous lines.
536
* If false, these lines will remain empty.
538
* @param state state of option.
540
void ASBeautifier::setEmptyLineFill(bool state)
542
emptyLineFill = state;
546
* get the number of spaces per indent
548
* @return value of indentLength option.
550
int ASBeautifier::getIndentLength(void)
556
* get the char used for indentation, space or tab
558
* @return the char used for indentation.
560
string ASBeautifier::getIndentString(void)
566
* get the state of the case indentation option. If true, lines of 'case'
567
* statements will be indented one additional indent.
569
* @return state of caseIndent option.
571
bool ASBeautifier::getCaseIndent(void)
577
* get C style identifier.
578
* If true, a C source is being indented.
580
* @return state of isCStyle option.
582
bool ASBeautifier::getCStyle(void)
588
* get Java style identifier.
589
* If true, a Java source is being indented.
591
* @return state of isJavaStyle option.
593
bool ASBeautifier::getJavaStyle(void)
599
* get C# style identifier.
600
* If true, a C# source is being indented.
602
* @return state of isSharpStyle option.
604
bool ASBeautifier::getSharpStyle(void)
610
* get the state of the empty line fill option.
611
* If true, empty lines will be filled with the whitespace.
612
* of their previous lines.
613
* If false, these lines will remain empty.
615
* @return state of emptyLineFill option.
617
bool ASBeautifier::getEmptyLineFill(void)
619
return emptyLineFill;
623
* check if there are any indented lines ready to be read by nextLine()
625
* @return are there any indented lines ready?
627
bool ASBeautifier::hasMoreLines() const
629
return sourceIterator->hasMoreLines();
633
* get the next indented line.
635
* @return indented line.
637
string ASBeautifier::nextLine()
639
return beautify(sourceIterator->nextLine());
643
* beautify a line of source code.
644
* every line of source code in a source code file should be sent
645
* one after the other to the beautify method.
647
* @return the indented line.
648
* @param originalLine the original unindented line.
650
string ASBeautifier::beautify(const string &originalLine)
653
bool isInLineComment = false;
654
bool lineStartsInComment = false;
655
bool isInClass = false;
656
bool isInSwitch = false;
657
bool isImmediatelyAfterConst = false;
658
bool isSpecialChar = false;
661
string outBuffer; // the newly idented line is bufferd here
663
const string *lastLineHeader = NULL;
664
bool closingBracketReached = false;
665
int spaceTabCount = 0;
667
size_t headerStackSize = headerStack->size();
668
bool shouldIndentBrackettedLine = true;
669
int lineOpeningBlocksNum = 0;
670
int lineClosingBlocksNum = 0;
671
bool previousLineProbation = (probationHeader != NULL);
674
currentHeader = NULL;
675
lineStartsInComment = isInComment;
676
blockCommentNoBeautify = blockCommentNoIndent;
677
previousLineProbationTab = false;
680
// handle and remove white spaces around the line:
681
// If not in comment, first find out size of white space before line,
682
// so that possible comments starting in the line continue in
683
// relation to the preliminary white-space.
686
int strlen = originalLine.length();
687
leadingWhiteSpaces = 0;
689
for (int j = 0; j < strlen && isWhiteSpace(originalLine[j]); j++)
691
if (originalLine[j] == '\t')
692
leadingWhiteSpaces += indentLength;
694
leadingWhiteSpaces++;
696
line = trim(originalLine);
700
// convert leading tabs to spaces
701
string spaceTabs(indentLength, ' ');
702
string newLine = originalLine;
703
int strlen = newLine.length();
705
for (int j=0; j < leadingWhiteSpaces && j < strlen; j++)
707
if (newLine[j] == '\t')
709
newLine.replace(j, 1, spaceTabs);
710
strlen = newLine.length();
714
// trim the comment leaving the new leading whitespace
716
strlen = newLine.length();
718
while (trimSize < strlen
719
&& trimSize < leadingWhiteSpaces
720
&& isWhiteSpace(newLine[trimSize]))
724
while (trimSize < strlen && isWhiteSpace(newLine[strlen-1]))
727
line = newLine.substr(trimSize, strlen);
728
size_t trimEnd = line.find_last_not_of(" \t");
729
if (trimEnd != string::npos)
731
int spacesToDelete = line.length() - 1 - trimEnd;
732
if (spacesToDelete > 0)
733
line.erase(trimEnd + 1, spacesToDelete);
738
if (line.length() == 0)
740
if (backslashEndsPrevLine) // must continue to clear variables
742
else if (emptyLineFill)
743
return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
748
// handle preprocessor commands
750
if (isCStyle && !isInComment && (line[0] == '#' || backslashEndsPrevLine))
754
string preproc = trim(string(line.c_str() + 1));
756
// When finding a multi-lined #define statement, the original beautifier
757
// 1. sets its isInDefineDefinition flag
758
// 2. clones a new beautifier that will be used for the actual indentation
759
// of the #define. This clone is put into the activeBeautifierStack in order
760
// to be called for the actual indentation.
761
// The original beautifier will have isInDefineDefinition = true, isInDefine = false
762
// The cloned beautifier will have isInDefineDefinition = true, isInDefine = true
763
if (preprocessorIndent && preproc.compare(0, 6, "define") == 0 && line[line.length() - 1] == '\\')
765
if (!isInDefineDefinition)
767
ASBeautifier *defineBeautifier;
769
// this is the original beautifier
770
isInDefineDefinition = true;
772
// push a new beautifier into the active stack
773
// this beautifier will be used for the indentation of this define
774
defineBeautifier = new ASBeautifier(*this);
775
activeBeautifierStack->push_back(defineBeautifier);
779
// the is the cloned beautifier that is in charge of indenting the #define.
783
else if (preproc.compare(0, 2, "if") == 0)
785
// push a new beautifier into the stack
786
waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
787
activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
788
waitingBeautifierStack->push_back(new ASBeautifier(*this));
790
else if (preproc.compare(0, 4/*2*/, "else") == 0)
792
if (waitingBeautifierStack && !waitingBeautifierStack->empty())
794
// MOVE current waiting beautifier to active stack.
795
activeBeautifierStack->push_back(waitingBeautifierStack->back());
796
waitingBeautifierStack->pop_back();
799
else if (preproc.compare(0, 4, "elif") == 0)
801
if (waitingBeautifierStack && !waitingBeautifierStack->empty())
803
// append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
804
activeBeautifierStack->push_back(new ASBeautifier(*(waitingBeautifierStack->back())));
807
else if (preproc.compare(0, 5, "endif") == 0)
810
ASBeautifier *beautifier;
812
if (waitingBeautifierStackLengthStack && !waitingBeautifierStackLengthStack->empty())
814
stackLength = waitingBeautifierStackLengthStack->back();
815
waitingBeautifierStackLengthStack->pop_back();
816
while ((int) waitingBeautifierStack->size() > stackLength)
818
beautifier = waitingBeautifierStack->back();
819
waitingBeautifierStack->pop_back();
824
if (!activeBeautifierStackLengthStack->empty())
826
stackLength = activeBeautifierStackLengthStack->back();
827
activeBeautifierStackLengthStack->pop_back();
828
while ((int) activeBeautifierStack->size() > stackLength)
830
beautifier = activeBeautifierStack->back();
831
activeBeautifierStack->pop_back();
838
// check if the last char is a backslash
839
if (line.length() > 0)
840
backslashEndsPrevLine = (line[line.length() - 1] == '\\');
842
backslashEndsPrevLine = false;
844
// check if this line ends a multi-line #define
845
// if so, use the #define's cloned beautifier for the line's indentation
846
// and then remove it from the active beautifier stack and delete it.
847
if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine)
849
string beautifiedLine;
850
ASBeautifier *defineBeautifier;
852
isInDefineDefinition = false;
853
defineBeautifier = activeBeautifierStack->back();
854
activeBeautifierStack->pop_back();
856
beautifiedLine = defineBeautifier->beautify(line);
857
delete defineBeautifier;
858
return beautifiedLine;
861
// unless this is a multi-line #define, return this precompiler line as is.
862
if (!isInDefine && !isInDefineDefinition)
866
// if there exists any worker beautifier in the activeBeautifierStack,
867
// then use it instead of me to indent the current line.
868
// variables set by ASFormatter must be updated.
869
if (!isInDefine && activeBeautifierStack != NULL && !activeBeautifierStack->empty())
871
activeBeautifierStack->back()->inLineNumber = inLineNumber;
872
activeBeautifierStack->back()->outLineNumber = outLineNumber;
873
activeBeautifierStack->back()->lineCommentNoBeautify = lineCommentNoBeautify;
874
activeBeautifierStack->back()->isNonInStatementArray = isNonInStatementArray;
875
return activeBeautifierStack->back()->beautify(line);
878
// calculate preliminary indentation based on data from past lines
879
if (!inStatementIndentStack->empty())
880
spaceTabCount = inStatementIndentStack->back();
883
for (i = 0; i < (int) headerStackSize; i++)
887
if (blockIndent || (!(i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET
888
&& (*headerStack)[i] == &AS_OPEN_BRACKET)))
891
if (!isJavaStyle && !namespaceIndent && i >= 1
892
&& (*headerStack)[i-1] == &AS_NAMESPACE
893
&& (*headerStack)[i] == &AS_OPEN_BRACKET)
896
if (isCStyle && i >= 1
897
&& (*headerStack)[i-1] == &AS_CLASS
898
&& (*headerStack)[i] == &AS_OPEN_BRACKET)
905
// is the switchIndent option is on, indent switch statements an additional indent.
906
else if (switchIndent && i > 1 &&
907
(*headerStack)[i-1] == &AS_SWITCH &&
908
(*headerStack)[i] == &AS_OPEN_BRACKET
917
if (!lineStartsInComment
921
&& headerStackSize >= 2
922
&& (*headerStack)[headerStackSize-2] == &AS_CLASS
923
&& (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
927
else if (!lineStartsInComment
930
&& headerStackSize >= 2
931
&& (*headerStack)[headerStackSize-2] == &AS_SWITCH
932
&& (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
938
isInClassHeaderTab = true;
948
// parse characters in the current line.
950
for (i = 0; i < (int) line.length(); i++)
957
outBuffer.append(1, ch);
959
if (isWhiteSpace(ch))
962
// check for utf8 characters
963
// isalnum() will display an assert message in debug if not bypassed here
967
// handle special characters (i.e. backslash+character such as \n, \t, ...)
970
isSpecialChar = false;
973
if (!(isInComment || isInLineComment) && line.compare(i, 2, "\\\\") == 0)
975
outBuffer.append(1, '\\');
979
if (!(isInComment || isInLineComment) && ch == '\\')
981
isSpecialChar = true;
985
// handle quotes (such as 'x' and "Hello Dolly")
986
if (!(isInComment || isInLineComment) && (ch == '"' || ch == '\''))
992
else if (quoteChar == ch)
995
isInStatement = true;
1003
if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0)
1005
isInLineComment = true;
1006
outBuffer.append(1, '/');
1010
else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0)
1013
outBuffer.append(1, '*');
1015
size_t j = line.find_first_not_of(" \t");
1016
if (!line.compare(j, 2, "/*") == 0) // does line start with comment?
1017
blockCommentNoIndent = true; // if no, cannot indent continuation lines
1020
else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0)
1022
isInComment = false;
1023
outBuffer.append(1, '/');
1025
blockCommentNoIndent = false; // ok to indent next comment
1029
if (isInComment || isInLineComment)
1032
// if we have reached this far then we are NOT in a comment or string of special character...
1034
if (probationHeader != NULL)
1036
if (((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{')
1037
|| (probationHeader == &AS_SYNCHRONIZED && ch == '('))
1039
// insert the probation header as a new header
1041
headerStack->push_back(probationHeader);
1043
// handle the specific probation header
1044
isInConditional = (probationHeader == &AS_SYNCHRONIZED);
1045
if (probationHeader == &AS_CONST)
1046
isImmediatelyAfterConst = true;
1048
isInStatement = false;
1049
// if the probation comes from the previous line, then indent by 1 tab count.
1050
if (previousLineProbation && ch == '{')
1053
previousLineProbationTab = true;
1055
previousLineProbation = false;
1058
// dismiss the probation header
1059
probationHeader = NULL;
1062
prevNonSpaceCh = currentNonSpaceCh;
1063
currentNonSpaceCh = ch;
1064
if (!isLegalNameChar(ch) && ch != ',' && ch != ';')
1066
prevNonLegalCh = currentNonLegalCh;
1067
currentNonLegalCh = ch;
1073
currentHeader = headerStack->back();
1076
currentHeader = NULL;
1078
if (isCStyle && isInTemplate
1079
&& (ch == '<' || ch == '>')
1080
&& findHeader(line, i, nonAssignmentOperators) == NULL)
1088
if (--templateDepth <= 0)
1094
isInTemplate = false;
1100
// handle parenthesies
1101
if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
1103
if (ch == '(' || ch == '[')
1105
if (parenDepth == 0)
1107
parenStatementStack->push_back(isInStatement);
1108
isInStatement = true;
1112
inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
1114
if (currentHeader != NULL)
1115
registerInStatementIndent(line, i, spaceTabCount, minConditionalIndent/*indentLength*2*/, true);
1117
registerInStatementIndent(line, i, spaceTabCount, 0, true);
1119
else if (ch == ')' || ch == ']')
1122
if (parenDepth == 0)
1124
isInStatement = parenStatementStack->back();
1125
parenStatementStack->pop_back();
1128
isInConditional = false;
1131
if (!inStatementIndentStackSizeStack->empty())
1133
int previousIndentStackSize = inStatementIndentStackSizeStack->back();
1134
inStatementIndentStackSizeStack->pop_back();
1135
while (previousIndentStackSize < (int) inStatementIndentStack->size())
1136
inStatementIndentStack->pop_back();
1138
if (!parenIndentStack->empty())
1140
int poppedIndent = parenIndentStack->back();
1141
parenIndentStack->pop_back();
1144
spaceTabCount = poppedIndent;
1156
// first, check if '{' is a block-opener or an static-array opener
1157
isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back())
1158
|| prevNonSpaceCh == '}'
1159
|| prevNonSpaceCh == ')'
1160
|| prevNonSpaceCh == ';'
1161
|| peekNextChar(line, i) == '{'
1162
|| isNonInStatementArray
1165
|| isImmediatelyAfterConst
1167
(prevNonSpaceCh == '('
1168
|| prevNonSpaceCh == '_'
1169
|| isalnum(prevNonSpaceCh))));
1171
isInClassHeader = false;
1172
if (!isBlockOpener && currentHeader != NULL)
1174
for (size_t n = 0; n < nonParenHeaders.size(); n++)
1175
if (currentHeader == nonParenHeaders[n])
1177
isBlockOpener = true;
1181
bracketBlockStateStack->push_back(isBlockOpener);
1184
inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
1185
registerInStatementIndent(line, i, spaceTabCount, 0, true);
1188
shouldIndentBrackettedLine = false;
1193
// this bracket is a block opener...
1195
++lineOpeningBlocksNum;
1196
// if (isInClassHeader)
1197
// isInClassHeader = false;
1199
if (isInClassHeaderTab)
1201
isInClassHeaderTab = false;
1202
// decrease tab count if bracket is broken
1203
size_t firstChar = line.find_first_not_of(" \t");
1204
if (firstChar != string::npos)
1205
if (line[firstChar] == '{' && (int) firstChar == i)
1209
// do not allow inStatementIndent - should occur for Java files only
1210
if (inStatementIndentStack->size() > 0)
1213
inStatementIndentStack->back() = 0;
1216
blockParenDepthStack->push_back(parenDepth);
1217
blockStatementStack->push_back(isInStatement);
1219
inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
1220
if (inStatementIndentStack->size() > 0)
1221
inStatementIndentStack->back() = 0;
1223
blockTabCount += isInStatement ? 1 : 0;
1225
isInStatement = false;
1227
tempStacks->push_back(new vector<const string*>);
1228
headerStack->push_back(&AS_OPEN_BRACKET);
1229
lastLineHeader = &AS_OPEN_BRACKET;
1234
//check if a header has been reached
1235
if (isWhiteSpace(prevCh))
1237
bool isIndentableHeader = true;
1238
const string *newHeader = findHeader(line, i, headers);
1239
if (newHeader != NULL)
1241
// if we reached here, then this is a header...
1244
vector<const string*> *lastTempStack;
1245
if (tempStacks->empty())
1246
lastTempStack = NULL;
1248
lastTempStack = tempStacks->back();
1250
// if a new block is opened, push a new stack into tempStacks to hold the
1251
// future list of headers in the new block.
1253
// take care of the special case: 'else if (...)'
1254
if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
1256
headerStack->pop_back();
1259
// take care of 'else'
1260
else if (newHeader == &AS_ELSE)
1262
if (lastTempStack != NULL)
1264
int indexOfIf = indexOf(*lastTempStack, &AS_IF);
1265
if (indexOfIf != -1)
1267
// recreate the header list in headerStack up to the previous 'if'
1268
// from the temporary snapshot stored in lastTempStack.
1269
int restackSize = lastTempStack->size() - indexOfIf - 1;
1270
for (int r = 0; r < restackSize; r++)
1272
headerStack->push_back(lastTempStack->back());
1273
lastTempStack->pop_back();
1275
if (!closingBracketReached)
1276
tabCount += restackSize;
1279
* If the above if is not true, i.e. no 'if' before the 'else',
1280
* then nothing beautiful will come out of this...
1281
* I should think about inserting an Exception here to notify the caller of this...
1286
// check if 'while' closes a previous 'do'
1287
else if (newHeader == &AS_WHILE)
1289
if (lastTempStack != NULL)
1291
int indexOfDo = indexOf(*lastTempStack, &AS_DO);
1292
if (indexOfDo != -1)
1294
// recreate the header list in headerStack up to the previous 'do'
1295
// from the temporary snapshot stored in lastTempStack.
1296
int restackSize = lastTempStack->size() - indexOfDo - 1;
1297
for (int r = 0; r < restackSize; r++)
1299
headerStack->push_back(lastTempStack->back());
1300
lastTempStack->pop_back();
1302
if (!closingBracketReached)
1303
tabCount += restackSize;
1307
// check if 'catch' closes a previous 'try' or 'catch'
1308
else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
1310
if (lastTempStack != NULL)
1312
int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
1313
if (indexOfTry == -1)
1314
indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
1315
if (indexOfTry != -1)
1317
// recreate the header list in headerStack up to the previous 'try'
1318
// from the temporary snapshot stored in lastTempStack.
1319
int restackSize = lastTempStack->size() - indexOfTry - 1;
1320
for (int r = 0; r < restackSize; r++)
1322
headerStack->push_back(lastTempStack->back());
1323
lastTempStack->pop_back();
1326
if (!closingBracketReached)
1327
tabCount += restackSize;
1331
else if (newHeader == &AS_CASE)
1336
else if (newHeader == &AS_DEFAULT)
1341
else if (newHeader == &AS_STATIC
1342
|| newHeader == &AS_SYNCHRONIZED
1343
|| (newHeader == &AS_CONST && isCStyle))
1345
if (!headerStack->empty() &&
1346
(headerStack->back() == &AS_STATIC
1347
|| headerStack->back() == &AS_SYNCHRONIZED
1348
|| headerStack->back() == &AS_CONST))
1350
isIndentableHeader = false;
1354
isIndentableHeader = false;
1355
probationHeader = newHeader;
1358
else if (newHeader == &AS_CONST)
1360
isIndentableHeader = false;
1362
else if (newHeader == &AS_TEMPLATE)
1365
isInTemplate = true;
1366
isIndentableHeader = false;
1370
if (isIndentableHeader)
1372
headerStack->push_back(newHeader);
1373
isInStatement = false;
1374
if (indexOf(nonParenHeaders, newHeader) == -1)
1376
isInConditional = true;
1378
lastLineHeader = newHeader;
1383
outBuffer.append(newHeader->substr(1));
1384
i += newHeader->length() - 1;
1390
if (isCStyle && !isalpha(prevCh)
1391
&& line.compare(i, 8, "operator") == 0 && !isalnum(line[i+8]))
1393
isInOperator = true;
1394
outBuffer.append(AS_OPERATOR.substr(1));
1399
// "new" operator is a pointer, not a calculation
1400
if (!isalpha(prevCh)
1401
&& line.compare(i, 3, "new") == 0 && !isalnum(line[i+3]))
1403
if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty())
1404
inStatementIndentStack->back() = 0;
1408
isInQuestion = true;
1411
// special handling of 'case' statements
1414
if ((int) line.length() > i + 1 && line[i+1] == ':') // look for ::
1417
outBuffer.append(1, ':');
1422
else if (isInQuestion)
1424
isInQuestion = false;
1427
else if (isCStyle && isInClass && prevNonSpaceCh != ')')
1430
// found a 'private:' or 'public:' inside a class definition
1431
// so do nothing special
1434
else if (!isJavaStyle && isInClassHeader)
1436
// found a 'class A : public B' definition
1437
// so do nothing special
1440
else if (isJavaStyle && lastLineHeader == &AS_FOR)
1442
// found a java for-each statement
1443
// so do nothing special
1446
else if (isCStyle && prevNonSpaceCh == ')')
1448
isInClassHeader = true;
1454
currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers
1458
ch = ';'; // from here on, treat char as ';'
1462
else // is in a label (e.g. 'label1:')
1465
--tabCount; // unindent label by one indent
1467
tabCount = 0; // completely flush indent to left
1475
if ((ch == ';' || (parenDepth > 0 && ch == ',')) && !inStatementIndentStackSizeStack->empty())
1476
while ((int) inStatementIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0)
1477
< (int) inStatementIndentStack->size())
1478
inStatementIndentStack->pop_back();
1481
// handle ends of statements
1482
if ((ch == ';' && parenDepth == 0) || ch == '}'/* || (ch == ',' && parenDepth == 0)*/)
1486
// first check if this '}' closes a previous block, or a static array...
1487
if (!bracketBlockStateStack->empty())
1489
bool bracketBlockState = bracketBlockStateStack->back();
1490
bracketBlockStateStack->pop_back();
1491
if (!bracketBlockState)
1493
if (!inStatementIndentStackSizeStack->empty())
1495
// this bracket is a static array
1497
int previousIndentStackSize = inStatementIndentStackSizeStack->back();
1498
inStatementIndentStackSizeStack->pop_back();
1499
while (previousIndentStackSize < (int) inStatementIndentStack->size())
1500
inStatementIndentStack->pop_back();
1503
shouldIndentBrackettedLine = false;
1505
if (!parenIndentStack->empty())
1507
int poppedIndent = parenIndentStack->back();
1508
parenIndentStack->pop_back();
1510
spaceTabCount = poppedIndent;
1517
// this bracket is block closer...
1519
++lineClosingBlocksNum;
1521
if (!inStatementIndentStackSizeStack->empty())
1522
inStatementIndentStackSizeStack->pop_back();
1524
if (!blockParenDepthStack->empty())
1526
parenDepth = blockParenDepthStack->back();
1527
blockParenDepthStack->pop_back();
1528
isInStatement = blockStatementStack->back();
1529
blockStatementStack->pop_back();
1535
closingBracketReached = true;
1536
int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET);
1537
if (headerPlace != -1)
1539
const string *popped = headerStack->back();
1540
while (popped != &AS_OPEN_BRACKET)
1542
headerStack->pop_back();
1543
popped = headerStack->back();
1545
headerStack->pop_back();
1547
if (!tempStacks->empty())
1549
vector<const string*> *temp = tempStacks->back();
1550
tempStacks->pop_back();
1556
ch = ' '; // needed due to cases such as '}else{', so that headers ('else' tn tih case) will be identified...
1560
* Create a temporary snapshot of the current block's header-list in the
1561
* uppermost inner stack in tempStacks, and clear the headerStack up to
1562
* the begining of the block.
1563
* Thus, the next future statement will think it comes one indent past
1564
* the block's '{' unless it specifically checks for a companion-header
1565
* (such as a previous 'if' for an 'else' header) within the tempStacks,
1566
* and recreates the temporary snapshot by manipulating the tempStacks.
1568
if (!tempStacks->back()->empty())
1569
while (!tempStacks->back()->empty())
1570
tempStacks->back()->pop_back();
1572
while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET)
1574
tempStacks->back()->push_back(headerStack->back());
1575
headerStack->pop_back();
1578
if (parenDepth == 0 && ch == ';')
1579
isInStatement = false;
1581
previousLastLineHeader = NULL;
1582
isInClassHeader = false;
1583
isInQuestion = false;
1589
// check for preBlockStatements ONLY if not within parenthesies
1590
// (otherwise 'struct XXX' statements would be wrongly interpreted...)
1591
if (isWhiteSpace(prevCh) && !isInTemplate && parenDepth == 0)
1593
const string *newHeader = findHeader(line, i, preBlockStatements);
1594
if (newHeader != NULL)
1596
isInClassHeader = true;
1597
outBuffer.append(newHeader->substr(1));
1598
i += newHeader->length() - 1;
1599
headerStack->push_back(newHeader);
1605
immediatelyPreviousAssignmentOp = NULL;
1607
// Check if an operator has been reached.
1608
const string *foundAssignmentOp = findHeader(line, i, assignmentOperators, false);
1609
if (foundAssignmentOp == &AS_RETURN)
1610
foundAssignmentOp = findHeader(line, i, assignmentOperators, true);
1611
const string *foundNonAssignmentOp = findHeader(line, i, nonAssignmentOperators, false);
1613
// Since findHeader's boundry checking was not used above, it is possible
1614
// that both an assignment op and a non-assignment op where found,
1615
// e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the
1617
if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL)
1618
if (foundAssignmentOp->length() < foundNonAssignmentOp->length())
1619
foundAssignmentOp = NULL;
1621
foundNonAssignmentOp = NULL;
1623
if (foundNonAssignmentOp != NULL)
1625
if (foundNonAssignmentOp->length() > 1)
1627
outBuffer.append(foundNonAssignmentOp->substr(1));
1628
i += foundNonAssignmentOp->length() - 1;
1632
else if (foundAssignmentOp != NULL)
1634
if (foundAssignmentOp->length() > 1)
1636
outBuffer.append(foundAssignmentOp->substr(1));
1637
i += foundAssignmentOp->length() - 1;
1640
if (!isInOperator && !isInTemplate && !isNonInStatementArray)
1642
registerInStatementIndent(line, i, spaceTabCount, 0, false);
1643
immediatelyPreviousAssignmentOp = foundAssignmentOp;
1644
isInStatement = true;
1649
isInOperator = false;
1652
// handle special cases of unindentation:
1655
* if '{' doesn't follow an immediately previous '{' in the headerStack
1656
* (but rather another header such as "for" or "if", then unindent it
1657
* by one indentation relative to its block.
1660
if (!lineStartsInComment
1662
&& outBuffer.length() > 0
1663
&& outBuffer[0] == '{'
1664
&& !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
1665
&& !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET)
1666
&& shouldIndentBrackettedLine)
1669
else if (!lineStartsInComment
1670
&& outBuffer.length() > 0
1671
&& outBuffer[0] == '}'
1672
&& shouldIndentBrackettedLine)
1675
// correctly indent one-line-blocks...
1676
else if (!lineStartsInComment
1677
&& outBuffer.length() > 0
1678
&& lineOpeningBlocksNum > 0
1679
&& lineOpeningBlocksNum == lineClosingBlocksNum
1680
&& previousLineProbationTab)
1681
--tabCount; //lineOpeningBlocksNum - (blockIndent ? 1 : 0);
1686
// take care of extra bracket indentatation option...
1687
if (bracketIndent && outBuffer.length() > 0 && shouldIndentBrackettedLine)
1688
if (outBuffer[0] == '{' || outBuffer[0] == '}')
1694
if (outBuffer[0] == '#')
1696
string preproc = trim(string(outBuffer.c_str() + 1));
1697
if (preproc.compare(0, 6, "define") == 0)
1699
if (!inStatementIndentStack->empty()
1700
&& inStatementIndentStack->back() > 0)
1702
defineTabCount = tabCount;
1706
defineTabCount = tabCount - 1;
1712
tabCount -= defineTabCount;
1717
if (lineCommentNoBeautify || blockCommentNoBeautify)
1718
tabCount = spaceTabCount = 0;
1720
// finally, insert indentations into begining of line
1722
prevFinalLineSpaceTabCount = spaceTabCount;
1723
prevFinalLineTabCount = tabCount;
1725
if (shouldForceTabIndentation)
1727
tabCount += spaceTabCount / indentLength;
1728
spaceTabCount = spaceTabCount % indentLength;
1731
outBuffer = preLineWS(spaceTabCount, tabCount) + outBuffer;
1733
if (lastLineHeader != NULL)
1734
previousLastLineHeader = lastLineHeader;
1740
string ASBeautifier::preLineWS(int spaceTabCount, int tabCount)
1744
for (int i = 0; i < tabCount; i++)
1747
while ((spaceTabCount--) > 0)
1755
* register an in-statement indent.
1757
void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount,
1758
int minIndent, bool updateParenStack)
1760
int inStatementIndent;
1761
int remainingCharNum = line.length() - i;
1762
int nextNonWSChar = getNextProgramCharDistance(line, i);
1764
// if indent is around the last char in the line, indent instead 2 spaces from the previous indent
1765
if (nextNonWSChar == remainingCharNum)
1767
int previousIndent = spaceTabCount;
1768
if (!inStatementIndentStack->empty())
1769
previousIndent = inStatementIndentStack->back();
1771
inStatementIndentStack->push_back(/*2*/ indentLength + previousIndent);
1772
if (updateParenStack)
1773
parenIndentStack->push_back(previousIndent);
1777
if (updateParenStack)
1778
parenIndentStack->push_back(i + spaceTabCount);
1780
inStatementIndent = i + nextNonWSChar + spaceTabCount;
1782
if (i + nextNonWSChar < minIndent)
1783
inStatementIndent = minIndent + spaceTabCount;
1785
if (i + nextNonWSChar > maxInStatementIndent)
1786
inStatementIndent = indentLength * 2 + spaceTabCount;
1788
if (!inStatementIndentStack->empty() &&
1789
inStatementIndent < inStatementIndentStack->back())
1790
inStatementIndent = inStatementIndentStack->back();
1792
if (isNonInStatementArray)
1793
inStatementIndent = 0;
1795
inStatementIndentStack->push_back(inStatementIndent);
1799
* get distance to the next non-white sspace, non-comment character in the line.
1800
* if no such character exists, return the length remaining to the end of the line.
1802
int ASBeautifier::getNextProgramCharDistance(const string &line, int i)
1804
bool inComment = false;
1805
int remainingCharNum = line.length() - i;
1809
for (charDistance = 1; charDistance < remainingCharNum; charDistance++)
1811
ch = line[i + charDistance];
1814
if (line.compare(i + charDistance, 2, "*/") == 0)
1821
else if (isWhiteSpace(ch))
1825
if (line.compare(i + charDistance, 2, "//") == 0)
1826
return remainingCharNum;
1827
else if (line.compare(i + charDistance, 2, "/*") == 0)
1834
return charDistance;
1837
return charDistance;
1842
* check if a specific line position contains a header, out of several possible headers.
1844
* @return a pointer to the found header. if no header was found then return NULL.
1846
const string *ASBeautifier::findHeader(const string &line, int i, const vector<const string*> &possibleHeaders, bool checkBoundry)
1848
int maxHeaders = possibleHeaders.size();
1849
// const string *header = NULL;
1852
for (p = 0; p < maxHeaders; p++)
1854
const string *header = possibleHeaders[p];
1856
if (line.compare(i, header->length(), header->c_str()) == 0)
1858
// check that this is a header and not a part of a longer word
1859
// (e.g. not at its begining, not at its middle...)
1861
int lineLength = line.length();
1862
int headerEnd = i + header->length();
1863
char startCh = (*header)[0]; // first char of header
1864
char endCh = 0; // char just after header
1865
char prevCh = 0; // char just before header
1867
if (headerEnd < lineLength)
1869
endCh = line[headerEnd];
1880
else if (prevCh != 0
1881
&& isLegalNameChar(startCh)
1882
&& isLegalNameChar(prevCh))
1886
else if (headerEnd >= lineLength
1887
|| !isLegalNameChar(startCh)
1888
|| !isLegalNameChar(endCh))
1903
* find the index number of a string element in a container of strings
1905
* @return the index number of element in the ocntainer. -1 if element not found.
1906
* @param container a vector of strings.
1907
* @param element the element to find .
1909
int ASBeautifier::indexOf(vector<const string*> &container, const string *element)
1911
vector<const string*>::const_iterator where;
1913
where = find(container.begin(), container.end(), element);
1914
if (where == container.end())
1917
return (int) (where - container.begin());
1921
* trim removes the white space surrounding a line.
1923
* @return the trimmed line.
1924
* @param str the line to trim.
1926
string ASBeautifier::trim(const string &str)
1930
int end = str.length() - 1;
1932
while (start < end && isWhiteSpace(str[start]))
1935
while (start <= end && isWhiteSpace(str[end]))
1938
string returnStr(str, start, end + 1 - start);
1943
* peek at the next unread character.
1945
* @return the next unread character.
1946
* @param line the line to check.
1947
* @param i the current char position on the line.
1949
char ASBeautifier::peekNextChar(string &line, int i)
1952
size_t peekNum = line.find_first_not_of(" \t", i + 1);
1954
if (peekNum == string::npos)
1963
} // end namespace astyle