📄 asformatter.cpp
字号:
}
/**
* append a string sequence to the current formatted line.
* Unless disabled (via canBreakLine == false), first check if a
* line-break has been registered, and if so break the
* formatted line, and only then append the sequence into
* the next formatted line.
*
* @param sequence the sequence to append.
* @param canBreakLine if true, a registered line-break
*/
void ASFormatter::appendSequence(const string &sequence, bool canBreakLine)
{
if (canBreakLine && isInLineBreak)
breakLine();
formattedLine.append(sequence);
}
/**
* append a space to the current formattedline, UNLESS the
* last character is already a white-space character.
*/
void ASFormatter::appendSpacePad()
{
int len = formattedLine.length();
if (len > 0 && !isWhiteSpace(formattedLine[len-1]))
{
formattedLine.append(1, ' ');
spacePadNum++;
}
}
/**
* append a space to the current formattedline, UNLESS the
* next character is already a white-space character.
*/
void ASFormatter::appendSpaceAfter()
{
int len = currentLine.length();
if (charNum + 1 < len && !isWhiteSpace(currentLine[charNum+1]))
{
formattedLine.append(1, ' ');
spacePadNum++;
}
}
/**
* register a line break for the formatted line.
*/
void ASFormatter::breakLine()
{
isLineReady = true;
isInLineBreak = false;
spacePadNum = 0;
formattedLineCommentNum = string::npos;
// queue an empty line prepend request if one exists
prependEmptyLine = isPrependPostBlockEmptyLineRequested;
readyFormattedLine = formattedLine;
if (isAppendPostBlockEmptyLineRequested)
{
isAppendPostBlockEmptyLineRequested = false;
isPrependPostBlockEmptyLineRequested = true;
}
else
{
isPrependPostBlockEmptyLineRequested = false;
}
formattedLine = "";
}
/**
* check if the currently reached open-bracket (i.e. '{')
* opens a:
* - a definition type block (such as a class or namespace),
* - a command block (such as a method block)
* - a static array
* this method takes for granted that the current character
* is an opening bracket.
*
* @return the type of the opened block.
*/
BracketType ASFormatter::getBracketType() const
{
BracketType returnVal;
if (foundPreDefinitionHeader)
{
returnVal = DEFINITION_TYPE;
if (foundNamespaceHeader)
returnVal = (BracketType)(returnVal | NAMESPACE_TYPE);
else if (foundClassHeader)
returnVal = (BracketType)(returnVal | CLASS_TYPE);
}
else
{
bool isCommandType = false;
if (previousNonWSChar != '=')
isCommandType = (foundPreCommandHeader
|| (currentHeader != NULL && isNonParenHeader)
|| (previousCommandChar == ')')
|| (previousCommandChar == ':' && !foundQuestionMark)
|| (previousCommandChar == ';')
|| ((previousCommandChar == '{' || previousCommandChar == '}')
&& isPreviousBracketBlockRelated));
returnVal = (isCommandType ? COMMAND_TYPE : ARRAY_TYPE);
}
if (isOneLineBlockReached())
returnVal = (BracketType)(returnVal | SINGLE_LINE_TYPE);
TRbracket(returnVal);
return returnVal;
}
/**
* check if the currently reached '*' or '&' character is
* a pointer-or-reference symbol, or another operator.
* this method takes for granted that the current character
* is either a '*' or '&'.
*
* @return whether current character is a reference-or-pointer
*/
bool ASFormatter::isPointerOrReference() const
{
bool isPR;
isPR = (!isInPotentialCalculation
|| IS_A(bracketTypeStack->back(), DEFINITION_TYPE)
|| (!isLegalNameChar(previousNonWSChar)
&& previousNonWSChar != ')'
&& previousNonWSChar != ']')
);
if (!isPR)
{
char nextChar = peekNextChar();
isPR |= (!isWhiteSpace(nextChar)
&& nextChar != '-'
&& nextChar != '('
&& nextChar != '['
&& !isLegalNameChar(nextChar));
}
return isPR;
}
/**
* check if the currently reached '-' character is
* a unary minus
* this method takes for granted that the current character
* is a '-'.
*
* @return whether the current '-' is a unary minus.
*/
bool ASFormatter::isUnaryMinus() const
{
return ((previousOperator == &AS_RETURN || !isalnum(previousCommandChar))
&& previousCommandChar != '.'
&& previousCommandChar != ')'
&& previousCommandChar != ']');
}
/**
* check if the currently reached '-' or '+' character is
* part of an exponent, i.e. 0.2E-5.
* this method takes for granted that the current character
* is a '-' or '+'.
*
* @return whether the current '-' is in an exponent.
*/
bool ASFormatter::isInExponent() const
{
int formattedLineLength = formattedLine.length();
if (formattedLineLength >= 2)
{
char prevPrevFormattedChar = formattedLine[formattedLineLength - 2];
char prevFormattedChar = formattedLine[formattedLineLength - 1];
return ((prevFormattedChar == 'e' || prevFormattedChar == 'E')
&& (prevPrevFormattedChar == '.' || isdigit(prevPrevFormattedChar)));
}
else
return false;
}
/**
* check if a one-line bracket has been reached,
* i.e. if the currently reached '{' character is closed
* with a complimentry '}' elsewhere on the current line,
*.
* @return has a one-line bracket been reached?
*/
bool ASFormatter::isOneLineBlockReached() const
{
bool isInComment = false;
bool isInQuote = false;
int bracketCount = 1;
int currentLineLength = currentLine.length();
char quoteChar = ' ';
for (int i = charNum + 1; i < currentLineLength; ++i)
{
char ch = currentLine[i];
if (isInComment)
{
if (currentLine.compare(i, 2, "*/") == 0)
{
isInComment = false;
++i;
}
continue;
}
if (ch == '\\')
{
++i;
continue;
}
if (isInQuote)
{
if (ch == quoteChar)
isInQuote = false;
continue;
}
if (ch == '"' || ch == '\'')
{
isInQuote = true;
quoteChar = ch;
continue;
}
if (currentLine.compare(i, 2, "//") == 0)
break;
if (currentLine.compare(i, 2, "/*") == 0)
{
isInComment = true;
++i;
continue;
}
if (ch == '{')
++bracketCount;
else if (ch == '}')
--bracketCount;
if (bracketCount == 0)
return true;
}
return false;
}
/**
* check if one of a set of headers has been reached in the
* current position of the current line.
*
* @return a pointer to the found header. Or a NULL if no header has been reached.
* @param headers a vector of headers.
* @param checkBoundry
*/
const string *ASFormatter::findHeader(const vector<const string*> &headers, bool checkBoundry)
{
return ASBeautifier::findHeader(currentLine, charNum, headers, checkBoundry);
}
/**
* check if a line begins with the specified character
* i.e. if the current line begins with a open bracket.
*
* @return true or false
*/
bool ASFormatter::lineBeginsWith(char charToCheck) const
{
bool beginsWith = false;
size_t i = currentLine.find_first_not_of(" \t");
if (i != string::npos)
if (currentLine[i] == charToCheck && (int) i == charNum)
beginsWith = true;
return beginsWith;
}
/**
* adjust comment position because of adding or deleting spaces
* the spaces are added or deleted to formattedLine
* spacePadNum contains the adjustment
*/
void ASFormatter::adjustComments(void)
{
assert(spacePadNum != 0);
assert(currentLine.compare(charNum, 2, "//") == 0
|| currentLine.compare(charNum, 2, "/*") == 0);
// block comment must be closed on this line with nothing after it
if (currentLine.compare(charNum, 2, "/*") == 0)
{
size_t endNum = currentLine.find("*/", charNum + 2);
if (endNum == string::npos)
return;
if (currentLine.find_first_not_of(" \t", endNum + 2) != string::npos)
return;
}
size_t len = formattedLine.length();
// if spaces were removed, need to add spaces before the comment
if (spacePadNum < 0)
{
int adjust = -spacePadNum; // make the number positive
if (formattedLine[len-1] != '\t') // don't adjust if a tab
formattedLine.append(adjust, ' ');
// else // comment out to avoid compiler warning
// adjust = 0;
// TRcomment(adjust); // trace macro
}
// if spaces were added, need to delete spaces before the comment, if possible
else if (spacePadNum > 0)
{
int adjust = spacePadNum;
if (formattedLine.find_last_not_of(' ') < len - adjust - 1
&& formattedLine[len-1] != '\t') // don't adjust a tab
formattedLine.resize(len - adjust);
// the following are commented out to avoid a Borland compiler warning
//else
// adjust = 0;
TRcomment(-adjust); // trace macro
}
}
/**
* append the current bracket inside the end of line comments
* currentChar contains the bracket, it will be appended to formattedLine
* formattedLineCommentNum is the comment location on formattedLine
*/
void ASFormatter::appendCharInsideComments(void)
{
if (formattedLineCommentNum == string::npos // does the comment start on the previous line?
|| isBeforeComment()) // does a comment follow on this line?
{
appendCurrentChar(true); // don't attach
return;
}
assert(formattedLine.compare(formattedLineCommentNum, 2, "//") == 0
|| formattedLine.compare(formattedLineCommentNum, 2, "/*") == 0);
// find the previous non space char
size_t end = formattedLineCommentNum;
size_t beg = formattedLine.find_last_not_of(" \t", end-1);
if (beg == string::npos) // is the previous line comment only?
{
appendCurrentChar(true); // don't attach
return;
}
beg++;
// insert the bracket
if (end - beg < 3) // is there room to insert?
formattedLine.insert(beg, 3-end+beg, ' ');
if (formattedLine[beg] == '\t') // don't pad with a tab
formattedLine.insert(beg, 1, ' ');
formattedLine[beg+1] = currentChar;
}
/**
* add or remove space padding to operators
* currentChar contains the paren
* the operators and necessary padding will be appended to formattedLine
* the calling function should have a continue statement after calling this method
*
* @param *newOperator the operator to be padded
*/
void ASFormatter::padOperators(const string *newOperator)
{
assert (shouldPadOperators);
assert(newOperator != NULL);
bool shouldPad = (newOperator != &AS_COLON_COLON
&& newOperator != &AS_PAREN_PAREN
&& newOperator != &AS_BLPAREN_BLPAREN
&& newOperator != &AS_PLUS_PLUS
&& newOperator != &AS_MINUS_MINUS
&& newOperator != &AS_NOT
&& newOperator != &AS_BIT_NOT
&& newOperator != &AS_ARROW
&& newOperator != &AS_OPERATOR
&& newOperator != &AS_RETURN
&& !(newOperator == &AS_MINUS && isInExponent())
&& !(newOperator == &AS_MINUS // check for negative number
&& (previousNonWSChar == '('
|| previousNonWSChar == '='
|| previousNonWSChar == ','))
&& !(newOperator == &AS_PLUS && isInExponent())
&& previousOperator != &AS_OPERATOR
&& !((newOperator == &AS_MULT || newOperator == &AS_BIT_AND)
&& isPointerOrReference())
&& !(newOperator == &AS_MULT
&& (previousNonWSChar == '.'
|| previousNonWSChar == '>')) // check for ->
&& !((isInTemplate || isCharImmediatelyPostTemplate)
&& (newOperator == &AS_LS || newOperator == &AS_GR))
);
// pad before operator
if (shouldPad
&& !isInBlParen
&& !(newOperator == &AS_COLON && !foundQuestionMark)
&& newOperator != &AS_SEMICOLON
&& newOperator != &AS_COMMA)
appendSpacePad();
appendSequence(*newOperator);
goForward(newOperator->length() - 1);
// since this block handles '()' and '[]',
// the parenStack must be updated here accordingly!
if (newOperator == &AS_PAREN_PAREN
|| newOperator == &AS_BLPAREN_BLPAREN)
parenStack->back()--;
currentChar = (*newOperator)[newOperator->length() - 1];
// pad after operator
// but do not pad after a '-' that is a unary-minus.
if (shouldPad
&& !isInBlParen
&& !isBeforeComment()
&& !(newOperator == &AS_MINUS && isUnaryMinus())
&& !(currentLine.compare(charNum + 1, 1, ";") == 0)
&& !(currentLine.compare(charNum + 1, 2, "::") == 0))
appendSpaceAfter();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -