📄 asbeautifier.cpp
字号:
continue;
// handle comments
if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0)
{
isInLineComment = true;
outBuffer.append(1, '/');
i++;
continue;
}
else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0)
{
isInComment = true;
outBuffer.append(1, '*');
i++;
size_t j = line.find_first_not_of(" \t");
if (!line.compare(j, 2, "/*") == 0) // does line start with comment?
blockCommentNoIndent = true; // if no, cannot indent continuation lines
continue;
}
else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0)
{
isInComment = false;
outBuffer.append(1, '/');
i++;
blockCommentNoIndent = false; // ok to indent next comment
continue;
}
if (isInComment || isInLineComment)
continue;
// if we have reached this far then we are NOT in a comment or string of special character...
if (probationHeader != NULL)
{
if (((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{')
|| (probationHeader == &AS_SYNCHRONIZED && ch == '('))
{
// insert the probation header as a new header
isInHeader = true;
headerStack->push_back(probationHeader);
// handle the specific probation header
isInConditional = (probationHeader == &AS_SYNCHRONIZED);
if (probationHeader == &AS_CONST)
isImmediatelyAfterConst = true;
isInStatement = false;
// if the probation comes from the previous line, then indent by 1 tab count.
if (previousLineProbation && ch == '{')
{
tabCount++;
previousLineProbationTab = true;
}
previousLineProbation = false;
}
// dismiss the probation header
probationHeader = NULL;
}
prevNonSpaceCh = currentNonSpaceCh;
currentNonSpaceCh = ch;
if (!isLegalNameChar(ch) && ch != ',' && ch != ';')
{
prevNonLegalCh = currentNonLegalCh;
currentNonLegalCh = ch;
}
if (isInHeader)
{
isInHeader = false;
currentHeader = headerStack->back();
}
else
currentHeader = NULL;
if (isCStyle && isInTemplate
&& (ch == '<' || ch == '>')
&& findHeader(line, i, nonAssignmentOperators) == NULL)
{
if (ch == '<')
{
++templateDepth;
}
else if (ch == '>')
{
if (--templateDepth <= 0)
{
if (isInTemplate)
ch = ';';
else
ch = 't';
isInTemplate = false;
templateDepth = 0;
}
}
}
// handle parenthesies
if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
{
if (ch == '(' || ch == '[')
{
if (parenDepth == 0)
{
parenStatementStack->push_back(isInStatement);
isInStatement = true;
}
parenDepth++;
inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
if (currentHeader != NULL)
registerInStatementIndent(line, i, spaceTabCount, minConditionalIndent/*indentLength*2*/, true);
else
registerInStatementIndent(line, i, spaceTabCount, 0, true);
}
else if (ch == ')' || ch == ']')
{
parenDepth--;
if (parenDepth == 0)
{
isInStatement = parenStatementStack->back();
parenStatementStack->pop_back();
ch = ' ';
isInConditional = false;
}
if (!inStatementIndentStackSizeStack->empty())
{
int previousIndentStackSize = inStatementIndentStackSizeStack->back();
inStatementIndentStackSizeStack->pop_back();
while (previousIndentStackSize < (int) inStatementIndentStack->size())
inStatementIndentStack->pop_back();
if (!parenIndentStack->empty())
{
int poppedIndent = parenIndentStack->back();
parenIndentStack->pop_back();
if (i == 0)
spaceTabCount = poppedIndent;
}
}
}
continue;
}
if (ch == '{')
{
bool isBlockOpener;
// first, check if '{' is a block-opener or an static-array opener
isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back())
|| prevNonSpaceCh == '}'
|| prevNonSpaceCh == ')'
|| prevNonSpaceCh == ';'
|| peekNextChar(line, i) == '{'
|| isNonInStatementArray
|| isInClassHeader
// || isBlockOpener
|| isImmediatelyAfterConst
|| (isInDefine &&
(prevNonSpaceCh == '('
|| prevNonSpaceCh == '_'
|| isalnum(prevNonSpaceCh))));
isInClassHeader = false;
if (!isBlockOpener && currentHeader != NULL)
{
for (size_t n = 0; n < nonParenHeaders.size(); n++)
if (currentHeader == nonParenHeaders[n])
{
isBlockOpener = true;
break;
}
}
bracketBlockStateStack->push_back(isBlockOpener);
if (!isBlockOpener)
{
inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
registerInStatementIndent(line, i, spaceTabCount, 0, true);
parenDepth++;
if (i == 0)
shouldIndentBrackettedLine = false;
continue;
}
// this bracket is a block opener...
++lineOpeningBlocksNum;
// if (isInClassHeader)
// isInClassHeader = false;
if (isInClassHeaderTab)
{
isInClassHeaderTab = false;
// decrease tab count if bracket is broken
size_t firstChar = line.find_first_not_of(" \t");
if (firstChar != string::npos)
if (line[firstChar] == '{' && (int) firstChar == i)
tabCount -= 2;
}
// do not allow inStatementIndent - should occur for Java files only
if (inStatementIndentStack->size() > 0)
{
spaceTabCount = 0;
inStatementIndentStack->back() = 0;
}
blockParenDepthStack->push_back(parenDepth);
blockStatementStack->push_back(isInStatement);
inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
if (inStatementIndentStack->size() > 0)
inStatementIndentStack->back() = 0;
blockTabCount += isInStatement ? 1 : 0;
parenDepth = 0;
isInStatement = false;
tempStacks->push_back(new vector<const string*>);
headerStack->push_back(&AS_OPEN_BRACKET);
lastLineHeader = &AS_OPEN_BRACKET;
continue;
}
//check if a header has been reached
if (isWhiteSpace(prevCh))
{
bool isIndentableHeader = true;
const string *newHeader = findHeader(line, i, headers);
if (newHeader != NULL)
{
// if we reached here, then this is a header...
isInHeader = true;
vector<const string*> *lastTempStack;
if (tempStacks->empty())
lastTempStack = NULL;
else
lastTempStack = tempStacks->back();
// if a new block is opened, push a new stack into tempStacks to hold the
// future list of headers in the new block.
// take care of the special case: 'else if (...)'
if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
{
headerStack->pop_back();
}
// take care of 'else'
else if (newHeader == &AS_ELSE)
{
if (lastTempStack != NULL)
{
int indexOfIf = indexOf(*lastTempStack, &AS_IF);
if (indexOfIf != -1)
{
// recreate the header list in headerStack up to the previous 'if'
// from the temporary snapshot stored in lastTempStack.
int restackSize = lastTempStack->size() - indexOfIf - 1;
for (int r = 0; r < restackSize; r++)
{
headerStack->push_back(lastTempStack->back());
lastTempStack->pop_back();
}
if (!closingBracketReached)
tabCount += restackSize;
}
/*
* If the above if is not true, i.e. no 'if' before the 'else',
* then nothing beautiful will come out of this...
* I should think about inserting an Exception here to notify the caller of this...
*/
}
}
// check if 'while' closes a previous 'do'
else if (newHeader == &AS_WHILE)
{
if (lastTempStack != NULL)
{
int indexOfDo = indexOf(*lastTempStack, &AS_DO);
if (indexOfDo != -1)
{
// recreate the header list in headerStack up to the previous 'do'
// from the temporary snapshot stored in lastTempStack.
int restackSize = lastTempStack->size() - indexOfDo - 1;
for (int r = 0; r < restackSize; r++)
{
headerStack->push_back(lastTempStack->back());
lastTempStack->pop_back();
}
if (!closingBracketReached)
tabCount += restackSize;
}
}
}
// check if 'catch' closes a previous 'try' or 'catch'
else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
{
if (lastTempStack != NULL)
{
int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
if (indexOfTry == -1)
indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
if (indexOfTry != -1)
{
// recreate the header list in headerStack up to the previous 'try'
// from the temporary snapshot stored in lastTempStack.
int restackSize = lastTempStack->size() - indexOfTry - 1;
for (int r = 0; r < restackSize; r++)
{
headerStack->push_back(lastTempStack->back());
lastTempStack->pop_back();
}
if (!closingBracketReached)
tabCount += restackSize;
}
}
}
else if (newHeader == &AS_CASE)
{
isInCase = true;
--tabCount;
}
else if (newHeader == &AS_DEFAULT)
{
isInCase = true;
--tabCount;
}
else if (newHeader == &AS_STATIC
|| newHeader == &AS_SYNCHRONIZED
|| (newHeader == &AS_CONST && isCStyle))
{
if (!headerStack->empty() &&
(headerStack->back() == &AS_STATIC
|| headerStack->back() == &AS_SYNCHRONIZED
|| headerStack->back() == &AS_CONST))
{
isIndentableHeader = false;
}
else
{
isIndentableHeader = false;
probationHeader = newHeader;
}
}
else if (newHeader == &AS_CONST)
{
isIndentableHeader = false;
}
else if (newHeader == &AS_TEMPLATE)
{
if (isCStyle)
isInTemplate = true;
isIndentableHeader = false;
}
if (isIndentableHeader)
{
headerStack->push_back(newHeader);
isInStatement = false;
if (indexOf(nonParenHeaders, newHeader) == -1)
{
isInConditional = true;
}
lastLineHeader = newHeader;
}
else
isInHeader = false;
outBuffer.append(newHeader->substr(1));
i += newHeader->length() - 1;
continue;
}
}
if (isCStyle && !isalpha(prevCh)
&& line.compare(i, 8, "operator") == 0 && !isalnum(line[i+8]))
{
isInOperator = true;
outBuffer.append(AS_OPERATOR.substr(1));
i += 7;
continue;
}
// "new" operator is a pointer, not a calculation
if (!isalpha(prevCh)
&& line.compare(i, 3, "new") == 0 && !isalnum(line[i+3]))
{
if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty())
inStatementIndentStack->back() = 0;
}
if (ch == '?')
isInQuestion = true;
// special handling of 'case' statements
if (ch == ':')
{
if ((int) line.length() > i + 1 && line[i+1] == ':') // look for ::
{
++i;
outBuffer.append(1, ':');
ch = ' ';
continue;
}
else if (isInQuestion)
{
isInQuestion = false;
}
else if (isCStyle && isInClass && prevNonSpaceCh != ')')
{
--tabCount;
// found a 'private:' or 'public:' inside a class definition
// so do nothing special
}
else if (!isJavaStyle && isInClassHeader)
{
// found a 'class A : public B' definition
// so do nothing special
}
else if (isJavaStyle && lastLineHeader == &AS_FOR)
{
// found a java for-each statement
// so do nothing special
}
else if (isCStyle && prevNonSpaceCh == ')')
{
isInClassHeader = true;
if (i == 0)
tabCount += 2;
}
else
{
currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers
if (isInCase)
{
isInCase = false;
ch = ';'; // from here on, treat char as ';'
}
else // is in a label (e.g. 'label1:')
{
if (labelIndent)
--tabCount; // unindent label by one indent
else
tabCount = 0; // completely flush indent to left
}
}
}
if ((ch == ';' || (parenDepth > 0 && ch == ',')) && !inStatementIndentStackSizeStack->empty())
while ((int) inStatementIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0)
< (int) inStatementIndentStack->size())
inStatementIndentStack->pop_back();
// handle ends of statements
if ((ch == ';' && parenDepth == 0) || ch == '}'/* || (ch == ',' && parenDepth == 0)*/)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -