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

📄 asformatter.cpp

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

		/* not in preprocessor ... */

		if (isImmediatelyPostComment)
		{
			isImmediatelyPostComment = false;
			isCharImmediatelyPostComment = true;
		}

		if (isImmediatelyPostLineComment)
		{
			isImmediatelyPostLineComment = false;
			isCharImmediatelyPostLineComment = true;
		}

		if (shouldBreakLineAfterComments)
		{
			shouldBreakLineAfterComments = false;
			shouldReparseCurrentChar = true;
			breakLine();
			continue;
		}

		// reset isImmediatelyPostHeader information
		if (isImmediatelyPostHeader)
		{
			isImmediatelyPostHeader = false;

			// Make sure headers are broken from their succeeding blocks
			// (e.g.
			//     if (isFoo) DoBar();
			//  should become
			//     if (isFoo)
			//         DoBar;
			// )
			// But treat else if() as a special case which should not be broken!
			if (shouldBreakOneLineStatements)
			{
				// if may break 'else if()'s, then simply break the line

				if (shouldBreakElseIfs)
					isInLineBreak = true;
			}
		}

		if (passedSemicolon)	// need to break the formattedLine
		{
			passedSemicolon = false;
			if (parenStack->back() == 0 && currentChar != ';') // allow ;;
			{
				// does a one-line statement have ending comments?
				if (IS_A(bracketTypeStack->back(), SINGLE_LINE_TYPE))
				{
					size_t blockEnd = currentLine.rfind(AS_CLOSE_BRACKET);
					assert(blockEnd != string::npos);
					// move ending comments to this formattedLine
					if (isBeforeLineEndComment(blockEnd))
					{
						size_t commentStart = currentLine.find_first_not_of(" \t", blockEnd + 1);
						assert(commentStart != string::npos);
						assert((currentLine.compare(commentStart, 2, "//") == 0)
						       || (currentLine.compare(commentStart, 2, "/*") == 0));
						size_t commentLength = currentLine.length() - commentStart;
						int tabCount = getIndentLength();
						appendSpacePad();
						for (int i=1; i<tabCount; i++)
							formattedLine.append(1, ' ');
						formattedLine.append(currentLine, commentStart, commentLength);
						currentLine.erase(commentStart, commentLength);
					}
				}
				shouldReparseCurrentChar = true;
				isInLineBreak = true;
				continue;
			}
		}

		if (passedColon)
		{
			passedColon = false;
			if (parenStack->back() == 0 && !isBeforeComment())
			{
				shouldReparseCurrentChar = true;
				isInLineBreak = true;
				continue;
			}
		}

		// Check if in template declaration, e.g. foo<bar> or foo<bar,fig>
		// If so, set isInTemplate to true
		if (!isInTemplate && currentChar == '<')
		{
			int maxTemplateDepth = 0;
			templateDepth = 0;
			const string *oper;
			for (size_t i = charNum;
			        i < currentLine.length();
			        i += (oper ? oper->length() : 1))
			{
				oper = ASBeautifier::findHeader(currentLine, i, operators);

				if (oper == &AS_LS)
				{
					templateDepth++;
					maxTemplateDepth++;
				}
				else if (oper == &AS_GR)
				{
					templateDepth--;
					if (templateDepth == 0)
					{
						// this is a template!
						isInTemplate = true;
						templateDepth = maxTemplateDepth;
						break;
					}
				}
				else if (oper == &AS_COMMA            // comma,     e.g. A<int, char>
				         || oper == &AS_BIT_AND       // reference, e.g. A<int&>
				         || oper == &AS_MULT          // pointer,   e.g. A<int*>
				         || oper == &AS_COLON_COLON)  // ::,        e.g. std::string
				{
					continue;
				}
				else if (!isLegalNameChar(currentLine[i]) && !isWhiteSpace(currentLine[i]))
				{
					// this is not a template -> leave...
					isInTemplate = false;
					break;
				}
			}
		}

		// handle parenthesies
		if (currentChar == '(' || currentChar == '[' || (isInTemplate && currentChar == '<'))
		{
			parenStack->back()++;
			if (currentChar == '[')
				isInBlParen = true;
		}
		else if (currentChar == ')' || currentChar == ']' || (isInTemplate && currentChar == '>'))
		{
			parenStack->back()--;
			if (isInTemplate && currentChar == '>')
			{
				templateDepth--;
				if (templateDepth == 0)
				{
					isInTemplate = false;
					isCharImmediatelyPostTemplate = true;
				}
			}

			// check if this parenthesis closes a header, e.g. if (...), while (...)
			if (isInHeader && parenStack->back() == 0)
			{
				isInHeader = false;
				isImmediatelyPostHeader = true;
			}
			if (currentChar == ']')
				isInBlParen = false;
			if (currentChar == ')')
				foundCastOperator = false;
		}

		// handle brackets
		if (currentChar == '{' || currentChar == '}')
		{
			if (currentChar == '{')
			{
				BracketType newBracketType = getBracketType();
				foundNamespaceHeader = false;
				foundClassHeader = false;
				foundPreDefinitionHeader = false;
				foundPreCommandHeader = false;
				isInPotentialCalculation = false;

				bracketTypeStack->push_back(newBracketType);
				preBracketHeaderStack->push_back(currentHeader);
				currentHeader = NULL;

				isPreviousBracketBlockRelated = !IS_A(newBracketType, ARRAY_TYPE);
			}

			// this must be done before the bracketTypeStack is popped
			BracketType bracketType = bracketTypeStack->back();
			bool isOpeningArrayBracket = (IS_A(bracketType, ARRAY_TYPE)
			                              && bracketTypeStack->size() >= 2
			                              && !IS_A((*bracketTypeStack)[bracketTypeStack->size()-2], ARRAY_TYPE)
			                             );

			if (currentChar == '}')
			{
				// if a request has been made to append a post block empty line,
				// but the block exists immediately before a closing bracket,
				// then there is not need for the post block empty line.
				//
				isAppendPostBlockEmptyLineRequested = false;

				if (!bracketTypeStack->empty())
				{
					previousBracketType = bracketTypeStack->back();
					bracketTypeStack->pop_back();
					isPreviousBracketBlockRelated = !IS_A(bracketType, ARRAY_TYPE);
				}

				if (!preBracketHeaderStack->empty())
				{
					currentHeader = preBracketHeaderStack->back();
					preBracketHeaderStack->pop_back();
				}
				else
					currentHeader = NULL;
			}

			// format brackets
			if (IS_A(bracketType, ARRAY_TYPE))
				formatArrayBrackets(bracketType, isOpeningArrayBracket);
			else
				formatBrackets(bracketType);
			continue;
		}

		if (((previousCommandChar == '{' && isPreviousBracketBlockRelated)
		        || (previousCommandChar == '}'
		            && bracketFormatMode != NONE_MODE
		            && !isImmediatelyPostEmptyBlock
		            && isPreviousBracketBlockRelated
		            && !isPreviousCharPostComment       // Fixes wrongly appended newlines after '}' immediately after comments
		            && peekNextChar() != ' '
		            && !IS_A(previousBracketType,  DEFINITION_TYPE)
		            && !(ASBeautifier::isJavaStyle && currentChar == ')'))
		        && !IS_A(bracketTypeStack->back(),  DEFINITION_TYPE))
		        && (shouldBreakOneLineBlocks
		            || !IS_A(bracketTypeStack->back(),  SINGLE_LINE_TYPE)))
		{
			isCharImmediatelyPostOpenBlock = (previousCommandChar == '{');
			isCharImmediatelyPostCloseBlock = (previousCommandChar == '}');

			//if (bracketFormatMode != NONE_MODE)
			//{
			previousCommandChar = ' ';
			isInLineBreak = true;
			//}
		}

		// reset block handling flags
		isImmediatelyPostEmptyBlock = false;

		// look for headers
		if (!isInTemplate)
		{
			if ((newHeader = findHeader(headers)) != NULL)
			{
				foundClosingHeader = false;
				const string *previousHeader;

				// recognize closing headers of do..while, if..else, try..catch..finally
				if ((newHeader == &AS_ELSE && currentHeader == &AS_IF)
				        || (newHeader == &AS_WHILE && currentHeader == &AS_DO)
				        || (newHeader == &AS_CATCH && currentHeader == &AS_TRY)
				        || (newHeader == &AS_CATCH && currentHeader == &AS_CATCH)
				        || (newHeader == &AS_FINALLY && currentHeader == &AS_TRY)
				        || (newHeader == &AS_FINALLY && currentHeader == &AS_CATCH))
					foundClosingHeader = true;

				previousHeader = currentHeader;
				currentHeader = newHeader;

				// If in ATTACH or LINUX bracket modes, attach closing headers (e.g. 'else', 'catch')
				// to their preceding bracket,
				// But do not perform the attachment if the shouldBreakClosingHeaderBrackets is set!
				if (!shouldBreakClosingHeaderBrackets
				        && foundClosingHeader
				        && (bracketFormatMode == ATTACH_MODE || bracketFormatMode == BDAC_MODE)
				        && (shouldBreakOneLineBlocks || !IS_A(previousBracketType,  SINGLE_LINE_TYPE))
				        && previousNonWSChar == '}')
				{
					spacePadNum = 0;                // don't count as padding

					size_t firstChar = formattedLine.find_first_not_of(" \t");
					if (firstChar != string::npos)		// if a blank line does not preceed this
					{
						isInLineBreak = false;
						appendSpacePad();
					}

					if (shouldBreakBlocks)
						isAppendPostBlockEmptyLineRequested = false;
				}

				// If NONE bracket mode, leave closing headers as they are (e.g. 'else', 'catch')
				if (foundClosingHeader && bracketFormatMode == NONE_MODE && previousCommandChar == '}')
				{
					if (lineBeginsWith('}'))                    // is closing bracket broken?
					{
						isInLineBreak = false;
						appendSpacePad();
					}

					if (shouldBreakBlocks)
						isAppendPostBlockEmptyLineRequested = false;
				}

				if (foundClosingHeader && bracketFormatMode == BREAK_MODE && previousCommandChar == '}')
					breakLine();

				//Check if a template definition as been reached, e.g. template<class A>
				//if (newHeader == &AS_TEMPLATE)
				//{
				//	isInTemplate = true;
				//}

				// check if the found header is non-paren header
				isNonParenHeader = (find(nonParenHeaders.begin(), nonParenHeaders.end(),
				                         newHeader) != nonParenHeaders.end());

				appendSequence(*currentHeader);
				goForward(currentHeader->length() - 1);
				// if a paren-header is found add a space after it, if needed
				// this checks currentLine, appendSpacePad() checks formattedLine
				if (!isNonParenHeader && charNum < (int) currentLine.length() && !isWhiteSpace(currentLine[charNum+1]))
					appendSpacePad();

				// Signal that a header has been reached
				// *** But treat a closing while() (as in do...while)
				//     as if it where NOT a header since a closing while()
				//     should never have a block after it!
				if (!(foundClosingHeader && currentHeader == &AS_WHILE))
				{
					isInHeader = true;
					if (isNonParenHeader)
					{
						isImmediatelyPostHeader = true;
						isInHeader = false;
					}
				}

				if (currentHeader == &AS_IF && previousHeader == &AS_ELSE)
					isInLineBreak = false;

				if (shouldBreakBlocks)
				{
					if (previousHeader == NULL
					        && !foundClosingHeader
					        && !isCharImmediatelyPostOpenBlock)
					{
						isPrependPostBlockEmptyLineRequested = true;
					}

					if (currentHeader == &AS_ELSE
					        || currentHeader == &AS_CATCH
					        || currentHeader == &AS_FINALLY
					        || foundClosingHeader)
					{
						isPrependPostBlockEmptyLineRequested = false;
					}

					if (shouldBreakClosingHeaderBlocks
					        &&  isCharImmediatelyPostCloseBlock)
					{
						isPrependPostBlockEmptyLineRequested = true;
					}

				}

				continue;
			}
			else if ((newHeader = findHeader(preDefinitionHeaders)) != NULL
			         && parenStack->back() == 0)
			{
				if (newHeader == &AS_NAMESPACE)
					foundNamespaceHeader = true;
				if (newHeader == &AS_CLASS)
					foundClassHeader = true;
				foundPreDefinitionHeader = true;
				appendSequence(*newHeader);
				goForward(newHeader->length() - 1);

				if (shouldBreakBlocks)
					isPrependPostBlockEmptyLineRequested = true;

				continue;
			}
			else if ((newHeader = findHeader(preCommandHeaders)) != NULL)
			{
				if (ASBeautifier::isJavaStyle
				        || (*newHeader == AS_CONST && previousCommandChar == ')') // 'const' member functions is a command bracket
				        || *newHeader == AS_EXTERN)
					foundPreCommandHeader = true;
				appendSequence(*newHeader);
				goForward(newHeader->length() - 1);

				continue;
			}
			else if ((newHeader = findHeader(castOperators)) != NULL)
			{
				foundCastOperator = true;
				appendSequence(*newHeader);
				goForward(newHeader->length() - 1);

				continue;
			}

		}

		if (isInLineBreak)          // OK to break line here
			breakLine();

		if (previousNonWSChar == '}' || currentChar == ';')
		{
			if (shouldBreakOneLineStatements && currentChar == ';'
			        && (shouldBreakOneLineBlocks || !IS_A(bracketTypeStack->back(),  SINGLE_LINE_TYPE))
			        //&& (! bracketFormatMode == NONE_MODE)
			   )
			{
				passedSemicolon = true;
			}

			if (shouldBreakBlocks && currentHeader != NULL && parenStack->back() == 0)
			{
				isAppendPostBlockEmptyLineRequested = true;
			}

			if (currentChar != ';')
				currentHeader = NULL;

			foundQuestionMark = false;
			foundNamespaceHeader = false;
			foundClassHeader = false;
			foundPreDefinitionHeader = false;
			foundPreCommandHeader = false;
			foundCastOperator = false;
			isInPotentialCalculation = false;
			isNonInStatementArray = false;
		}

		if (currentChar == ':'

⌨️ 快捷键说明

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