📄 asbeautifier.cpp
字号:
if ( ! isInComment && ! suppressCurrentIndent )
{
TRACE( ENTRY, "not in comment, indent not suppressed - memorizing leading WS and trimming line" );
leadingWhiteSpaces = 0;
while ( leadingWhiteSpaces < originalLine.size() && isspace(originalLine[leadingWhiteSpaces]) )
{
leadingWhiteSpaces++;
}
line = trim(originalLine);
TRACE( EXIT, "line: '" << line << "'" );
}
else
{
TRACE( ENTRY, "in comment - trimming away already registered leading WS (?)" );
unsigned trimSize;
for (trimSize=0;
trimSize < originalLine.size() && trimSize < leadingWhiteSpaces && isspace(originalLine[trimSize]);
trimSize++)
{
// EMPTY
}
line = originalLine.substr(trimSize);
TRACE( EXIT, "line: '" << line << "'" );
}
// handle empty lines
if (line.size() == 0)
{
TRACE( ENTRY, "line is empty" );
if (emptyLineIndent)
{
TRACE( INFO, "as emptyLineIndent is set, WS is added (preLineWS(" << prevFinalLineSpaceTabCount << ", " << prevFinalLineTabCount << "))" );
TRACE( EXIT, "'" << preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount) << "'" );
return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
}
else
{
TRACE( EXIT, "returning empty line" );
return line;
}
}
// handle preprocessor commands
if ( ( sourceStyle != STYLE_JAVA ) && ! isInComment && ( line[0] == '#' || backslashEndsPrevLine ) )
{
if (line[0] == '#')
{
TRACE( INFO, "encountered preprocessor statement" );
// TODO: Haven't looked into the following block yet.
string preproc = trim( line.substr(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 && BEGINS_WITH(preproc, "define", 6) && line[line.size() - 1] == '\\' )
{
TRACE( INFO, "...which is a multi-line #define" );
if ( !isInDefineDefinition )
{
TRACE( INFO, "isInDefineDefinition == false" );
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
{
TRACE( INFO, "isInDefineDefinition == true" );
// the is the cloned beautifier that is in charge of indenting the #define.
isInDefine = true;
}
}
else if (BEGINS_WITH(preproc, "if", 2))
{
TRACE( INFO, "processing #if / #ifdef / #ifndef" );
// 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 (BEGINS_WITH(preproc, "else", 4))
{
TRACE( INFO, "processing #else" );
if (!waitingBeautifierStack->empty())
{
// MOVE current waiting beautifier to active stack.
activeBeautifierStack->push_back(waitingBeautifierStack->back());
waitingBeautifierStack->pop_back();
}
}
else if (BEGINS_WITH(preproc, "elif", 4))
{
TRACE( INFO, "processing #elif" );
if (!waitingBeautifierStack->empty())
{
// append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
activeBeautifierStack->push_back( new ASBeautifier( *(waitingBeautifierStack->back()) ) );
}
} // BEGINS_WITH(preproc, "elif", 4))
else if (BEGINS_WITH(preproc, "endif", 5))
{
TRACE( INFO, "processing #endif" );
unsigned stackLength;
ASBeautifier *beautifier;
if ( ! waitingBeautifierStackLengthStack->empty() )
{
TRACE( INFO, "clearing waitingBeautifierStack" );
stackLength = waitingBeautifierStackLengthStack->back();
waitingBeautifierStackLengthStack->pop_back();
// FIXME: what about the LengthStack?
while ( waitingBeautifierStack->size() > stackLength )
{
beautifier = waitingBeautifierStack->back();
waitingBeautifierStack->pop_back();
delete beautifier;
}
}
if ( ! activeBeautifierStackLengthStack->empty() )
{
TRACE( INFO, "clearing activeBeautifierStack" );
stackLength = activeBeautifierStackLengthStack->back();
activeBeautifierStackLengthStack->pop_back();
// FIXME: what about the LengthStack?
while ( activeBeautifierStack->size() > stackLength )
{
beautifier = activeBeautifierStack->back();
activeBeautifierStack->pop_back();
delete beautifier;
}
}
} // BEGINS_WITH(preproc, "endif", 5))
} // line[0] == '#'
// check if the last char of current line is a backslash
if ( line[ line.size() - 1 ] == '\\' )
{
TRACE( INFO, "current line ends in '\\'" );
backslashEndsPrevLine = true;
}
else
{
TRACE( INFO, "current line does not end in '\\'" );
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 )
{
TRACE( INFO, "last line of multi-line define" );
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 )
{
TRACE( INFO, "not a multi-line define - return as-is" );
return originalLine;
}
} // end of preprocessor handling
// if there exists any worker beautifier in the activeBeautifierStack,
// then use it instead of this to indent the current line.
// TODO: Check whether one of the two checks on activeBeautifierStack is redundant.
if ( ! isInDefine && activeBeautifierStack != NULL && ! activeBeautifierStack->empty() )
{
TRACE( INFO, "delegating to on-stack beautifier (IS THIS EVER REACHED?)" );
return activeBeautifierStack->back()->beautify( line );
}
// calculate preliminary indentation based on data from past lines
if ( ! inStatementIndentStack->empty() )
{
TRACE( INFO, "getting preliminary indentation from inStatementIndentStack:" << inStatementIndentStack->back() );
spaceTabCount = inStatementIndentStack->back();
}
for ( i = 0; i < headerStackSize; ++i )
{
isInClass = false;
if ( blockIndent || ( ! ( i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET
&& (*headerStack)[i] == &AS_OPEN_BRACKET ) ) )
{
TRACE( INFO, "reached block, adding indent" );
++tabCount;
}
if ( ( sourceStyle != STYLE_JAVA ) && ! namespaceIndent && i > 0
&& (*headerStack)[i-1] == &AS_NAMESPACE
&& (*headerStack)[i] == &AS_OPEN_BRACKET )
{
TRACE( INFO, "reached namespace but namespaceIndent == false, removing indent" );
--tabCount;
}
if ( ( sourceStyle != STYLE_JAVA ) && i > 0
&& (*headerStack)[i-1] == &AS_CLASS
&& (*headerStack)[i] == &AS_OPEN_BRACKET )
{
TRACE( INFO, "reached class..." );
if ( classIndent )
{
TRACE( INFO, "...adding (class) indent" );
++tabCount;
}
isInClass = true;
}
// is the switchIndent option is on, indent switch statements an additional indent.
// TODO: ELSE if? Shouldn't this be just another IF? And i checked > 0 as above?
else if ( switchIndent && i > 1
&& (*headerStack)[i-1] == &AS_SWITCH
&& (*headerStack)[i] == &AS_OPEN_BRACKET )
{
TRACE( INFO, "reached switch block, assing indent" );
++tabCount;
isInSwitch = true;
}
} // for ( i = 0; i < headerStackSize; ++i )
if ( ! lineStartsInComment && ( sourceStyle != STYLE_JAVA )
&& isInClass
&& classIndent
&& headerStackSize >= 2
&& (*headerStack)[headerStackSize-2] == &AS_CLASS
&& (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
&& line[0] == '}' )
{
TRACE( INFO, "reached end of class (?), removing indent" );
--tabCount;
}
else if ( ! lineStartsInComment && isInSwitch
&& switchIndent
&& headerStackSize >= 2
&& (*headerStack)[headerStackSize-2] == &AS_SWITCH
&& (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
&& line[0] == '}' )
{
TRACE( INFO, "reached end of switch block, removing indent" );
--tabCount;
}
if (isInClassHeader)
{
TRACE( INFO, "isInClassHeader - adding two indents" );
isInClassHeaderTab = true;
tabCount += 2;
}
if (isInConditional)
{
TRACE( INFO, "isInConditional - removing indent" );
--tabCount;
} // end of indent adjust
// parse characters in the current line.
for ( i = 0; i < line.size(); ++i )
{
tempCh = line[i];
prevCh = ch;
ch = tempCh;
outBuffer.append(1, ch);
TRACE( INFO, "next char: '" << ch << "'." );
if (isWhiteSpace(ch))
{
TRACE( INFO, "skipping whitespace" );
continue;
}
// handle special characters (i.e. backslash + character such as \n, \t, ...)
if (isSpecialChar)
{
TRACE( INFO, "skipping special (escaped) char" );
isSpecialChar = false;
continue;
}
if ( ! ( isInComment || isInLineComment ) && ( line.substr(i, 2) == "\\\\" ) )
{
TRACE( INFO, "encountered '\\', appending to outBuffer" );
outBuffer.append(1, '\\');
++i;
continue;
}
if ( ! ( isInComment || isInLineComment ) && ch=='\\' )
{
TRACE( INFO, "encountered '\', next char is special (escaped)" );
isSpecialChar = true;
continue;
}
// handle quotes (such as 'x' and "Hello Dolly")
if ( ! ( isInComment || isInLineComment ) && ( ch=='"' || ch=='\'' ) )
{
TRACE( INFO, "encountered quote (' or \")" );
if ( ! isInQuote )
{
TRACE( INFO, "this is the BEGINNING of a quote" );
quoteChar = ch;
isInQuote = true;
}
else if (quoteChar == ch)
{
TRACE( INFO, "this is the END of a quote" );
isInQuote = false;
isInStatement = true;
continue;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -