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

📄 asformatter.cpp

📁 著名的代码自动缩进软件ASTYLE的源码,为1.21版本,支持C/C++/JAVA的各种格式的排版,支持自定的样式,功能强大
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		        && shouldBreakOneLineStatements
		        && !foundQuestionMark           // not in a ... ? ... : ... sequence
		        && !foundPreDefinitionHeader    // not in a definition block (e.g. class foo : public bar
		        && previousCommandChar != ')'   // not immediately after closing paren of a method header, e.g. ASFormatter::ASFormatter(...) : ASBeautifier(...)
		        && previousChar != ':'          // not part of '::'
		        && peekNextChar() != ':')       // not part of '::'
		{
			passedColon = true;
			if (shouldBreakBlocks)
				isPrependPostBlockEmptyLineRequested = true;
		}

		if (currentChar == '?')
			foundQuestionMark = true;

		// determine if this is a potential calculation
		newHeader = findHeader(operators);

		if (newHeader != NULL)
		{
			if (!isInPotentialCalculation)
			{
				if (find(assignmentOperators.begin(), assignmentOperators.end(), newHeader)
				        != assignmentOperators.end())
				{
					char peekedChar = peekNextChar();
					isInPotentialCalculation = (newHeader != &AS_RETURN
					                            && !(newHeader == &AS_EQUAL && peekedChar == '*')
					                            && !(newHeader == &AS_EQUAL && peekedChar == '&'));
				}
			}
		}
		else
		{
			// the following are not calculations
			if (currentLine.compare(charNum, 3, "new") == 0 && !isLegalNameChar(currentLine[charNum+3]))
				isInPotentialCalculation = false;
		}

		if (shouldPadOperators && newHeader != NULL)
		{
			padOperators(newHeader);
			continue;
		}

		if ((shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens)
		        && (currentChar == '(' || currentChar == ')'))
		{
			padParens();
			continue;
		}

		appendCurrentChar();
	}   // end of while loop  *  end of while loop  *  end of while loop  *  end of while loop

	// return a beautified (i.e. correctly indented) line.

	string beautifiedLine;
	size_t readyFormattedLineLength = trim(readyFormattedLine).length();

	if (prependEmptyLine                // prepend a blank line before this formatted line
	        && readyFormattedLineLength > 0
	        && previousReadyFormattedLineLength > 0)
	{
		isLineReady = true;             // signal that a readyFormattedLine is still waiting
		beautifiedLine = beautify("");
		previousReadyFormattedLineLength = 0;
	}
	else								// format the current formatted line
	{
		isLineReady = false;
		beautifiedLine = beautify(readyFormattedLine);
		previousReadyFormattedLineLength = readyFormattedLineLength;
		lineCommentNoBeautify = lineCommentNoIndent;
		lineCommentNoIndent = false;
		if (appendOpeningBracket)       // insert bracket after this formatted line
		{
			appendOpeningBracket = false;
			isLineReady = true;         // signal that a readyFormattedLine is still waiting
			readyFormattedLine = "{";
			isPrependPostBlockEmptyLineRequested = false;	// next line should not be empty
		}
	}

	prependEmptyLine = false;
	enhance(beautifiedLine);                // call the enhancer function
	return beautifiedLine;
}


/**
* check if there are any indented lines ready to be read by nextLine()
*
* @return    are there any indented lines ready?
*/
bool ASFormatter::hasMoreLines() const
{
	return !endOfCodeReached;
}

/**
 * set the bracket formatting mode.
 * options:
 *    astyle::NONE_MODE     no formatting of brackets.
 *    astyle::ATTACH_MODE   Java, K&R style bracket placement.
 *    astyle::BREAK_MODE    ANSI C/C++ style bracket placement.
 *
 * @param mode         the bracket formatting mode.
 */
void ASFormatter::setBracketFormatMode(BracketMode mode)
{
	bracketFormatMode = mode;
}

