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

📄 asformatter.cpp

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

/**
 * add or remove space padding to parens
 * currentChar contains the paren
 * the parens and necessary padding will be appended to formattedLine
 * the calling function should have a continue statement after calling this method
 */
void ASFormatter::padParens(void)
{
	assert(shouldPadParensOutside || shouldPadParensInside || shouldUnPadParens);
	assert (currentChar == '(' || currentChar == ')');

	if (currentChar == '(')
	{
		int spacesOutsideToDelete = formattedLine.length() - 1;
		int spacesInsideToDelete = 0;

		// compute spaces outside the opening paren to delete
		if (shouldUnPadParens)
		{
			char lastChar = ' ';
			bool prevIsParenHeader = false;
			size_t i = formattedLine.find_last_not_of(" \t");
			if (i != string::npos)
			{
				size_t end = i;
				spacesOutsideToDelete -= i;
				lastChar = formattedLine[i];
				// was last word a paren header?
				int start;          // start of the previous word
				for (start = i; start > 0; start--)
				{
					if (isLegalNameChar(formattedLine[start]) || formattedLine[start] == '*')
						continue;
					start++;
					break;
				}
				string prevWord = formattedLine.substr(start, end-start+1);
				// if previous word is a header, it will be a paren header
				const string *prevWordH = ASBeautifier::findHeader(formattedLine, start, headers);
				if (prevWordH != NULL)
				{
					prevIsParenHeader = true;
					TRxtra(*prevWordH);         // trace macro
				}
				else if (prevWord == "return" 	// don't unpad return statements
				         || prevWord == "*")     // don't unpad multiply or pointer
				{
					prevIsParenHeader = true;
					TRxtra(prevWord);           // trace macro
				}
				// don't unpad variables
				else if (prevWord == "bool"
				         || prevWord ==  "int"
				         || prevWord ==  "void"
				         || prevWord ==  "void*"
				         || (prevWord.length() >= 6     // check end of word for _t
				             && prevWord.compare(prevWord.length()-2, 2, "_t") == 0)
				         || prevWord ==  "BOOL"
				         || prevWord ==  "DWORD"
				         || prevWord ==  "HWND"
				         || prevWord ==  "INT"
				         || prevWord ==  "LPSTR"
				         || prevWord ==  "VOID"
				         || prevWord ==  "LPVOID"
				        )
				{
					prevIsParenHeader = true;
					TRxtra(prevWord);           // trace macro
				}
			}
			// do not unpad operators, but leave them if already padded
			if (shouldPadParensOutside || prevIsParenHeader)
				spacesOutsideToDelete--;
			else if (lastChar == '|'          // check for ||
			         || lastChar == '&'      // check for &&
			         || lastChar == ','
			         || (lastChar == '>' && !foundCastOperator)
			         || lastChar == '<'
			         || lastChar == '?'
			         || lastChar == ':'
			         || lastChar == ';'
			         || lastChar == '='
			         || lastChar == '+'
			         || lastChar == '-'
			         || (lastChar == '*' && isInPotentialCalculation)
			         || lastChar == '/'
			         || lastChar == '%')
				spacesOutsideToDelete--;

			if (spacesOutsideToDelete > 0)
			{
				formattedLine.erase(i + 1, spacesOutsideToDelete);
				spacePadNum -= spacesOutsideToDelete;
			}
		}

		// pad open paren outside
		char peekedCharOutside = peekNextChar();
		if (shouldPadParensOutside)
			if (!(currentChar == '(' && peekedCharOutside == ')'))
				appendSpacePad();

		appendCurrentChar();

		// unpad open paren inside
		if (shouldUnPadParens)
		{
			size_t j = currentLine.find_first_not_of(" \t", charNum + 1);
			if (j != string::npos)
				spacesInsideToDelete = j - charNum - 1;
			if (shouldPadParensInside)
				spacesInsideToDelete--;
			if (spacesInsideToDelete > 0)
			{
				currentLine.erase(charNum + 1, spacesInsideToDelete);
				spacePadNum -= spacesInsideToDelete;
			}
		}

		// pad open paren inside
		char peekedCharInside = peekNextChar();
		if (shouldPadParensInside)
			if (!(currentChar == '(' && peekedCharInside == ')'))
				appendSpaceAfter();

		TRunpad('(', spacesOutsideToDelete, spacesInsideToDelete);       // trace macro
	}
	else if (currentChar == ')' /*|| currentChar == ']'*/)
	{
		int spacesOutsideToDelete = 0;
		int spacesInsideToDelete = formattedLine.length();

		// unpad close paren inside
		if (shouldUnPadParens)
		{
			size_t i = formattedLine.find_last_not_of(" \t");
			if (i != string::npos)
				spacesInsideToDelete = formattedLine.length() - 1 - i;
			if (shouldPadParensInside)
				spacesInsideToDelete--;
			if (spacesInsideToDelete > 0)
			{
				formattedLine.erase(i + 1, spacesInsideToDelete);
				spacePadNum -= spacesInsideToDelete;
			}
		}

		// pad close paren inside
		if (shouldPadParensInside)
			if (!(previousChar == '(' && currentChar == ')'))
				appendSpacePad();

		appendCurrentChar();

		// unpad close paren outside
		if (shouldUnPadParens)
		{
			// may have end of line comments
			size_t j = currentLine.find_first_not_of(" \t", charNum + 1);
			if (j != string::npos)
				if (currentLine[j] == '[' || currentLine[j] == ']')
					spacesOutsideToDelete = j - charNum - 1;
			if (shouldPadParensOutside)
				spacesOutsideToDelete--;
//                    spacesOutsideToDelete--;            // always leave 1 space

			if (spacesOutsideToDelete > 0)
			{
				currentLine.erase(charNum + 1, spacesOutsideToDelete);
				spacePadNum -= spacesOutsideToDelete;
			}
		}

		// pad close paren outside
		char peekedCharOutside = peekNextChar();
		if (shouldPadParensOutside)
			if (peekedCharOutside != ';'
			        && peekedCharOutside != ','
			        && peekedCharOutside != '.'
			        && peekedCharOutside != '-')    // check for ->
//                            && !(currentChar == ']' && peekedCharOutside == '['))
				appendSpaceAfter();

		TRunpad(')', spacesInsideToDelete, 0 /*spacesOutsideToDelete*/);       // trace macro
	}
	return;
}

