📄 asbeautifier.cpp
字号:
}
if (isInOperator)
isInOperator = false;
}
// handle special cases of unindentation:
/*
* if '{' doesn't follow an immediately previous '{' in the headerStack
* (but rather another header such as "for" or "if", then unindent it
* by one indentation relative to its block.
*/
// cerr << endl << lineOpeningBlocksNum << " " << lineClosingBlocksNum << " " << previousLastLineHeader << endl;
// indent #define lines with one less tab
//if (isInDefine)
// tabCount -= defineTabCount-1;
if (!lineStartsInComment
&& !blockIndent
&& outBuffer.size()>0
&& outBuffer[0]=='{'
&& !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)
&& !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET)
&& shouldIndentBrackettedLine)
--tabCount;
else if (!lineStartsInComment
&& outBuffer.size()>0
&& outBuffer[0]=='}'
&& shouldIndentBrackettedLine )
--tabCount;
// correctly indent one-line-blocks...
else if (!lineStartsInComment
&& outBuffer.size()>0
&& lineOpeningBlocksNum > 0
&& lineOpeningBlocksNum == lineClosingBlocksNum
&& previousLastLineHeader != NULL
&& previousLastLineHeader != &AS_OPEN_BRACKET)
tabCount -= 1; //lineOpeningBlocksNum - (blockIndent ? 1 : 0);
if (tabCount < 0)
tabCount = 0;
// take care of extra bracket indentatation option...
if (bracketIndent && outBuffer.size()>0 && shouldIndentBrackettedLine)
if (outBuffer[0]=='{' || outBuffer[0]=='}')
tabCount++;
if (isInDefine)
{
if (outBuffer[0] == '#')
{
string preproc = trim(string(outBuffer.c_str() + 1));
if (BEGINS_WITH(preproc, "define", 6))
{
if (!inStatementIndentStack->empty()
&& inStatementIndentStack->back() > 0)
{
defineTabCount = tabCount;
}
else
{
defineTabCount = tabCount - 1;
tabCount--;
}
}
}
tabCount -= defineTabCount;
}
if (tabCount < 0)
tabCount = 0;
// For multi-line string constants, suppress indent of next line (bug #417767).
if ( isInQuote && line[ line.size() - 1 ] == '\\' )
{
TRACE( INFO, "Line ends with continued quote - suppressing indent of next line." );
suppressIndent = true;
}
else
{
suppressIndent = false;
}
// finally, insert indentations into begining of line
prevFinalLineSpaceTabCount = spaceTabCount;
prevFinalLineTabCount = tabCount;
if (forceTabIndent)
{
tabCount += spaceTabCount / indentLength;
spaceTabCount = spaceTabCount % indentLength;
}
// attempted bugfix #417767
if ( ! suppressCurrentIndent )
{
outBuffer = preLineWS(spaceTabCount,tabCount) + outBuffer;
}
if (lastLineHeader != NULL)
{
previousLastLineHeader = lastLineHeader;
}
return outBuffer;
}
string ASBeautifier::preLineWS(int spaceTabCount, int tabCount)
{
string ws;
for (int i=0; i<tabCount; i++)
ws += indentString;
while ((spaceTabCount--) > 0)
ws += string(" ");
return ws;
}
/*
* register an in-statement indent.
*/
void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount,
int minIndent, bool updateParenStack)
{
int inStatementIndent;
int remainingCharNum = line.size() - i;
int nextNonWSChar = 1;
nextNonWSChar = getNextProgramCharDistance(line, i);
// if indent is around the last char in the line, indent instead 2 spaces from the previous indent
if (nextNonWSChar == remainingCharNum)
{
int previousIndent = spaceTabCount;
if (!inStatementIndentStack->empty())
previousIndent = inStatementIndentStack->back();
inStatementIndentStack->push_back(/*2*/ indentLength + previousIndent );
if (updateParenStack)
parenIndentStack->push_back( previousIndent );
return;
}
if (updateParenStack)
parenIndentStack->push_back(i+spaceTabCount);
inStatementIndent = i + nextNonWSChar + spaceTabCount;
if (i + nextNonWSChar < minIndent)
inStatementIndent = minIndent + spaceTabCount;
if (i + nextNonWSChar > maxInStatementIndent)
inStatementIndent = indentLength*2 + spaceTabCount;
if (!inStatementIndentStack->empty() &&
inStatementIndent < inStatementIndentStack->back())
inStatementIndent = inStatementIndentStack->back();
inStatementIndentStack->push_back(inStatementIndent);
}
/**
* get distance to the next non-white sspace, non-comment character in the line.
* if no such character exists, return the length remaining to the end of the line.
*/
int ASBeautifier::getNextProgramCharDistance(const string &line, int i)
{
bool inComment = false;
int remainingCharNum = line.size() - i;
int charDistance = 1;
int ch;
for (charDistance = 1; charDistance < remainingCharNum; charDistance++)
{
ch = line[i + charDistance];
if (inComment)
{
if (CONTAINS_AT(line, AS_CLOSE_COMMENT, 2, i + charDistance))
{
charDistance++;
inComment = false;
}
continue;
}
else if (isWhiteSpace(ch))
continue;
else if (ch == '/')
{
if (CONTAINS_AT(line, AS_OPEN_LINE_COMMENT, 2, i + charDistance))
return remainingCharNum;
else if (CONTAINS_AT(line, AS_OPEN_COMMENT, 2, i + charDistance))
{
charDistance++;
inComment = true;
}
}
else
return charDistance;
}
return charDistance;
}
/**
* check if a specific character can be used in a legal variable/method/class name
*
* @return legality of the char.
* @param ch the character to be checked.
*/
bool ASBeautifier::isLegalNameChar(char ch) const
{
return (isalnum(ch) //(ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9') ||
|| ch=='.' || ch=='_' || (!( sourceStyle != STYLE_JAVA ) && ch=='$') || (( sourceStyle != STYLE_JAVA ) && ch=='~'));
}
/**
* check if a specific line position contains a header, out of several possible headers.
*
* @return a pointer to the found header. if no header was found then return NULL.
*/
const string *ASBeautifier::findHeader(const string &line, int i, const vector<const string*> &possibleHeaders, bool checkBoundry)
{
int maxHeaders = possibleHeaders.size();
const string *header = NULL;
int p;
for (p=0; p < maxHeaders; p++)
{
header = possibleHeaders[p];
if (CONTAINS_AT(line, *header, header->size(), i))
{
// check that this is a header and not a part of a longer word
// (e.g. not at its begining, not at its middle...)
int lineLength = line.size();
int headerEnd = i + header->length();
char startCh = (*header)[0]; // first char of header
char endCh = 0; // char just after header
char prevCh = 0; // char just before header
if (headerEnd < lineLength)
{
endCh = line[headerEnd];
}
if (i > 0)
{
prevCh = line[i-1];
}
if (!checkBoundry)
{
return header;
}
else if (prevCh != 0
&& isLegalNameChar(startCh)
&& isLegalNameChar(prevCh))
{
return NULL;
}
else if (headerEnd >= lineLength
|| !isLegalNameChar(startCh)
|| !isLegalNameChar(endCh))
{
return header;
}
else
{
return NULL;
}
}
}
return NULL;
}
/**
* check if a specific character can be used in a legal variable/method/class name
*
* @return legality of the char.
* @param ch the character to be checked.
*/
bool ASBeautifier::isWhiteSpace(char ch) const
{
return (ch == ' ' || ch == '\t');
}
/**
* find the index number of a string element in a container of strings
*
* @return the index number of element in the ocntainer. -1 if element not found.
* @param container a vector of strings.
* @param element the element to find .
*/
int ASBeautifier::indexOf(vector<const string*> &container, const string *element)
{
vector<const string*>::const_iterator where;
where= find(container.begin(), container.end(), element);
if (where == container.end())
return -1;
else
return where - container.begin();
}
/**
* trim removes the white space surrounding a line.
*
* @return the trimmed line.
* @param str the line to trim.
*/
string ASBeautifier::trim(const string &str)
{
int start = 0;
int end = str.size() - 1;
while (start < end && isWhiteSpace(str[start]))
start++;
while (start <= end && isWhiteSpace(str[end]))
end--;
string returnStr(str, start, end+1-start);
return returnStr;
}
} // namespace astyle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -