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

📄 asbeautifier.cpp

📁 c语言格式化源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
						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)*/)		{			if (ch == '}')			{				// first check if this '}' closes a previous block, or a static array...				if (!bracketBlockStateStack->empty())				{					bool bracketBlockState = bracketBlockStateStack->back();					bracketBlockStateStack->pop_back();					if (!bracketBlockState)					{						if (!inStatementIndentStackSizeStack->empty())						{							// this bracket is a static array							int previousIndentStackSize = inStatementIndentStackSizeStack->back();							inStatementIndentStackSizeStack->pop_back();							while (previousIndentStackSize < (int) inStatementIndentStack->size())								inStatementIndentStack->pop_back();							parenDepth--;							if (i == 0)								shouldIndentBrackettedLine = false;							if (!parenIndentStack->empty())							{								int poppedIndent = parenIndentStack->back();								parenIndentStack->pop_back();								if (i == 0)									spaceTabCount = poppedIndent;							}						}						continue;					}				}				// this bracket is block closer...				++lineClosingBlocksNum;				if (!inStatementIndentStackSizeStack->empty())					inStatementIndentStackSizeStack->pop_back();				if (!blockParenDepthStack->empty())				{					parenDepth = blockParenDepthStack->back();					blockParenDepthStack->pop_back();					isInStatement = blockStatementStack->back();					blockStatementStack->pop_back();					if (isInStatement)						blockTabCount--;				}				closingBracketReached = true;				int headerPlace = indexOf(*headerStack, &AS_OPEN_BRACKET);				if (headerPlace != -1)				{					const string *popped = headerStack->back();					while (popped != &AS_OPEN_BRACKET)					{						headerStack->pop_back();						popped = headerStack->back();					}					headerStack->pop_back();					if (!tempStacks->empty())					{						vector<const string*> *temp =  tempStacks->back();						tempStacks->pop_back();						delete temp;					}				}				ch = ' '; // needed due to cases such as '}else{', so that headers ('else' tn tih case) will be identified...			}			/*			 * Create a temporary snapshot of the current block's header-list in the			 * uppermost inner stack in tempStacks, and clear the headerStack up to			 * the begining of the block.			 * Thus, the next future statement will think it comes one indent past			 * the block's '{' unless it specifically checks for a companion-header			 * (such as a previous 'if' for an 'else' header) within the tempStacks,			 * and recreates the temporary snapshot by manipulating the tempStacks.			 */			if (!tempStacks->back()->empty())				while (!tempStacks->back()->empty())					tempStacks->back()->pop_back();			while (!headerStack->empty() && headerStack->back() != &AS_OPEN_BRACKET)			{				tempStacks->back()->push_back(headerStack->back());				headerStack->pop_back();			}			if (parenDepth == 0 && ch == ';')				isInStatement = false;			previousLastLineHeader = NULL;			isInClassHeader = false;			isInQuestion = false;			continue;		}		// check for preBlockStatements ONLY if not within parenthesies		// (otherwise 'struct XXX' statements would be wrongly interpreted...)		if (isWhiteSpace(prevCh) && !isInTemplate && parenDepth == 0)		{			const string *newHeader = findHeader(line, i, preBlockStatements);			if (newHeader != NULL)			{				isInClassHeader = true;				outBuffer.append(newHeader->substr(1));				i += newHeader->length() - 1;				headerStack->push_back(newHeader);			}		}		// Handle operators		immediatelyPreviousAssignmentOp = NULL;		// Check if an operator has been reached.		const string *foundAssignmentOp = findHeader(line, i, assignmentOperators, false);		if (foundAssignmentOp == &AS_RETURN		        || foundAssignmentOp == &AS_CIN		        || foundAssignmentOp == &AS_COUT		        || foundAssignmentOp == &AS_CERR)			foundAssignmentOp = findHeader(line, i, assignmentOperators, true);		const string *foundNonAssignmentOp = findHeader(line, i, nonAssignmentOperators, false);		// Since findHeader's boundry checking was not used above, it is possible		// that both an assignment op and a non-assignment op where found,		// e.g. '>>' and '>>='. If this is the case, treat the LONGER one as the		// found operator.		if (foundAssignmentOp != NULL && foundNonAssignmentOp != NULL)		{			if (foundAssignmentOp->length() < foundNonAssignmentOp->length())				foundAssignmentOp = NULL;			else				foundNonAssignmentOp = NULL;		}		if (foundNonAssignmentOp != NULL)		{			if (foundNonAssignmentOp->length() > 1)			{				outBuffer.append(foundNonAssignmentOp->substr(1));				i += foundNonAssignmentOp->length() - 1;			}		}		else if (foundAssignmentOp != NULL)		{			if (foundAssignmentOp->length() > 1)			{				outBuffer.append(foundAssignmentOp->substr(1));				i += foundAssignmentOp->length() - 1;			}			if (!isInOperator && !isInTemplate && !isNonInStatementArray)			{				registerInStatementIndent(line, i, spaceTabCount, 0, false);				immediatelyPreviousAssignmentOp = foundAssignmentOp;				isInStatement = true;			}		}		if (isInOperator)			isInOperator = false;	}	// handle special cases of unindentation:	/*	 * if '{' doesn't follow an immediately previous '{' in the headerStack	 * (but rather another header such as "for" or "if", then unindent it	 * by one indentation relative to its block.	 */	if (!lineStartsInComment	        && !blockIndent	        && outBuffer.length() > 0	        && outBuffer[0] == '{'	        && !(lineOpeningBlocksNum > 0 && lineOpeningBlocksNum == lineClosingBlocksNum)	        && !(headerStack->size() > 1 && (*headerStack)[headerStack->size()-2] == &AS_OPEN_BRACKET)	        && shouldIndentBrackettedLine)		--tabCount;	else if (!lineStartsInComment	         && outBuffer.length() > 0	         && outBuffer[0] == '}'	         && shouldIndentBrackettedLine)		--tabCount;	// correctly indent one-line-blocks...	else if (!lineStartsInComment	         && outBuffer.length() > 0	         && lineOpeningBlocksNum > 0	         && lineOpeningBlocksNum == lineClosingBlocksNum	         && previousLineProbationTab)		--tabCount; //lineOpeningBlocksNum - (blockIndent ? 1 : 0);	if (tabCount < 0)		tabCount = 0;	// take care of extra bracket indentatation option...	if (bracketIndent && outBuffer.length() > 0 && shouldIndentBrackettedLine)		if (outBuffer[0] == '{' || outBuffer[0] == '}')			tabCount++;	if (isInDefine)	{		if (outBuffer[0] == '#')		{			string preproc = trim(string(outBuffer.c_str() + 1));			if (preproc.compare(0, 6, "define") == 0)			{				if (!inStatementIndentStack->empty()				        && inStatementIndentStack->back() > 0)				{					defineTabCount = tabCount;				}				else				{					defineTabCount = tabCount - 1;					tabCount--;				}			}		}		tabCount -= defineTabCount;	}	if (tabCount < 0)		tabCount = 0;	if (lineCommentNoBeautify || blockCommentNoBeautify || isInQuoteContinuation)		tabCount = spaceTabCount = 0;	// finally, insert indentations into begining of line	prevFinalLineSpaceTabCount = spaceTabCount;	prevFinalLineTabCount = tabCount;	if (shouldForceTabIndentation)	{		tabCount += spaceTabCount / indentLength;		spaceTabCount = spaceTabCount % indentLength;	}	outBuffer = preLineWS(spaceTabCount, tabCount) + outBuffer;	if (lastLineHeader != NULL)		previousLastLineHeader = lastLineHeader;	return outBuffer;}string ASBeautifier::preLineWS(int spaceTabCount, int tabCount){	string ws;	for (int i = 0; i < tabCount; i++)		ws += indentString;	while ((spaceTabCount--) > 0)		ws += string(" ");	return ws;}/** * register an in-statement indent. */void ASBeautifier::registerInStatementIndent(const string &line, int i, int spaceTabCount,        int minIndent, bool updateParenStack){	int inStatementIndent;	int remainingCharNum = line.length() - i;	int nextNonWSChar = getNextProgramCharDistance(line, i);	// if indent is around the last char in the line, indent instead 2 spaces from the previous indent	if (nextNonWSChar == remainingCharNum)	{		int previousIndent = spaceTabCount;		if (!inStatementIndentStack->empty())			previousIndent = inStatementIndentStack->back();		inStatementIndentStack->push_back(/*2*/ indentLength + previousIndent);		if (updateParenStack)			parenIndentStack->push_back(previousIndent);		return;	}	if (updateParenStack)		parenIndentStack->push_back(i + spaceTabCount);	inStatementIndent = i + nextNonWSChar + spaceTabCount;	if (i + nextNonWSChar < minIndent)		inStatementIndent = minIndent + spaceTabCount;	if (i + nextNonWSChar > maxInStatementIndent)		inStatementIndent =  indentLength * 2 + spaceTabCount;	if (!inStatementIndentStack->empty() &&	        inStatementIndent < inStatementIndentStack->back())		inStatementIndent = inStatementIndentStack->back();	if (isNonInStatementArray)		inStatementIndent = 0;	inStatementIndentStack->push_back(inStatementIndent);}/** * get distance to the next non-white sspace, non-comment character in the line. * if no such character exists, return the length remaining to the end of the line. */int ASBeautifier::getNextProgramCharDistance(const string &line, int i){	bool inComment = false;	int  remainingCharNum = line.length() - i;	int  charDistance;	char ch;	for (charDistance = 1; charDistance < remainingCharNum; charDistance++)	{		ch = line[i + charDistance];		if (inComment)		{			if (line.compare(i + charDistance, 2, "*/") == 0)			{				charDistance++;				inComment = false;			}			continue;		}		else if (isWhiteSpace(ch))			continue;		else if (ch == '/')		{			if (line.compare(i + charDistance, 2, "//") == 0)				return remainingCharNum;			else if (line.compare(i + charDistance, 2, "/*") == 0)			{				charDistance++;				inComment = true;			}		}		else			return charDistance;	}	return charDistance;}/** * check if a specific line position contains a header, out of several possible headers. * * @return    a pointer to the found header. if no header was found then return NULL. */const string *ASBeautifier::findHeader(const string &line, int i, const vector<const string*> &possibleHeaders, bool checkBoundry){	int maxHeaders = possibleHeaders.size();	// const string *header = NULL;	int p;	for (p = 0; p < maxHeaders; p++)	{		const string *header = possibleHeaders[p];		if (line.compare(i, header->length(), header->c_str()) == 0)		{			// check that this is a header and not a part of a longer word			// (e.g. not at its begining, not at its middle...)			int lineLength = line.length();			int headerEnd = i + header->length();			char startCh = (*header)[0];   // first char of header			char endCh = 0;                // char just after header			char prevCh = 0;               // char just before header			if (headerEnd < lineLength)			{				endCh = line[headerEnd];			}			if (i > 0)			{				prevCh = line[i-1];			}			if (!checkBoundry)			{				return header;			}			else if (prevCh != 0			         && isLegalNameChar(startCh)			         && isLegalNameChar(prevCh))			{				continue;			}			else if (headerEnd >= lineLength			         || !isLegalNameChar(startCh)			         || !isLegalNameChar(endCh))			{				return header;			}			else			{				continue;			}		}	}	return NULL;}/** * find the index number of a string element in a container of strings * * @return              the index number of element in the ocntainer. -1 if element not found. * @param container     a vector of strings. * @param element       the element to find . */int ASBeautifier::indexOf(vector<const string*> &container, const string *element){	vector<const string*>::const_iterator where;	where = find(container.begin(), container.end(), element);	if (where == container.end())		return -1;	else		return (int) (where - container.begin());}/** * trim removes the white space surrounding a line. * * @return          the trimmed line. * @param str       the line to trim. */string ASBeautifier::trim(const string &str){	int start = 0;	int end = str.length() - 1;	while (start < end && isWhiteSpace(str[start]))		start++;	while (start <= end && isWhiteSpace(str[end]))		end--;	string returnStr(str, start, end + 1 - start);	return returnStr;}/*** peek at the next unread character.** @return     	the next unread character.* @param line   the line to check.* @param i      the current char position on the line.*/char ASBeautifier::peekNextChar(const string &line, int i) const{	char ch = ' ';	size_t peekNum = line.find_first_not_of(" \t", i + 1);	if (peekNum == string::npos)		return ch;	ch = line[peekNum];	return ch;}}   // end namespace astyle

⌨️ 快捷键说明

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