📄 asbeautifier.cpp
字号:
defineTabCount = 0;
}
/**
* set indentation style to ANSI C/C++.
*/
void ASBeautifier::setCStyle()
{
isCStyle = true;
}
/**
* set indentation style to Java / K&R.
*/
void ASBeautifier::setJavaStyle()
{
isCStyle = false;
}
/**
* indent using one tab per indentation
*/
void ASBeautifier::setTabIndentation(int length, bool forceTabs)
{
indentString = "\t";
indentLength = length;
shouldForceTabIndentation = forceTabs;
if (!isMinimalConditinalIndentSet)
minConditionalIndent = indentLength * 2;
}
/**
* indent using a number of spaces per indentation.
*
* @param length number of spaces per indent.
*/
void ASBeautifier::setSpaceIndentation(int length)
{
indentString=string(length, ' ');
indentLength = length;
if (!isMinimalConditinalIndentSet)
minConditionalIndent = indentLength * 2;
}
/**
* set the maximum indentation between two lines in a multi-line statement.
*
* @param max maximum indentation length.
*/
void ASBeautifier::setMaxInStatementIndentLength(int max)
{
maxInStatementIndent = max;
}
/**
* set the minimum indentation between two lines in a multi-line condition.
*
* @param min minimal indentation length.
*/
void ASBeautifier::setMinConditionalIndentLength(int min)
{
minConditionalIndent = min;
isMinimalConditinalIndentSet = true;
}
/**
* set the state of the bracket indentation option. If true, brackets will
* be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setBracketIndent(bool state)
{
bracketIndent = state;
}
/**
* set the state of the block indentation option. If true, entire blocks
* will be indented one additional indent, similar to the GNU indent style.
*
* @param state state of option.
*/
void ASBeautifier::setBlockIndent(bool state)
{
if (state)
setBracketIndent(false); // so that we don't have both bracket and block indent
blockIndent = state;
}
/**
* set the state of the class indentation option. If true, C++ class
* definitions will be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setClassIndent(bool state)
{
classIndent = state;
}
/**
* set the state of the switch indentation option. If true, blocks of 'switch'
* statements will be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setSwitchIndent(bool state)
{
switchIndent = state;
}
/**
* set the state of the case indentation option. If true, lines of 'case'
* statements will be indented one additional indent.
*
* @param state state of option.
*/
void ASBeautifier::setCaseIndent(bool state)
{
caseIndent = state;
}
/**
* set the state of the namespace indentation option.
* If true, blocks of 'namespace' statements will be indented one
* additional indent. Otherwise, NO indentation will be added.
*
* @param state state of option.
*/
void ASBeautifier::setNamespaceIndent(bool state)
{
namespaceIndent = state;
}
/**
* set the state of the label indentation option.
* If true, labels will be indented one indent LESS than the
* current indentation level.
* If false, labels will be flushed to the left with NO
* indent at all.
*
* @param state state of option.
*/
void ASBeautifier::setLabelIndent(bool state)
{
labelIndent = state;
}
/**
* set the state of the preprocessor indentation option.
* If true, multiline #define statements will be indented.
*
* @param state state of option.
*/
void ASBeautifier::setPreprocessorIndent(bool state)
{
preprocessorIndent = state;
}
/**
* set the state of the empty line fill option.
* If true, empty lines will be filled with the whitespace.
* of their previous lines.
* If false, these lines will remain empty.
*
* @param state state of option.
*/
void ASBeautifier::setEmptyLineFill(bool state)
{
emptyLineFill = state;
}
/**
* check if there are any indented lines ready to be read by nextLine()
*
* @return are there any indented lines ready?
*/
bool ASBeautifier::hasMoreLines() const
{
return sourceIterator->hasMoreLines();
}
/**
* get the next indented line.
*
* @return indented line.
*/
string ASBeautifier::nextLine()
{
return beautify(sourceIterator->nextLine());
}
/**
* beautify a line of source code.
* every line of source code in a source code file should be sent
* one after the other to the beautify method.
*
* @return the indented line.
* @param originalLine the original unindented line.
*/
string ASBeautifier::beautify(const string &originalLine)
{
string line;
bool isInLineComment = false;
bool lineStartsInComment = false;
bool isInClass = false;
bool isInSwitch = false;
bool isImmediatelyAfterConst = false;
bool isSpecialChar = false;
char ch = ' ';
char prevCh;
string outBuffer; // the newly idented line is bufferd here
int tabCount = 0;
const string *lastLineHeader = NULL;
bool closingBracketReached = false;
int spaceTabCount = 0;
char tempCh;
int headerStackSize = headerStack->size();
//bool isLineInStatement = isInStatement;
bool shouldIndentBrackettedLine = true;
int lineOpeningBlocksNum = 0;
int lineClosingBlocksNum = 0;
bool previousLineProbation = (probationHeader != NULL);
int i;
currentHeader = NULL;
lineStartsInComment = isInComment;
// handle and remove white spaces around the line:
// If not in comment, first find out size of white space before line,
// so that possible comments starting in the line continue in
// relation to the preliminary white-space.
if (!isInComment)
{
leadingWhiteSpaces = 0;
while (leadingWhiteSpaces<originalLine.length() && originalLine[leadingWhiteSpaces] <= 0x20)
leadingWhiteSpaces++;
line = trim(originalLine);
}
else
{
int trimSize;
for (trimSize=0;
trimSize < originalLine.length() && trimSize<leadingWhiteSpaces && originalLine[trimSize] <= 0x20 ;
trimSize++)
;
line = originalLine.substr(trimSize);
}
if (line.length() == 0)
{
if (emptyLineFill)
return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
else
return line;
}
// handle preprocessor commands
if (isCStyle && !isInComment && (line[0] == '#' || backslashEndsPrevLine))
{
if (line[0] == '#')
{
string preproc = trim(string(line.c_str() + 1));
// When finding a multi-lined #define statement, the original beautifier
// 1. sets its isInDefineDefinition flag
// 2. clones a new beautifier that will be used for the actual indentation
// of the #define. This clone is put into the activeBeautifierStack in order
// to be called for the actual indentation.
// The original beautifier will have isInDefineDefinition = true, isInDefine = false
// The cloned beautifier will have isInDefineDefinition = true, isInDefine = true
if (preprocessorIndent && preproc.COMPARE(0, 6, string("define")) == 0 && line[line.length() - 1] == '\\')
{
if (!isInDefineDefinition)
{
ASBeautifier *defineBeautifier;
// this is the original beautifier
isInDefineDefinition = true;
// push a new beautifier into the active stack
// this breautifier will be used for the indentation of this define
defineBeautifier = new ASBeautifier(*this);
//defineBeautifier->init();
//defineBeautifier->isInDefineDefinition = true;
//defineBeautifier->beautify("");
activeBeautifierStack->push_back(defineBeautifier);
}
else
{
// the is the cloned beautifier that is in charge of indenting the #define.
isInDefine = true;
}
}
else if (preproc.COMPARE(0, 2, string("if")) == 0)
{
// push a new beautifier into the stack
waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
waitingBeautifierStack->push_back(new ASBeautifier(*this));
}
else if (preproc.COMPARE(0, 4/*2*/, string("else")) == 0)
{
if (!waitingBeautifierStack->empty())
{
// MOVE current waiting beautifier to active stack.
activeBeautifierStack->push_back(waitingBeautifierStack->back());
waitingBeautifierStack->pop_back();
}
}
else if (preproc.COMPARE(0, 4, string("elif")) == 0)
{
if (!waitingBeautifierStack->empty())
{
// append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
activeBeautifierStack->push_back( new ASBeautifier( *(waitingBeautifierStack->back()) ) );
}
}
else if (preproc.COMPARE(0, 5, string("endif")) == 0)
{
int stackLength;
ASBeautifier *beautifier;
if (!waitingBeautifierStackLengthStack->empty())
{
stackLength = waitingBeautifierStackLengthStack->back();
waitingBeautifierStackLengthStack->pop_back();
while (waitingBeautifierStack->size() > stackLength)
{
beautifier = waitingBeautifierStack->back();
waitingBeautifierStack->pop_back();
delete beautifier;
}
}
if (!activeBeautifierStackLengthStack->empty())
{
stackLength = activeBeautifierStackLengthStack->back();
activeBeautifierStackLengthStack->pop_back();
while (activeBeautifierStack->size() > stackLength)
{
beautifier = activeBeautifierStack->back();
activeBeautifierStack->pop_back();
delete beautifier;
}
}
}
}
// check if the last char is a backslash
if(line.length() > 0)
backslashEndsPrevLine = (line[line.length() - 1] == '\\');
else
backslashEndsPrevLine = false;
// check if this line ends a multi-line #define
// if so, use the #define's cloned beautifier for the line's indentation
// and then remove it from the active beautifier stack and delete it.
if (!backslashEndsPrevLine && isInDefineDefinition && !isInDefine)
{
string beautifiedLine;
ASBeautifier *defineBeautifier;
isInDefineDefinition = false;
defineBeautifier = activeBeautifierStack->back();
activeBeautifierStack->pop_back();
beautifiedLine = defineBeautifier->beautify(line);
delete defineBeautifier;
return beautifiedLine;
}
// unless this is a multi-line #define, return this precompiler line as is.
if (!isInDefine && !isInDefineDefinition)
return originalLine;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -