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

📄 asbeautifier.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if ( ! isInComment && ! suppressCurrentIndent )
    {
        TRACE( ENTRY, "not in comment, indent not suppressed - memorizing leading WS and trimming line" );
        leadingWhiteSpaces = 0;
        while ( leadingWhiteSpaces < originalLine.size() && isspace(originalLine[leadingWhiteSpaces]) )
        {
            leadingWhiteSpaces++;
        }
        line = trim(originalLine);
        TRACE( EXIT, "line: '" << line << "'" );
    }
    else
    {
        TRACE( ENTRY, "in comment - trimming away already registered leading WS (?)" );
        unsigned trimSize;
        for (trimSize=0;
             trimSize < originalLine.size() && trimSize < leadingWhiteSpaces && isspace(originalLine[trimSize]);
             trimSize++)
        {
            // EMPTY
        }
        line = originalLine.substr(trimSize);
        TRACE( EXIT, "line: '" << line << "'" );
    }

    // handle empty lines
    if (line.size() == 0)
    {
        TRACE( ENTRY, "line is empty" );
        if (emptyLineIndent)
        {
            TRACE( INFO, "as emptyLineIndent is set, WS is added (preLineWS(" << prevFinalLineSpaceTabCount << ", " << prevFinalLineTabCount << "))" );
            TRACE( EXIT, "'" << preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount) << "'" );
            return preLineWS(prevFinalLineSpaceTabCount, prevFinalLineTabCount);
        }
        else
        {
            TRACE( EXIT, "returning empty line" );
            return line;
        }
    }

    // handle preprocessor commands
    if ( ( sourceStyle != STYLE_JAVA ) && ! isInComment && ( line[0] == '#' || backslashEndsPrevLine ) )
    {
        if (line[0] == '#')
        {
            TRACE( INFO, "encountered preprocessor statement" );
            // TODO: Haven't looked into the following block yet.
            string preproc = trim( line.substr(1) );

            // When finding a multi-lined #define statement, the original beautifier...
            // 1. sets its isInDefineDefinition flag,
            // 2. clones a new beautifier that will be used for the actual indentation
            //    of the #define. This clone is put into the activeBeautifierStack in order
            //    to be called for the actual indentation.
            // The original beautifier will have isInDefineDefinition = true, isInDefine = false
            // The cloned beautifier will have   isInDefineDefinition = true, isInDefine = true
            if ( preprocessorIndent && BEGINS_WITH(preproc, "define", 6) &&  line[line.size() - 1] == '\\' )
            {
                TRACE( INFO, "...which is a multi-line #define" );

                if ( !isInDefineDefinition )
                {
                    TRACE( INFO, "isInDefineDefinition == false" );
                    ASBeautifier *defineBeautifier;

                    // this is the original beautifier
                    isInDefineDefinition = true;

                    // push a new beautifier into the active stack;
                    // this breautifier will be used for the indentation of this define
                    defineBeautifier = new ASBeautifier(*this);
                    //defineBeautifier->init();
                    //defineBeautifier->isInDefineDefinition = true;
                    //defineBeautifier->beautify("");
                    activeBeautifierStack->push_back(defineBeautifier);
                }
                else
                {
                    TRACE( INFO, "isInDefineDefinition == true" );
                    // the is the cloned beautifier that is in charge of indenting the #define.
                    isInDefine = true;
                }

            }
            else if (BEGINS_WITH(preproc, "if", 2))
            {
                TRACE( INFO, "processing #if / #ifdef / #ifndef" );
                // push a new beautifier into the stack
                waitingBeautifierStackLengthStack->push_back(waitingBeautifierStack->size());
                activeBeautifierStackLengthStack->push_back(activeBeautifierStack->size());
                waitingBeautifierStack->push_back(new ASBeautifier(*this));
            }
            else if (BEGINS_WITH(preproc, "else", 4))
            {
                TRACE( INFO, "processing #else" );
                if (!waitingBeautifierStack->empty())
                {
                    // MOVE current waiting beautifier to active stack.
                    activeBeautifierStack->push_back(waitingBeautifierStack->back());
                    waitingBeautifierStack->pop_back();
                }
            }
            else if (BEGINS_WITH(preproc, "elif", 4))
            {
                TRACE( INFO, "processing #elif" );
                if (!waitingBeautifierStack->empty())
                {
                    // append a COPY current waiting beautifier to active stack, WITHOUT deleting the original.
                    activeBeautifierStack->push_back( new ASBeautifier( *(waitingBeautifierStack->back()) ) );
                }
            } // BEGINS_WITH(preproc, "elif", 4))
            else if (BEGINS_WITH(preproc, "endif", 5))
            {
                TRACE( INFO, "processing #endif" );
                unsigned stackLength;
                ASBeautifier *beautifier;

                if ( ! waitingBeautifierStackLengthStack->empty() )
                {
                    TRACE( INFO, "clearing waitingBeautifierStack" );
                    stackLength = waitingBeautifierStackLengthStack->back();
                    waitingBeautifierStackLengthStack->pop_back();
                    // FIXME: what about the LengthStack?
                    while ( waitingBeautifierStack->size() > stackLength )
                    {
                        beautifier = waitingBeautifierStack->back();
                        waitingBeautifierStack->pop_back();
                        delete beautifier;
                    }
                }

                if ( ! activeBeautifierStackLengthStack->empty() )
                {
                    TRACE( INFO, "clearing activeBeautifierStack" );
                    stackLength = activeBeautifierStackLengthStack->back();
                    activeBeautifierStackLengthStack->pop_back();
                    // FIXME: what about the LengthStack?
                    while ( activeBeautifierStack->size() > stackLength )
                    {
                        beautifier = activeBeautifierStack->back();
                        activeBeautifierStack->pop_back();
                        delete beautifier;
                    }
                }

            } // BEGINS_WITH(preproc, "endif", 5))

        } // line[0] == '#'

        // check if the last char of current line is a backslash
        if ( line[ line.size() - 1 ] == '\\' )
        {
            TRACE( INFO, "current line ends in '\\'" );
            backslashEndsPrevLine = true;
        }
        else
        {
            TRACE( INFO, "current line does not end in '\\'" );
            backslashEndsPrevLine = false;
        }

        // check if this line ends a multi-line #define
        // if so, use the #define's cloned beautifier for the line's indentation
        // and then remove it from the active beautifier stack and delete it.
        if ( ! backslashEndsPrevLine && isInDefineDefinition && ! isInDefine )
        {
            TRACE( INFO, "last line of multi-line define" );
            string beautifiedLine;
            ASBeautifier *defineBeautifier;

            isInDefineDefinition = false;
            defineBeautifier = activeBeautifierStack->back();
            activeBeautifierStack->pop_back();

            beautifiedLine = defineBeautifier->beautify(line);
            delete defineBeautifier;
            return beautifiedLine;
        }

        // unless this is a multi-line #define, return this precompiler line as is.
        if ( ! isInDefine && ! isInDefineDefinition )
        {
            TRACE( INFO, "not a multi-line define - return as-is" );
            return originalLine;
        }

    } // end of preprocessor handling

    // if there exists any worker beautifier in the activeBeautifierStack,
    // then use it instead of this to indent the current line.
    // TODO: Check whether one of the two checks on activeBeautifierStack is redundant.
    if ( ! isInDefine && activeBeautifierStack != NULL && ! activeBeautifierStack->empty() )
    {
        TRACE( INFO, "delegating to on-stack beautifier (IS THIS EVER REACHED?)" );
        return activeBeautifierStack->back()->beautify( line );
    }

    // calculate preliminary indentation based on data from past lines
    if ( ! inStatementIndentStack->empty() )
    {
        TRACE( INFO, "getting preliminary indentation from inStatementIndentStack:" << inStatementIndentStack->back() );
        spaceTabCount = inStatementIndentStack->back();
    }

    for ( i = 0; i < headerStackSize; ++i )
    {
        isInClass = false;

        if ( blockIndent || ( ! ( i > 0 && (*headerStack)[i-1] != &AS_OPEN_BRACKET
                                        && (*headerStack)[i]   == &AS_OPEN_BRACKET ) ) )
        {
            TRACE( INFO, "reached block, adding indent" );
            ++tabCount;
        }

        if ( ( sourceStyle != STYLE_JAVA ) && ! namespaceIndent      && i > 0
                                           && (*headerStack)[i-1]    == &AS_NAMESPACE
                                           && (*headerStack)[i]      == &AS_OPEN_BRACKET )
        {
            TRACE( INFO, "reached namespace but namespaceIndent == false, removing indent" );
            --tabCount;
        }

        if ( ( sourceStyle != STYLE_JAVA ) && i > 0
                                           && (*headerStack)[i-1] == &AS_CLASS
                                           && (*headerStack)[i]   == &AS_OPEN_BRACKET )
        {
            TRACE( INFO, "reached class..." );
            if ( classIndent )
            {
                TRACE( INFO, "...adding (class) indent" );
                ++tabCount;
            }
            isInClass = true;
        }

        // is the switchIndent option is on, indent switch statements an additional indent.
        // TODO: ELSE if? Shouldn't this be just another IF? And i checked > 0 as above?
        else if ( switchIndent && i > 1
                               && (*headerStack)[i-1] == &AS_SWITCH
                               && (*headerStack)[i]   == &AS_OPEN_BRACKET )
        {
            TRACE( INFO, "reached switch block, assing indent" );
            ++tabCount;
            isInSwitch = true;
        }

    } // for ( i = 0; i < headerStackSize; ++i )

    if ( ! lineStartsInComment && ( sourceStyle != STYLE_JAVA )
                               && isInClass
                               && classIndent
                               && headerStackSize >= 2
                               && (*headerStack)[headerStackSize-2] == &AS_CLASS
                               && (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
                               && line[0] == '}' )
    {
        TRACE( INFO, "reached end of class (?), removing indent" );
        --tabCount;
    }
    else if ( ! lineStartsInComment && isInSwitch
                                    && switchIndent
                                    && headerStackSize >= 2
                                    && (*headerStack)[headerStackSize-2] == &AS_SWITCH
                                    && (*headerStack)[headerStackSize-1] == &AS_OPEN_BRACKET
                                    && line[0] == '}' )
    {
        TRACE( INFO, "reached end of switch block, removing indent" );
        --tabCount;
    }

    if (isInClassHeader)
    {
        TRACE( INFO, "isInClassHeader - adding two indents" );
        isInClassHeaderTab = true;
        tabCount += 2;
    }

    if (isInConditional)
    {
        TRACE( INFO, "isInConditional - removing indent" );
        --tabCount;
    } // end of indent adjust


    // parse characters in the current line.
    for ( i = 0; i < line.size(); ++i )
    {
        tempCh = line[i];
        prevCh = ch;
        ch = tempCh;

        outBuffer.append(1, ch);

        TRACE( INFO, "next char: '" << ch << "'." );
        if (isWhiteSpace(ch))
        {
            TRACE( INFO, "skipping whitespace" );
            continue;
        }

        // handle special characters (i.e. backslash + character such as \n, \t, ...)
        if (isSpecialChar)
        {
            TRACE( INFO, "skipping special (escaped) char" );
            isSpecialChar = false;
            continue;
        }
        if ( ! ( isInComment || isInLineComment ) && ( line.substr(i, 2) == "\\\\" ) )
        {
            TRACE( INFO, "encountered '\\', appending to outBuffer" );
            outBuffer.append(1, '\\');
            ++i;
            continue;
        }
        if ( ! ( isInComment || isInLineComment ) && ch=='\\' )
        {
            TRACE( INFO, "encountered '\', next char is special (escaped)" );
            isSpecialChar = true;
            continue;
        }

        // handle quotes (such as 'x' and "Hello Dolly")
        if ( ! ( isInComment || isInLineComment ) && ( ch=='"' || ch=='\'' ) )
        {
            TRACE( INFO, "encountered quote (' or \")" );
            if ( ! isInQuote )
            {
                TRACE( INFO, "this is the BEGINNING of a quote" );
                quoteChar = ch;
                isInQuote = true;
            }
            else if (quoteChar == ch)
            {
                TRACE( INFO, "this is the END of a quote" );
                isInQuote = false;
                isInStatement = true;
                continue;
            }
        }

⌨️ 快捷键说明

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