/**
 * set closing header bracket breaking mode
 * options:
 *    true     brackets just before closing headers (e.g. 'else', 'catch')
 *             will be broken, even if standard brackets are attached.
 *    false    closing header brackets will be treated as standard brackets.
 *
 * @param state         the closing header bracket breaking mode.
 */
void ASFormatter::setBreakClosingHeaderBracketsMode(bool state)
{
	shouldBreakClosingHeaderBrackets = state;
}

/**
 * set 'else if()' breaking mode
 * options:
 *    true     'else' headers will be broken from their succeeding 'if' headers.
 *    false    'else' headers will be attached to their succeeding 'if' headers.
 *
 * @param state         the 'else if()' breaking mode.
 */
void ASFormatter::setBreakElseIfsMode(bool state)
{
	shouldBreakElseIfs = state;
}

/**
 * set operator padding mode.
 * options:
 *    true     statement operators will be padded with spaces around them.
 *    false    statement operators will not be padded.
 *
 * @param state         the padding mode.
 */
void ASFormatter::setOperatorPaddingMode(bool state)
{
	shouldPadOperators = state;
}

/**
* set parenthesis outside padding mode.
* options:
*    true     statement parenthesiss will be padded with spaces around them.
*    false    statement parenthesiss will not be padded.
*
* @param state         the padding mode.
*/
void ASFormatter::setParensOutsidePaddingMode(bool state)
{
	shouldPadParensOutside = state;
}

/**
* set parenthesis inside padding mode.
* options:
*    true     statement parenthesis will be padded with spaces around them.
*    false    statement parenthesis will not be padded.
*
* @param state         the padding mode.
*/
void ASFormatter::setParensInsidePaddingMode(bool state)
{
	shouldPadParensInside = state;
}

/**
* set parenthesis unpadding mode.
* options:
*    true     statement parenthesis will be unpadded with spaces removed around them.
*    false    statement parenthesis will not be unpadded.
*
* @param state         the padding mode.
*/
void ASFormatter::setParensUnPaddingMode(bool state)
{
	shouldUnPadParens = state;
}

/**
 * set option to break/not break one-line blocks
 *
 * @param state        true = break, false = don't break.
 */
void ASFormatter::setBreakOneLineBlocksMode(bool state)
{
	shouldBreakOneLineBlocks = state;
}

/**
 * set option to break/not break lines consisting of multiple statements.
 *
 * @param state        true = break, false = don't break.
 */
void ASFormatter::setSingleStatementsMode(bool state)
{
	shouldBreakOneLineStatements = state;
}

/**
 * set option to convert tabs to spaces.
 *
 * @param state        true = convert, false = don't convert.
 */
void ASFormatter::setTabSpaceConversionMode(bool state)
{
	shouldConvertTabs = state;
}


/**
 * set option to break unrelated blocks of code with empty lines.
 *
 * @param state        true = convert, false = don't convert.
 */
void ASFormatter::setBreakBlocksMode(bool state)
{
	shouldBreakBlocks = state;
}

/**
 * set option to break closing header blocks of code (such as 'else', 'catch', ...) with empty lines.
 *
 * @param state        true = convert, false = don't convert.
 */
void ASFormatter::setBreakClosingHeaderBlocksMode(bool state)
{
	shouldBreakClosingHeaderBlocks = state;
}

/**
 * jump over several characters.
 *
 * @param i       the number of characters to jump over.
 */
void ASFormatter::goForward(int i)
{
	while (--i >= 0)
		getNextChar();
}

/**
* peek at the next unread character.
*
* @return     the next unread character.
*/
char ASFormatter::peekNextChar() const
{
	char ch = ' ';
	size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1);

	if (peekNum == string::npos)
		return ch;

	ch = currentLine[peekNum];

//	if (shouldConvertTabs && ch == '\t')
//		ch = ' ';

	return ch;
}

