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

📄 asbeautifier.cpp

📁 Artistic Style 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

		else if (foundAssignmentOp != NULL)
		{
			if (foundAssignmentOp->length() > 1)
            {
                outBuffer.append(foundAssignmentOp->substr(1));
                i += foundAssignmentOp->length() - 1;
            }

            if (!isInOperator && !isInTemplate)
            {
                registerInStatementIndent(line, i, spaceTabCount, 0, false);
                immediatelyPreviousAssignmentOp = foundAssignmentOp;
                isInStatement = true;
            }
		}

/*
        immediatelyPreviousAssignmentOp = NULL;
        bool isNonAssingmentOperator = false;
        for (int n = 0; n < nonAssignmentOperators.size(); n++)
            if (line.COMPARE(i, nonAssignmentOperators[n]->length(), *(nonAssignmentOperators[n])) == 0)
            {
                if (nonAssignmentOperators[n]->length() > 1)
                {
                    outBuffer.append(nonAssignmentOperators[n]->substr(1));
                    i += nonAssignmentOperators[n]->length() - 1;
                }
                isNonAssingmentOperator = true;
                break;
            }
        if (!isNonAssingmentOperator)
        {
            for (int a = 0; a < assignmentOperators.size(); a++)
                if (line.COMPARE(i, assignmentOperators[a]->length(), *(assignmentOperators[a])) == 0)
                {
                    if (assignmentOperators[a]->length() > 1)
                    {
                        outBuffer.append(assignmentOperators[a]->substr(1));
                        i += assignmentOperators[a]->length() - 1;
                    }

                    if (!isInOperator && !isInTemplate)
                    {
                        registerInStatementIndent(line, i, spaceTabCount, 0, false);
                        immediatelyPreviousAssignmentOp = assignmentOperators[a];
                        isInStatement = true;
                    }
                    break;
                }
        }
*/

        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.
     */
    //    cerr << endl << lineOpeningBlocksNum << " " <<  lineClosingBlocksNum << " " <<  previousLastLineHeader << endl;

    // indent #define lines with one less tab
    //if (isInDefine)
    //    tabCount -= defineTabCount-1;


    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
             && previousLastLineHeader != NULL
             && previousLastLineHeader != &AS_OPEN_BRACKET)
        tabCount -= 1; //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, string("define")) == 0)
            {
                if (!inStatementIndentStack->empty()
                        && inStatementIndentStack->back() > 0)
                {
                    defineTabCount = tabCount;
                }
                else
                {
                    defineTabCount = tabCount - 1;
                    tabCount--;
                }
            }
        }

        tabCount -= defineTabCount;
    }

    if (tabCount < 0)
        tabCount = 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 = 1;

    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();

    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 = 1;
    int ch;

    for (charDistance = 1; charDistance < remainingCharNum; charDistance++)
    {
        ch = line[i + charDistance];
        if (inComment)
        {
            if (line.COMPARE(i + charDistance, 2, AS_CLOSE_COMMENT) == 0)
            {
                charDistance++;
                inComment = false;
            }
            continue;
        }
        else if (isWhiteSpace(ch))
            continue;
        else if (ch == '/')
        {
            if (line.COMPARE(i + charDistance, 2, AS_OPEN_LINE_COMMENT) == 0)
                return remainingCharNum;
            else if (line.COMPARE(i + charDistance, 2, AS_OPEN_COMMENT) == 0)
            {
                charDistance++;
                inComment = true;
            }
        }
        else
            return charDistance;
    }

    return charDistance;
}


/**
 * check if a specific character can be used in a legal variable/method/class name
 *
 * @return          legality of the char.
 * @param ch        the character to be checked.
 */
bool ASBeautifier::isLegalNameChar(char ch) const
{
    return (isalnum(ch) //(ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9') ||
            || ch=='.' || ch=='_' || (!isCStyle && ch=='$') || (isCStyle && ch=='~'));
}


/**
 * 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++)
    {
        header = possibleHeaders[p];
		
        if (line.COMPARE(i, header->length(), *header) == 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))
			{
				return NULL;
			}
            else if (headerEnd >= lineLength 
					|| !isLegalNameChar(startCh) 
					|| !isLegalNameChar(endCh))
			{
                return header;
			}
            else
            {
				return NULL;
			}
        }
    }

    return NULL;
}


/**
 * check if a specific character can be used in a legal variable/method/class name
 *
 * @return          legality of the char.
 * @param ch        the character to be checked.
 */
bool ASBeautifier::isWhiteSpace(char ch) const
{
    return (ch == ' ' || ch == '\t');
}

/**
 * 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 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;
}

#ifdef USES_NAMESPACE
}
#endif

⌨️ 快捷键说明

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