/**
 * format brackets as attached or broken
 * currentChar contains the bracket
 * the brackets will be appended to the current formattedLine or a new formattedLine as necessary
 * the calling function should have a continue statement after calling this method
 *
 * @param bracketType    the type of bracket to be formatted.
 */
void ASFormatter::formatBrackets(BracketType bracketType)
{
	assert(!IS_A(bracketType, ARRAY_TYPE));
	assert (currentChar == '{' || currentChar == '}');

	if (currentChar == '{')
	{
		parenStack->push_back(0);
	}
	else if (currentChar == '}')
	{
		if (!parenStack->empty())
		{
			parenStack->pop_back();
		}
	}

	if (currentChar == '{')
	{
		bool bdacBreak = false;
		// should a Linux bracket be broken?
		if (bracketFormatMode == BDAC_MODE)
		{
			// always break a class
			if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], CLASS_TYPE))
				bdacBreak = true;
			// break a namespace and the first bracket if a function
			else if (bracketTypeStack->size() <= 2)
			{
				if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], NAMESPACE_TYPE)
				        || IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE))
					bdacBreak = true;
			}
			// break the first bracket after a namespace if a function
			else if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-2], NAMESPACE_TYPE))
			{
				if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE))
					bdacBreak = true;
			}
			// if not C style then break the first bracket after a class if a function
			else if (!ASBeautifier::isCStyle)
			{
				if (IS_A((*bracketTypeStack)[bracketTypeStack->size()-2], CLASS_TYPE)
				        && IS_A((*bracketTypeStack)[bracketTypeStack->size()-1], COMMAND_TYPE))
					bdacBreak = true;
			}
		}
		if (bracketFormatMode == ATTACH_MODE
		        || (bracketFormatMode == BDAC_MODE && !bdacBreak))
		{
			// are there comments before the bracket?
			if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment)
			{
				if ((shouldBreakOneLineBlocks || !IS_A(bracketType,  SINGLE_LINE_TYPE))
				        && peekNextChar() != '}')
					appendCharInsideComments();
				else
					appendCurrentChar(true);		// don't attach
			}
			else if (previousCommandChar == '{'
			         || previousCommandChar == '}'
			         || previousCommandChar == ';')  // '}' , ';' chars added for proper handling of '{' immediately after a '}' or ';'
			{
				appendCurrentChar(true);			// don't attach
			}
			else
			{
				size_t firstChar = formattedLine.find_first_not_of(" \t");
				if (firstChar == string::npos)		// if a blank line preceeds this
					appendCurrentChar(true);		// don't attach
				else if (shouldBreakOneLineBlocks
				         || !IS_A(bracketType,  SINGLE_LINE_TYPE)
				         || peekNextChar() == '}')
				{
					appendSpacePad();
					appendCurrentChar(false);		// OK to attach
				}
				else
					appendCurrentChar(true);		// don't attach
			}
		}
		else if (bracketFormatMode == BREAK_MODE
		         || (bracketFormatMode == BDAC_MODE && bdacBreak))
		{
			if (isBeforeComment())
			{
				// do not break unless comment is at line end
				if (isBeforeLineEndComment(charNum))
				{
					currentChar = ' ';				// remove bracket from current line
					appendOpeningBracket = true;	// append bracket to following line
				}
			}
			else if (!IS_A(bracketType,  SINGLE_LINE_TYPE))
				breakLine();
			else if (shouldBreakOneLineBlocks && peekNextChar() != '}')
				breakLine();

			appendCurrentChar();
		}
		else if (bracketFormatMode == NONE_MODE)
		{
			if (lineBeginsWith('{'))                // is opening bracket broken?
				appendCurrentChar(true);
			else
				appendCurrentChar(false);
		}
	}
	else if (currentChar == '}')
	{
		// mark state of immediately after empty block
		// this state will be used for locating brackets that appear immedately AFTER an empty block (e.g. '{} \n}').
		if (previousCommandChar == '{')
			isImmediatelyPostEmptyBlock = true;

		if ((!(previousCommandChar == '{' && isPreviousBracketBlockRelated))            // this '{' does not close an empty block
		        && (shouldBreakOneLineBlocks || !IS_A(bracketType,  SINGLE_LINE_TYPE))  // astyle is allowed to break on line blocks
		        && (!(bracketFormatMode == NONE_MODE && IS_A(bracketType,  SINGLE_LINE_TYPE)))
		        && !isImmediatelyPostEmptyBlock)                                        // this '}' does not immediately follow an empty block
		{
			breakLine();
			appendCurrentChar();
		}
		else
		{
			if (!isCharImmediatelyPostComment
			        && !bracketFormatMode == NONE_MODE
			        && !isImmediatelyPostEmptyBlock)
				isInLineBreak = false;

			appendCurrentChar();

			//if (!bracketFormatMode == NONE_MODE)
			//	if ((shouldBreakOneLineBlocks || !IS_A(bracketType,  SINGLE_LINE_TYPE))
			//	        && !(currentChar == '}' && peekNextChar() == ';'))      // fixes }; placed on separate lines
			//		shouldBreakLineAfterComments = true;
		}

		if (shouldBreakBlocks)
		{
			isAppendPostBlockEmptyLineRequested = true;
		}
	}
	return;
}

