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

📄 asbeautifier.cpp

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

		// handle comments

		if (!(isInComment || isInLineComment) && line.compare(i, 2, "//") == 0)
		{
			isInLineComment = true;
			outBuffer.append(1, '/');
			i++;
			continue;
		}
		else if (!(isInComment || isInLineComment) && line.compare(i, 2, "/*") == 0)
		{
			isInComment = true;
			outBuffer.append(1, '*');
			i++;
			size_t j = line.find_first_not_of(" \t");
			if (!line.compare(j, 2, "/*") == 0)	// does line start with comment?
				blockCommentNoIndent = true;	// if no, cannot indent continuation lines
			continue;
		}
		else if ((isInComment || isInLineComment) && line.compare(i, 2, "*/") == 0)
		{
			isInComment = false;
			outBuffer.append(1, '/');
			i++;
			blockCommentNoIndent = false;		// ok to indent next comment
			continue;
		}

		if (isInComment || isInLineComment)
			continue;

		// if we have reached this far then we are NOT in a comment or string of special character...

		if (probationHeader != NULL)
		{
			if (((probationHeader == &AS_STATIC || probationHeader == &AS_CONST) && ch == '{')
			        || (probationHeader == &AS_SYNCHRONIZED && ch == '('))
			{
				// insert the probation header as a new header
				isInHeader = true;
				headerStack->push_back(probationHeader);

				// handle the specific probation header
				isInConditional = (probationHeader == &AS_SYNCHRONIZED);
				if (probationHeader == &AS_CONST)
					isImmediatelyAfterConst = true;

				isInStatement = false;
				// if the probation comes from the previous line, then indent by 1 tab count.
				if (previousLineProbation && ch == '{')
				{
					tabCount++;
					previousLineProbationTab = true;
				}
				previousLineProbation = false;
			}

			// dismiss the probation header
			probationHeader = NULL;
		}

		prevNonSpaceCh = currentNonSpaceCh;
		currentNonSpaceCh = ch;
		if (!isLegalNameChar(ch) && ch != ',' && ch != ';')
		{
			prevNonLegalCh = currentNonLegalCh;
			currentNonLegalCh = ch;
		}

		if (isInHeader)
		{
			isInHeader = false;
			currentHeader = headerStack->back();
		}
		else
			currentHeader = NULL;

		if (isCStyle && isInTemplate
		        && (ch == '<' || ch == '>')
		        &&  findHeader(line, i, nonAssignmentOperators) == NULL)
		{
			if (ch == '<')
			{
				++templateDepth;
			}
			else if (ch == '>')
			{
				if (--templateDepth <= 0)
				{
					if (isInTemplate)
						ch = ';';
					else
						ch = 't';
					isInTemplate = false;
					templateDepth = 0;
				}
			}
		}

		// handle parenthesies
		if (ch == '(' || ch == '[' || ch == ')' || ch == ']')
		{
			if (ch == '(' || ch == '[')
			{
				if (parenDepth == 0)
				{
					parenStatementStack->push_back(isInStatement);
					isInStatement = true;
				}
				parenDepth++;

				inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());

				if (currentHeader != NULL)
					registerInStatementIndent(line, i, spaceTabCount, minConditionalIndent/*indentLength*2*/, true);
				else
					registerInStatementIndent(line, i, spaceTabCount, 0, true);
			}
			else if (ch == ')' || ch == ']')
			{
				parenDepth--;
				if (parenDepth == 0)
				{
					isInStatement = parenStatementStack->back();
					parenStatementStack->pop_back();
					ch = ' ';

					isInConditional = false;
				}

				if (!inStatementIndentStackSizeStack->empty())
				{
					int previousIndentStackSize = inStatementIndentStackSizeStack->back();
					inStatementIndentStackSizeStack->pop_back();
					while (previousIndentStackSize < (int) inStatementIndentStack->size())
						inStatementIndentStack->pop_back();

					if (!parenIndentStack->empty())
					{
						int poppedIndent = parenIndentStack->back();
						parenIndentStack->pop_back();

						if (i == 0)
							spaceTabCount = poppedIndent;
					}
				}
			}

			continue;
		}


		if (ch == '{')
		{
			bool isBlockOpener;
			// first, check if '{' is a block-opener or an static-array opener
			isBlockOpener = ((prevNonSpaceCh == '{' && bracketBlockStateStack->back())
			                 || prevNonSpaceCh == '}'
			                 || prevNonSpaceCh == ')'
			                 || prevNonSpaceCh == ';'
			                 || peekNextChar(line, i) == '{'
			                 || isNonInStatementArray
			                 || isInClassHeader
//			                 || isBlockOpener
			                 || isImmediatelyAfterConst
			                 || (isInDefine &&
			                     (prevNonSpaceCh == '('
			                      || prevNonSpaceCh == '_'
			                      || isalnum(prevNonSpaceCh))));

			isInClassHeader = false;
			if (!isBlockOpener && currentHeader != NULL)
			{
				for (size_t n = 0; n < nonParenHeaders.size(); n++)
					if (currentHeader == nonParenHeaders[n])
					{
						isBlockOpener = true;
						break;
					}
			}
			bracketBlockStateStack->push_back(isBlockOpener);
			if (!isBlockOpener)
			{
				inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
				registerInStatementIndent(line, i, spaceTabCount, 0, true);
				parenDepth++;
				if (i == 0)
					shouldIndentBrackettedLine = false;

				continue;
			}

			// this bracket is a block opener...

			++lineOpeningBlocksNum;
//			if (isInClassHeader)
//			isInClassHeader = false;

			if (isInClassHeaderTab)
			{
				isInClassHeaderTab = false;
				// decrease tab count if bracket is broken
				size_t firstChar = line.find_first_not_of(" \t");
				if (firstChar != string::npos)
					if (line[firstChar] == '{' && (int) firstChar == i)
						tabCount -= 2;
			}

			// do not allow inStatementIndent - should occur for Java files only
			if (inStatementIndentStack->size() > 0)
			{
				spaceTabCount = 0;
				inStatementIndentStack->back() = 0;
			}

			blockParenDepthStack->push_back(parenDepth);
			blockStatementStack->push_back(isInStatement);

			inStatementIndentStackSizeStack->push_back(inStatementIndentStack->size());
			if (inStatementIndentStack->size() > 0)
				inStatementIndentStack->back() = 0;

			blockTabCount += isInStatement ? 1 : 0;
			parenDepth = 0;
			isInStatement = false;

			tempStacks->push_back(new vector<const string*>);
			headerStack->push_back(&AS_OPEN_BRACKET);
			lastLineHeader = &AS_OPEN_BRACKET;

			continue;
		}

		//check if a header has been reached
		if (isWhiteSpace(prevCh))
		{
			bool isIndentableHeader = true;
			const string *newHeader = findHeader(line, i, headers);
			if (newHeader != NULL)
			{
				// if we reached here, then this is a header...
				isInHeader = true;

				vector<const string*> *lastTempStack;
				if (tempStacks->empty())
					lastTempStack = NULL;
				else
					lastTempStack = tempStacks->back();

				// if a new block is opened, push a new stack into tempStacks to hold the
				// future list of headers in the new block.

				// take care of the special case: 'else if (...)'
				if (newHeader == &AS_IF && lastLineHeader == &AS_ELSE)
				{
					headerStack->pop_back();
				}

				// take care of 'else'
				else if (newHeader == &AS_ELSE)
				{
					if (lastTempStack != NULL)
					{
						int indexOfIf = indexOf(*lastTempStack, &AS_IF);
						if (indexOfIf != -1)
						{
							// recreate the header list in headerStack up to the previous 'if'
							// from the temporary snapshot stored in lastTempStack.
							int restackSize = lastTempStack->size() - indexOfIf - 1;
							for (int r = 0; r < restackSize; r++)
							{
								headerStack->push_back(lastTempStack->back());
								lastTempStack->pop_back();
							}
							if (!closingBracketReached)
								tabCount += restackSize;
						}
						/*
						 * If the above if is not true, i.e. no 'if' before the 'else',
						 * then nothing beautiful will come out of this...
						 * I should think about inserting an Exception here to notify the caller of this...
						 */
					}
				}

				// check if 'while' closes a previous 'do'
				else if (newHeader == &AS_WHILE)
				{
					if (lastTempStack != NULL)
					{
						int indexOfDo = indexOf(*lastTempStack, &AS_DO);
						if (indexOfDo != -1)
						{
							// recreate the header list in headerStack up to the previous 'do'
							// from the temporary snapshot stored in lastTempStack.
							int restackSize = lastTempStack->size() - indexOfDo - 1;
							for (int r = 0; r < restackSize; r++)
							{
								headerStack->push_back(lastTempStack->back());
								lastTempStack->pop_back();
							}
							if (!closingBracketReached)
								tabCount += restackSize;
						}
					}
				}
				// check if 'catch' closes a previous 'try' or 'catch'
				else if (newHeader == &AS_CATCH || newHeader == &AS_FINALLY)
				{
					if (lastTempStack != NULL)
					{
						int indexOfTry = indexOf(*lastTempStack, &AS_TRY);
						if (indexOfTry == -1)
							indexOfTry = indexOf(*lastTempStack, &AS_CATCH);
						if (indexOfTry != -1)
						{
							// recreate the header list in headerStack up to the previous 'try'
							// from the temporary snapshot stored in lastTempStack.
							int restackSize = lastTempStack->size() - indexOfTry - 1;
							for (int r = 0; r < restackSize; r++)
							{
								headerStack->push_back(lastTempStack->back());
								lastTempStack->pop_back();
							}

							if (!closingBracketReached)
								tabCount += restackSize;
						}
					}
				}
				else if (newHeader == &AS_CASE)
				{
					isInCase = true;
					--tabCount;
				}
				else if (newHeader == &AS_DEFAULT)
				{
					isInCase = true;
					--tabCount;
				}
				else if (newHeader == &AS_STATIC
				         || newHeader == &AS_SYNCHRONIZED
				         || (newHeader == &AS_CONST && isCStyle))
				{
					if (!headerStack->empty() &&
					        (headerStack->back() == &AS_STATIC
					         || headerStack->back() == &AS_SYNCHRONIZED
					         || headerStack->back() == &AS_CONST))
					{
						isIndentableHeader = false;
					}
					else
					{
						isIndentableHeader = false;
						probationHeader = newHeader;
					}
				}
				else if (newHeader == &AS_CONST)
				{
					isIndentableHeader = false;
				}
				else if (newHeader == &AS_TEMPLATE)
				{
					if (isCStyle)
						isInTemplate = true;
					isIndentableHeader = false;
				}


				if (isIndentableHeader)
				{
					headerStack->push_back(newHeader);
					isInStatement = false;
					if (indexOf(nonParenHeaders, newHeader) == -1)
					{
						isInConditional = true;
					}
					lastLineHeader = newHeader;
				}
				else
					isInHeader = false;

				outBuffer.append(newHeader->substr(1));
				i += newHeader->length() - 1;

				continue;
			}
		}

		if (isCStyle && !isalpha(prevCh)
		        && line.compare(i, 8, "operator") == 0 && !isalnum(line[i+8]))
		{
			isInOperator = true;
			outBuffer.append(AS_OPERATOR.substr(1));
			i += 7;
			continue;
		}

		// "new" operator is a pointer, not a calculation
		if (!isalpha(prevCh)
		        && line.compare(i, 3, "new") == 0 && !isalnum(line[i+3]))
		{
			if (prevNonSpaceCh == '=' && isInStatement && !inStatementIndentStack->empty())
				inStatementIndentStack->back() = 0;
		}

		if (ch == '?')
			isInQuestion = true;


		// special handling of 'case' statements
		if (ch == ':')
		{
			if ((int) line.length() > i + 1 && line[i+1] == ':') // look for ::
			{
				++i;
				outBuffer.append(1, ':');
				ch = ' ';
				continue;
			}

			else if (isInQuestion)
			{
				isInQuestion = false;
			}

			else if (isCStyle && isInClass && prevNonSpaceCh != ')')
			{
				--tabCount;
				// found a 'private:' or 'public:' inside a class definition
				// so do nothing special
			}

			else if (!isJavaStyle && isInClassHeader)
			{
				// found a 'class A : public B' definition
				// so do nothing special
			}

			else if (isJavaStyle && lastLineHeader == &AS_FOR)
			{
				// found a java for-each statement
				// so do nothing special
			}

			else if (isCStyle && prevNonSpaceCh == ')')
			{
				isInClassHeader = true;
				if (i == 0)
					tabCount += 2;
			}
			else
			{
				currentNonSpaceCh = ';'; // so that brackets after the ':' will appear as block-openers
				if (isInCase)
				{
					isInCase = false;
					ch = ';'; // from here on, treat char as ';'
				}


				else // is in a label (e.g. 'label1:')
				{
					if (labelIndent)
						--tabCount; // unindent label by one indent
					else
						tabCount = 0; // completely flush indent to left
				}



			}
		}

		if ((ch == ';'  || (parenDepth > 0 && ch == ','))  && !inStatementIndentStackSizeStack->empty())
			while ((int) inStatementIndentStackSizeStack->back() + (parenDepth > 0 ? 1 : 0)
			        < (int) inStatementIndentStack->size())
				inStatementIndentStack->pop_back();


		// handle ends of statements
		if ((ch == ';' && parenDepth == 0) || ch == '}'/* || (ch == ',' && parenDepth == 0)*/)

⌨️ 快捷键说明

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