📄 asbeautifier.cpp
字号:
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 + -