⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asformatter.cpp

📁 著名的代码自动缩进软件ASTYLE的源码,为1.21版本,支持C/C++/JAVA的各种格式的排版,支持自定的样式,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

/**
 * 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 + -