/**
 * format array brackets as attached or broken
 * determine if the brackets can have an inStatement indent
 * currentChar contains the bracket
 * the brackets will be appended to the current formattedLine or a new formattedLine as necessary
 * the calling function should have a continue statement after calling this method
 *
 * @param bracketType            the type of bracket to be formatted, must be an ARRAY_TYPE.
 * @param isOpeningArrayBracket  indicates if this is the opening bracket for the array block.
 */
void ASFormatter::formatArrayBrackets(BracketType bracketType, bool isOpeningArrayBracket)
{
	assert(IS_A(bracketType, ARRAY_TYPE));
	assert (currentChar == '{' || currentChar == '}');

	if (currentChar == '{')
	{
		// is this the first opening bracket in the array?
		if (isOpeningArrayBracket)
		{
			if (bracketFormatMode == ATTACH_MODE || bracketFormatMode == BDAC_MODE)
			{
				// don't attach to a preprocessor directive
				if (isImmediatelyPostPreprocessor)
					appendCurrentChar(true);			// don't attach
				// are there comments before the bracket?
				else if (isCharImmediatelyPostComment || isCharImmediatelyPostLineComment)
				{
					appendCharInsideComments();
				}
				else
				{
					// if bracket is broken or not an assignment
					if (lineBeginsWith('{') || previousNonWSChar != '=')
						appendSpacePad();
					appendCurrentChar(false);			// OK to attach
				}
			}
			else if (bracketFormatMode == BREAK_MODE)
			{
				if (isWhiteSpace(peekNextChar()))
					breakLine();
				else if (isBeforeComment())
				{
					// do not break unless comment is at line end
					if (isBeforeLineEndComment(charNum))
					{
						currentChar = ' ';				// remove bracket from current line
						appendOpeningBracket = true;	// append bracket to following line
					}
				}
				appendCurrentChar();
			}
			else if (bracketFormatMode == NONE_MODE)
			{
				if (lineBeginsWith('{'))                // is opening bracket broken?
					appendCurrentChar();
				else
					appendCurrentChar(false);
			}
		}
		else
			appendCurrentChar();	 // not the first opening bracket - don't change

		// if an opening bracket ends the line there will be no inStatement indent
		char nextChar = peekNextChar();
		if (isWhiteSpace(nextChar)
		        || isBeforeLineEndComment(charNum)
		        || nextChar == '{')
			isNonInStatementArray = true;
		if (isNonInStatementArray)
			TRarray('x');
		else
			TRarray(' ');

	}
	else if (currentChar == '}')
	{
		// does this close the first opening bracket in the array?
		if (isOpeningArrayBracket && !IS_A(bracketType, SINGLE_LINE_TYPE) )
		{
			breakLine();
			appendCurrentChar();
		}
		else
			appendCurrentChar();
	}
}


}   // end namespace astyle

⌨️ 快捷键说明

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