Beispiel #1
0
/*
    Returns the recommended indent for the bottom line of yyProgram
    assuming that it starts in a C-style comment, a condition that is
    tested elsewhere.

    Essentially, we're trying to align against some text on the
    previous line.
*/
static int indentWhenBottomLineStartsInCComment()
{
    int k = yyLine->lastIndexOf( "/*" );
    if ( k == -1 ) {
        /*
          We found a normal text line in a comment. Align the
          bottom line with the text on this line.
        */
        return indentOfLine( *yyLine );
    } else {
        /*
          The C-style comment starts on this line. If there is
          text on the same line, align with it. Otherwise, align
          with the slash-aster plus a given offset.
        */
        int indent = columnForIndex( *yyLine, k );
        k += 2;
        while ( k < (int) yyLine->length() ) {
            if ( !(*yyLine)[k].isSpace() )
                return columnForIndex( *yyLine, k );
            k++;
        }
        return indent + ppCommentOffset;
    }
}
Beispiel #2
0
/*
    Returns the recommended indent for the bottom line of yyProgram,
    assuming it's a continuation line.

    We're trying to align the continuation line against some parenthesis
    or other bracked left opened on a previous line, or some interesting
    operator such as '='.
*/
static int indentForContinuationLine()
{
    int braceDepth = 0;
    int delimDepth = 0;

    bool leftBraceFollowed = *yyLeftBraceFollows;

    for ( int i = 0; i < SmallRoof; i++ ) {
        int hook = -1;

        int j = yyLine->length();
        while ( j > 0 && hook < 0 ) {
            j--;
            QChar ch = (*yyLine)[j];

            switch ( ch.unicode() ) {
            case ')':
            case ']':
                delimDepth++;
                break;
            case '}':
                braceDepth++;
                break;
            case '(':
            case '[':
                delimDepth--;
                /*
                    An unclosed delimiter is a good place to align at,
                    at least for some styles (including Trolltech's).
                */
                if ( delimDepth == -1 )
                    hook = j;
                break;
            case '{':
                braceDepth--;
                /*
                    A left brace followed by other stuff on the same
                    line is typically for an enum or an initializer.
                    Such a brace must be treated just like the other
                    delimiters.
                */
                if ( braceDepth == -1 ) {
                    if ( j < (int) yyLine->length() - 1 ) {
                        hook = j;
                    } else {
                        return 0; // shouldn't happen
                    }
                }
                break;
            case '=':
                /*
                    An equal sign is a very natural alignment hook
                    because it's usually the operator with the lowest
                    precedence in statements it appears in. Case in
                    point:

                        int x = 1 +
                                2;

                    However, we have to beware of constructs such as
                    default arguments and explicit enum constant
                    values:

                        void foo( int x = 0,
                                  int y = 0 );

                    And not

                        void foo( int x = 0,
                                        int y = 0 );

                    These constructs are caracterized by a ',' at the
                    end of the unfinished lines or by unbalanced
                    parentheses.
                */
                if ( QString("!=<>").indexOf((*yyLine)[j - 1]) == -1 &&
                     (*yyLine)[j + 1] != '=' ) {
                    if ( braceDepth == 0 && delimDepth == 0 &&
                         j < (int) yyLine->length() - 1 &&
                         !yyLine->endsWith(",") &&
                         (yyLine->contains('(') == yyLine->contains(')')) )
                        hook = j;
                }
            }
        }

        if ( hook >= 0 ) {
            /*
                Yes, we have a delimiter or an operator to align
                against! We don't really align against it, but rather
                against the following token, if any. In this example,
                the following token is "11":

                    int x = ( 11 +
                              2 );

                If there is no such token, we use a continuation indent:

                    static QRegExp foo( QString(
                            "foo foo foo foo foo foo foo foo foo") );
            */
            hook++;
            while ( hook < (int) yyLine->length() ) {
                if ( !(*yyLine)[hook].isSpace() )
                    return columnForIndex( *yyLine, hook );
                hook++;
            }
            return indentOfLine( *yyLine ) + ppContinuationIndentSize;
        }

        if ( braceDepth != 0 )
            break;

        /*
            The line's delimiters are balanced. It looks like a
            continuation line or something.
        */
        if ( delimDepth == 0 ) {
            if ( leftBraceFollowed ) {
                /*
                    We have

                        int main()
                        {

                    or

                        Bar::Bar()
                            : Foo( x )
                        {

                    The "{" should be flush left.
                */
                if ( !isContinuationLine() )
                    return indentOfLine( *yyLine );
            } else if ( isContinuationLine() || yyLine->endsWith(",") ) {
                /*
                    We have

                        x = a +
                            b +
                            c;

                    or

                        int t[] = {
                            1, 2, 3,
                            4, 5, 6

                    The "c;" should fall right under the "b +", and the
                    "4, 5, 6" right under the "1, 2, 3,".
                */
                return indentOfLine( *yyLine );
            } else {
                /*
                    We have

                        stream << 1 +
                                2;

                    We could, but we don't, try to analyze which
                    operator has precedence over which and so on, to
                    obtain the excellent result

                        stream << 1 +
                                  2;

                    We do have a special trick above for the assignment
                    operator above, though.
                */
                return indentOfLine( *yyLine ) + ppContinuationIndentSize;
            }
        }

        if ( !readLine() )
            break;
    }
    return 0;
}
Beispiel #3
0
/*
    Returns the indentation size of string t.
*/
int indentOfLine( const QString& t )
{
    return columnForIndex( t, t.indexOf(firstNonWhiteSpace(t)) );
}
QString CppToQsConverter::convertedCode( Tree *qsTree, const QString& code,
					 const QSet<QString>& classesWithNoQ )
{
    QString result;
    QStringList program;
    QStringList comments;
    int programWidth = 0;

    QStringList originalLines = code.split("\n");
    QStringList::ConstIterator ol = originalLines.begin();
    while ( ol != originalLines.end() ) {
	QString code = (*ol).trimmed();
	QString comment;

	int slashSlash = code.indexOf( "//" );
	if ( slashSlash != -1 ) {
	    comment = code.mid( slashSlash );
	    code.truncate( slashSlash );
	    code = code.trimmed();
	}

	code = convertCodeLine( qsTree, program, code, classesWithNoQ );
	program.append( code );

	comment = convertComment( qsTree, comment, classesWithNoQ );
	comments.append( comment );

	int n = indentForBottomLine( program, QChar::Null );
	for ( int i = 0; i < n; i++ )
	    program.last().prepend( " " );

	int width = columnForIndex( program.last(), program.last().length() );
	if ( !comment.isEmpty() && width > programWidth )
	    programWidth = width;
	++ol;
    }

    programWidth = ( (programWidth + (tabSize - 1) + 2) / tabSize ) * tabSize;

    QStringList::ConstIterator p = program.begin();
    QStringList::ConstIterator c = comments.begin();
    while ( c != comments.end() ) {
	if ( c != comments.begin() )
	    result += "\n";

	if ( (*p).trimmed().isEmpty() ) {
	    if ( !(*c).isEmpty() )
		result += *p;
	} else {
	    result += *p;
	    if ( !(*c).isEmpty() ) {
		int i = columnForIndex( *p, (*p).length() );
		while ( i++ < programWidth )
		    result += " ";
	    }
	}
	result += *c;
	++p;
	++c;
    }
    return result;
}