/**
* check if current placement is before a comment or line-comment
*
* @return     is before a comment or line-comment.
*/
bool ASFormatter::isBeforeComment() const
{
	bool foundComment = false;
	size_t peekNum = currentLine.find_first_not_of(" \t", charNum + 1);

	if (peekNum == string::npos)
		return foundComment;

	foundComment = (currentLine.compare(peekNum, 2, "/*") == 0
	                || currentLine.compare(peekNum, 2, "//") == 0);

	return foundComment;
}

/**
* check if current placement is before a comment or line-comment
* if a block comment it must be at the end of the line
*
* @return     is before a comment or line-comment.
*/
bool ASFormatter::isBeforeLineEndComment(int startPos) const
{
	bool foundLineEndComment = false;
	size_t peekNum = currentLine.find_first_not_of(" \t", startPos + 1);

	if (peekNum != string::npos)
	{
		if (currentLine.compare(peekNum, 2, "//") == 0)
			foundLineEndComment = true;
		else if (currentLine.compare(peekNum, 2, "/*") == 0)
		{
			// comment must be closed on this line with nothing after it
			size_t endNum = currentLine.find("*/", peekNum + 2);
			if (endNum != string::npos)
				if (currentLine.find_first_not_of(" \t", endNum + 2) == string::npos)
					foundLineEndComment = true;
		}
	}
	return foundLineEndComment;
}


/**
* get the next character, increasing the current placement in the process.
* the new character is inserted into the variable currentChar.
*
* @return   whether succeded to recieve the new character.
*/
bool ASFormatter::getNextChar()
{
	isInLineBreak = false;
	previousChar = currentChar;

	if (!isWhiteSpace(currentChar))
	{
		previousNonWSChar = currentChar;
		if (!isInComment && !isInLineComment && !isInQuote
		        && !isImmediatelyPostComment
		        && !isImmediatelyPostLineComment
		        && !isSequenceReached("/*")
		        && !isSequenceReached("//"))
			previousCommandChar = previousNonWSChar;
	}

	int currentLineLength = currentLine.length();

	if (charNum + 1 < currentLineLength
	        && (!isWhiteSpace(peekNextChar()) || isInComment || isInLineComment))
	{
		currentChar = currentLine[++charNum];

		if (shouldConvertTabs && currentChar == '\t')
			currentChar = ' ';

		return true;
	}
	else        // end of line has been reached
	{
		if (sourceIterator->hasMoreLines())
		{
			currentLine = sourceIterator->nextLine();
			spacePadNum = 0;
			inLineNumber++;

			if (currentLine.length() == 0)
			{
				currentLine = string(" ");        // a null is inserted if this is not done
			}

			// unless reading in the first line of the file,
			// break a new line.
			if (!isVirgin)
				isInLineBreak = true;
			else
				isVirgin = false;

			if (isInLineComment)
				isImmediatelyPostLineComment = true;
			isInLineComment = false;

			// check if is in preprocessor before line trimming
			isImmediatelyPostPreprocessor = isInPreprocessor;
			if (previousNonWSChar != '\\')
				isInPreprocessor = false;

			trimNewLine();
			currentChar = currentLine[charNum];

			if (shouldConvertTabs && currentChar == '\t')
				currentChar = ' ';

			return true;
		}
		else
		{
			endOfCodeReached = true;
			return false;
		}
	}
}

/**
* jump over the leading white space in the current line,
* IF the line does not begin a comment or is in a preprocessor definition.
*/
void ASFormatter::trimNewLine()
{
	int len = currentLine.length();
	charNum = 0;

	if (isInComment || isInPreprocessor)
		return;

	while (isWhiteSpace(currentLine[charNum]) && charNum + 1 < len)
		++charNum;

	doesLineStartComment = false;
	if (isSequenceReached("/*"))
	{
		charNum = 0;
		doesLineStartComment = true;
	}
}

/**
 * append a character 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 character into
 * the next formatted line.
 *
 * @param ch               the character to append.
 * @param canBreakLine     if true, a registered line-break
 */
void ASFormatter::appendChar(char ch, bool canBreakLine)
{
	if (canBreakLine && isInLineBreak)
		breakLine();
	formattedLine.append(1, ch);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -