diff options
author | Roberto Raggi <[email protected]> | 2010-08-10 10:49:40 +0200 |
---|---|---|
committer | Roberto Raggi <[email protected]> | 2010-08-10 10:50:00 +0200 |
commit | da5d6d7db275066be85e56a8d2892162a099e98b (patch) | |
tree | 9c64cfc2b87cc1060b7cfef5e3772f028fafe783 | |
parent | 9df9695a7fdab213f0f564f8fe4cd74c196465fc (diff) |
Get rid of the old deprecated indenter.
-rw-r--r-- | src/plugins/cppeditor/cppeditor.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditor.pro | 1 | ||||
-rw-r--r-- | src/plugins/fakevim/fakevim.pro | 1 | ||||
-rw-r--r-- | src/plugins/fakevim/fakevimplugin.cpp | 1 | ||||
-rw-r--r-- | src/plugins/qmljseditor/qmljseditor.cpp | 1 | ||||
-rw-r--r-- | src/plugins/qmljseditor/qmljseditor_dependencies.pri | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/textblockiterator.cpp | 93 | ||||
-rw-r--r-- | src/plugins/texteditor/textblockiterator.h | 68 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.pro | 2 | ||||
-rw-r--r-- | src/shared/indenter/README | 9 | ||||
-rw-r--r-- | src/shared/indenter/constants.cpp | 64 | ||||
-rw-r--r-- | src/shared/indenter/indenter.cpp | 1125 | ||||
-rw-r--r-- | src/shared/indenter/indenter.h | 147 | ||||
-rw-r--r-- | src/shared/indenter/indenter.pri | 4 | ||||
-rw-r--r-- | src/shared/indenter/test/main.cpp | 178 | ||||
-rw-r--r-- | src/shared/indenter/test/test.pro | 10 |
16 files changed, 0 insertions, 1707 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index b7e95c19a2a..2f62d8e818b 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -73,8 +73,6 @@ #include <texteditor/basetextdocument.h> #include <texteditor/fontsettings.h> #include <texteditor/texteditorconstants.h> -#include <texteditor/textblockiterator.h> -#include <indenter.h> #include <QtCore/QDebug> #include <QtCore/QTime> diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro index 6707b2d3e6a..be74639661a 100644 --- a/src/plugins/cppeditor/cppeditor.pro +++ b/src/plugins/cppeditor/cppeditor.pro @@ -3,7 +3,6 @@ TARGET = CppEditor DEFINES += CPPEDITOR_LIBRARY include(../../qtcreatorplugin.pri) include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri) -include($$IDE_SOURCE_TREE/src/shared/indenter/indenter.pri) include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus.pri) include(cppeditor_dependencies.pri) HEADERS += cppplugin.h \ diff --git a/src/plugins/fakevim/fakevim.pro b/src/plugins/fakevim/fakevim.pro index 5a4df06c237..adffef024e4 100644 --- a/src/plugins/fakevim/fakevim.pro +++ b/src/plugins/fakevim/fakevim.pro @@ -9,7 +9,6 @@ include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/texteditor/texteditor.pri) include(../../plugins/cppeditor/cppeditor.pri) include(../../plugins/find/find.pri) -include(../../shared/indenter/indenter.pri) # DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII QT += gui diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index b57294c9f12..8883ada1fb8 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -57,7 +57,6 @@ #include <texteditor/texteditorconstants.h> #include <texteditor/tabsettings.h> #include <texteditor/texteditorsettings.h> -#include <texteditor/textblockiterator.h> #include <find/findplugin.h> #include <find/textfindconstants.h> diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index dd68aff7b52..bf01cd03812 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -56,7 +56,6 @@ #include <extensionsystem/pluginmanager.h> #include <texteditor/basetextdocument.h> #include <texteditor/fontsettings.h> -#include <texteditor/textblockiterator.h> #include <texteditor/texteditorconstants.h> #include <texteditor/texteditorsettings.h> #include <texteditor/syntaxhighlighter.h> diff --git a/src/plugins/qmljseditor/qmljseditor_dependencies.pri b/src/plugins/qmljseditor/qmljseditor_dependencies.pri index c478dc233f9..c0d9f426825 100644 --- a/src/plugins/qmljseditor/qmljseditor_dependencies.pri +++ b/src/plugins/qmljseditor/qmljseditor_dependencies.pri @@ -1,6 +1,5 @@ include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/texteditor/texteditor.pri) include(../../plugins/projectexplorer/projectexplorer.pri) -include(../../shared/indenter/indenter.pri) include(../../libs/qmljs/qmljs.pri) include(../../libs/utils/utils.pri) diff --git a/src/plugins/texteditor/textblockiterator.cpp b/src/plugins/texteditor/textblockiterator.cpp deleted file mode 100644 index 71b0a052a52..00000000000 --- a/src/plugins/texteditor/textblockiterator.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation ([email protected]) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "textblockiterator.h" - -#include <QtGui/QTextDocument> - -using namespace TextEditor; - -TextBlockIterator::TextBlockIterator() - : m_document(0), - m_initialized(false) -{ } - -TextBlockIterator::TextBlockIterator(const QTextBlock &block) - : m_document(block.document()), - m_block(block), - m_initialized(false) -{ } - -bool TextBlockIterator::equals(const TextBlockIterator &other) const -{ - if (m_document != other.m_document) - return false; - return m_block == other.m_block; -} - -QString TextBlockIterator::operator*() const -{ - if (! m_initialized) - read(); - return m_text; -} - -void TextBlockIterator::read() const -{ - m_initialized = true; - m_text = m_block.text(); -} - -TextBlockIterator &TextBlockIterator::operator++() -{ - m_initialized = false; - m_block = m_block.next(); - return *this; -} - -TextBlockIterator &TextBlockIterator::operator--() -{ - m_initialized = false; - m_block = m_block.previous(); - return *this; -} - -TextBlockIterator TextBlockIterator::operator++(int) -{ - TextBlockIterator prev; - ++*this; - return prev; -} - -TextBlockIterator TextBlockIterator::operator--(int) -{ - TextBlockIterator prev; - --*this; - return prev; -} diff --git a/src/plugins/texteditor/textblockiterator.h b/src/plugins/texteditor/textblockiterator.h deleted file mode 100644 index ae6d02a2293..00000000000 --- a/src/plugins/texteditor/textblockiterator.h +++ /dev/null @@ -1,68 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation ([email protected]) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef TEXTBLOCKITERATOR_H -#define TEXTBLOCKITERATOR_H - -#include "texteditor_global.h" - -#include <QtGui/QTextBlock> - -namespace TextEditor { - -/* Iterator for the text blocks of a document. */ -class TEXTEDITOR_EXPORT TextBlockIterator { -public: - TextBlockIterator(); - TextBlockIterator(const QTextBlock &block); - - bool equals(const TextBlockIterator &o) const; - - QString operator*() const; - TextBlockIterator &operator++(); - TextBlockIterator &operator--(); - TextBlockIterator operator++(int); - TextBlockIterator operator--(int); - -private: - void read() const; - -private: - const QTextDocument *m_document; - QTextBlock m_block; - mutable QString m_text; - mutable bool m_initialized; -}; - -inline bool operator==(const TextBlockIterator &i1, const TextBlockIterator &i2) { return i1.equals(i2); } -inline bool operator!=(const TextBlockIterator &i1, const TextBlockIterator &i2) { return !i1.equals(i2); } - -} // namespace TextEditor - -#endif // TEXTBLOCKITERATOR_H diff --git a/src/plugins/texteditor/texteditor.pro b/src/plugins/texteditor/texteditor.pro index df3e8f380de..a140d718b96 100644 --- a/src/plugins/texteditor/texteditor.pro +++ b/src/plugins/texteditor/texteditor.pro @@ -26,7 +26,6 @@ SOURCES += texteditorplugin.cpp \ displaysettings.cpp \ displaysettingspage.cpp \ fontsettings.cpp \ - textblockiterator.cpp \ linenumberfilter.cpp \ basetextmark.cpp \ findinfiles.cpp \ @@ -90,7 +89,6 @@ HEADERS += texteditorplugin.h \ displaysettings.h \ displaysettingspage.h \ fontsettings.h \ - textblockiterator.h \ itexteditable.h \ itexteditor.h \ linenumberfilter.h \ diff --git a/src/shared/indenter/README b/src/shared/indenter/README deleted file mode 100644 index deaac0168b9..00000000000 --- a/src/shared/indenter/README +++ /dev/null @@ -1,9 +0,0 @@ -C++ / Qt Script indenter based on: - -research/qsa/quickport/src/neweditor/yyindent.cpp - -Known issues: -- Using an indentation different from 4 makes it goof up. - -History: -- 070510: Split off the test application and made it work with Qt 4. diff --git a/src/shared/indenter/constants.cpp b/src/shared/indenter/constants.cpp deleted file mode 100644 index 8b5f0383c57..00000000000 --- a/src/shared/indenter/constants.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation ([email protected]) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "indenter.h" - -using namespace SharedTools::IndenterInternal; - -// --- Constants -Constants::Constants() : - m_slashAster(QLatin1String("/*")), - m_asterSlash(QLatin1String("*/")), - m_slashSlash(QLatin1String("//")), - m_else(QLatin1String("else")), - m_qobject(QLatin1String("Q_OBJECT")), - m_operators(QLatin1String("!=<>")), - m_bracesSemicolon(QLatin1String("{};")), - m_3dots(QLatin1String("...")), - - m_literal(QLatin1String("([\"'])(?:\\\\.|[^\\\\])*\\1")), - m_label(QLatin1String("^\\s*((?:case\\b([^:]|::)+|[a-zA-Z_0-9]+)(?:\\s+slots|\\s+Q_SLOTS)?:)(?!:)")), - m_inlineCComment(QLatin1String("/\\*.*\\*/")), - m_braceX(QLatin1String("^\\s*\\}\\s*(?:else|catch)\\b")), - m_iflikeKeyword(QLatin1String("\\b(?:catch|do|for|if|while|foreach)\\b")), - m_caseLabel(QLatin1String("^\\s*(?:case\\b(?:[^:]|::)+" - "|(?:public|protected|private|signals|Q_SIGNALS|default)(?:\\s+slots|\\s+Q_SLOTS)?\\s*" - "):")), - m_templateFunc(QLatin1String("template<.*>")) -{ - m_literal.setMinimal(true); - m_inlineCComment.setMinimal(true); - Q_ASSERT(m_literal.isValid()); - Q_ASSERT(m_label.isValid()); - Q_ASSERT(m_inlineCComment.isValid()); - Q_ASSERT(m_braceX.isValid()); - Q_ASSERT(m_iflikeKeyword.isValid()); - Q_ASSERT(m_caseLabel.isValid()); - Q_ASSERT(m_templateFunc.isValid()); -} diff --git a/src/shared/indenter/indenter.cpp b/src/shared/indenter/indenter.cpp deleted file mode 100644 index f631505c60a..00000000000 --- a/src/shared/indenter/indenter.cpp +++ /dev/null @@ -1,1125 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation ([email protected]) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -/* - This file is a self-contained interactive indenter for C++ and Qt - Script. - - The general problem of indenting a C++ program is ill posed. On the - one hand, an indenter has to analyze programs written in a - free-form formal language that is best described in terms of - tokens, not characters, not lines. On the other hand, indentation - applies to lines and white space characters matter, and otherwise - the programs to indent are formally invalid in general, as they are - being edited. - - The approach taken here works line by line. We receive a program - consisting of N lines or more, and we want to compute the - indentation appropriate for the Nth line. Lines beyond the Nth - lines are of no concern to us, so for simplicity we pretend the - program has exactly N lines and we call the Nth line the "bottom - line". Typically, we have to indent the bottom line when it's still - empty, so we concentrate our analysis on the N - 1 lines that - precede. - - By inspecting the (N - 1)-th line, the (N - 2)-th line, ... - backwards, we determine the kind of the bottom line and indent it - accordingly. - - * The bottom line is a comment line. See - bottomLineStartsInCComment() and - indentWhenBottomLineStartsInCComment(). - * The bottom line is a continuation line. See isContinuationLine() - and indentForContinuationLine(). - * The bottom line is a standalone line. See - indentForStandaloneLine(). - - Certain tokens that influence the indentation, notably braces, are - looked for in the lines. This is done by simple string comparison, - without a real tokenizer. Confusing constructs such as comments and - string literals are removed beforehand. -*/ - -#include "indenter.h" - -namespace SharedTools { - -/* qmake ignore Q_OBJECT */ - -/* - The indenter avoids getting stuck in almost infinite loops by - imposing arbitrary limits on the number of lines it analyzes when - looking for a construct. - - For example, the indenter never considers more than BigRoof lines - backwards when looking for the start of a C-style comment. -*/ -namespace { - enum { SmallRoof = 40, BigRoof = 400 }; - -/* - The indenter supports a few parameters: - - * ppHardwareTabSize is the size of a '\t' in your favorite editor. - * ppIndentSize is the size of an indentation, or software tab - size. - * ppContinuationIndentSize is the extra indent for a continuation - line, when there is nothing to align against on the previous - line. - * ppCommentOffset is the indentation within a C-style comment, - when it cannot be picked up. - * ppIndentBraces will indent braces flush with an indented code - block. - * ppDoubleIndentBlocks do double indent of blocks so as together - with ppIndentBraces enabled it form some sort of GNU indenting style -*/ - - - enum { ppCommentOffset = 1 }; -} - -Indenter::Indenter() : - ppHardwareTabSize(8), - ppIndentSize(4), - ppIndentBraces(false), - ppContinuationIndentSize(8), - ppDoubleIndentBlocks(false), - yyLinizerState(new LinizerState), - yyLine(0), - yyBraceDepth(0), - yyLeftBraceFollows(0) -{ -} - -Indenter::~Indenter() -{ - delete yyLinizerState; -} - -Indenter &Indenter::instance() -{ - static Indenter rc; - return rc; -} - -void Indenter::setIndentSize(int size) -{ - ppIndentSize = size; - ppContinuationIndentSize = 2 * size; -} - -void Indenter::setTabSize(int size) -{ - ppHardwareTabSize = size; -} - -void Indenter::setIndentBraces(bool indent) -{ - ppIndentBraces = indent; -} - -void Indenter::setDoubleIndentBlocks(bool indent) -{ - ppDoubleIndentBlocks = indent; -} - -/* - Returns the first non-space character in the string t, or - QChar::null if the string is made only of white space. -*/ -QChar Indenter::firstNonWhiteSpace(const QString &t) -{ - if (const int len = t.length()) - for (int i = 0; i < len; i++) - if (!t[i].isSpace()) - return t[i]; - return QChar::Null; -} - -/* - Returns true if string t is made only of white space; otherwise - returns false. -*/ -bool Indenter::isOnlyWhiteSpace(const QString &t) -{ - return t.isEmpty() || firstNonWhiteSpace(t).isNull(); -} - -/* - Assuming string t is a line, returns the column number of a given - index. Column numbers and index are identical for strings that don't - contain '\t's. -*/ -int Indenter::columnForIndex(const QString &t, int index) const -{ - int col = 0; - if (index > t.length()) - index = t.length(); - - const QChar tab = QLatin1Char('\t'); - - for (int i = 0; i < index; i++) { - if (t[i] == tab) { - col = ((col / ppHardwareTabSize) + 1) * ppHardwareTabSize; - } else { - col++; - } - } - return col; -} - -/* - Returns the indentation size of string t. -*/ -int Indenter::indentOfLine(const QString &t) const -{ - return columnForIndex(t, t.indexOf(firstNonWhiteSpace(t))); -} - -/* - Replaces t[k] by ch, unless t[k] is '\t'. Tab characters are better - left alone since they break the "index equals column" rule. No - provisions are taken against '\n' or '\r', which shouldn't occur in - t anyway. -*/ -static inline void eraseChar(QString &t, int k, QChar ch) -{ - if (t[k] != QLatin1Char('\t')) - t[k] = ch; -} - -/* - Removes some nefast constructs from a code line and returns the - resulting line. -*/ -QString Indenter::trimmedCodeLine(const QString &t) -{ - QString trimmed = t; - int k; - - const QChar capitalX = QLatin1Char('X'); - const QChar blank = QLatin1Char(' '); - const QChar colon = QLatin1Char(':'); - const QChar semicolon = QLatin1Char(';'); - /* - Replace character and string literals by X's, since they may - contain confusing characters (such as '{' and ';'). "Hello!" is - replaced by XXXXXXXX. The literals are rigourously of the same - length before and after; otherwise, we would break alignment of - continuation lines. - */ - k = 0; - while ((k = m_constants.m_literal.indexIn(trimmed), k) != -1) { - const int matchedLength = m_constants.m_literal.matchedLength(); - for (int i = 0; i < matchedLength ; i++) - eraseChar(trimmed, k + i, capitalX); - k += matchedLength; - } - - /* - Replace inline C-style comments by spaces. Other comments are - handled elsewhere. - */ - k = 0; - while ((k = m_constants.m_inlineCComment.indexIn(trimmed, k)) != -1) { - const int matchedLength = m_constants.m_inlineCComment.matchedLength(); - for (int i = 0; i < matchedLength; i++) - eraseChar(trimmed, k + i, blank); - k += matchedLength; - } - - /* - Replace goto and switch labels by whitespace, but be careful - with this case: - - foo1: bar1; - bar2; - */ - while (trimmed.lastIndexOf(colon) != -1 && m_constants.m_label.indexIn(trimmed) != -1) { - const QString cap1 = m_constants.m_label.cap(1); - const int pos1 = m_constants.m_label.pos(1); - int stop = cap1.length(); - - if (pos1 + stop < trimmed.length() && ppIndentSize < stop) - stop = ppIndentSize; - - int i = 0; - while (i < stop) { - eraseChar(trimmed, pos1 + i, blank ); - i++; - } - while (i < cap1.length()) { - eraseChar(trimmed, pos1 + i,semicolon); - i++; - } - } - - /* - Remove C++-style comments. - */ - k = trimmed.indexOf(m_constants.m_slashSlash); - if (k != -1) - trimmed.truncate(k); - - return trimmed; -} - -/* - Returns '(' if the last parenthesis is opening, ')' if it is - closing, and QChar::null if there are no parentheses in t. -*/ -static inline QChar lastParen(const QString &t) -{ - - const QChar opening = QLatin1Char('('); - const QChar closing = QLatin1Char(')'); - - - int i = t.length(); - while (i > 0) { - i--; - const QChar c = t[i]; - if (c == opening || c == closing) - return c; - } - return QChar::Null; -} - -/* - Returns true if typedIn the same as okayCh or is null; otherwise - returns false. -*/ -static inline bool okay(QChar typedIn, QChar okayCh) -{ - return typedIn == QChar::Null || typedIn == okayCh; -} - - -/* - Saves and restores the state of the global linizer. This enables - backtracking. -*/ -#define YY_SAVE() \ -LinizerState savedState = *yyLinizerState -#define YY_RESTORE() \ - *yyLinizerState = savedState - - /* - Advances to the previous line in yyProgram and update yyLine - accordingly. yyLine is cleaned from comments and other damageable - constructs. Empty lines are skipped. -*/ - bool Indenter::readLine() - { - int k; - - const QChar openingBrace = QLatin1Char('{'); - const QChar closingBrace = QLatin1Char('}'); - const QChar blank = QLatin1Char(' '); - const QChar hash = QLatin1Char('#'); - - yyLinizerState->leftBraceFollows = - (firstNonWhiteSpace(yyLinizerState->line) == openingBrace ); - - do { - if (yyLinizerState->iter == yyProgramBegin) { - yyLinizerState->line = QString::null; - return false; - } - - --yyLinizerState->iter; - yyLinizerState->line = *yyLinizerState->iter; - - yyLinizerState->line = trimmedCodeLine(yyLinizerState->line); - - /* - Remove C-style comments that span multiple lines. If the - bottom line starts in a C-style comment, we are not aware - of that and eventually yyLine will contain a slash-aster. - - Notice that both if's can be executed, since - yyLinizerState->inCComment is potentially set to false in - the first if. The order of the if's is also important. - */ - - if (yyLinizerState->inCComment) { - - k = yyLinizerState->line.indexOf(m_constants.m_slashAster); - if (k == -1) { - yyLinizerState->line = QString::null; - } else { - yyLinizerState->line.truncate(k); - yyLinizerState->inCComment = false; - } - } - - if (!yyLinizerState->inCComment) { - k = yyLinizerState->line.indexOf(m_constants.m_asterSlash); - if (k != -1) { - for (int i = 0; i < k + 2; i++) - eraseChar(yyLinizerState->line, i, blank); - yyLinizerState->inCComment = true; - } - } - - /* - Remove preprocessor directives. - */ - k = 0; - while (k < yyLinizerState->line.length()) { - QChar ch = yyLinizerState->line[k]; - if (ch == hash) { - yyLinizerState->line = QString::null; - } else if (!ch.isSpace()) { - break; - } - k++; - } - - /* - Remove trailing spaces. - */ - k = yyLinizerState->line.length(); - while (k > 0 && yyLinizerState->line[k - 1].isSpace()) - k--; - yyLinizerState->line.truncate(k); - - /* - '}' increment the brace depth and '{' decrements it and not - the other way around, as we are parsing backwards. - */ - yyLinizerState->braceDepth += - yyLinizerState->line.count(closingBrace ) - yyLinizerState->line.count(openingBrace ); - - /* - We use a dirty trick for - - } else ... - - We don't count the '}' yet, so that it's more or less - equivalent to the friendly construct - - } - else ... - */ - if (yyLinizerState->pendingRightBrace) - yyLinizerState->braceDepth++; - yyLinizerState->pendingRightBrace = - (m_constants.m_braceX.indexIn(yyLinizerState->line) == 0); - if (yyLinizerState->pendingRightBrace) - yyLinizerState->braceDepth--; - } while (yyLinizerState->line.isEmpty()); - - return true; -} - -/* - Resets the linizer to its initial state, with yyLine containing the - line above the bottom line of the program. -*/ -void Indenter::startLinizer() -{ - yyLinizerState->braceDepth = 0; - yyLinizerState->inCComment = false; - yyLinizerState->pendingRightBrace = false; - - yyLine = &yyLinizerState->line; - yyBraceDepth = &yyLinizerState->braceDepth; - yyLeftBraceFollows = &yyLinizerState->leftBraceFollows; - - yyLinizerState->iter = yyProgramEnd; - --yyLinizerState->iter; - yyLinizerState->line = *yyLinizerState->iter; - readLine(); -} - -/* - Returns true if the start of the bottom line of yyProgram (and - potentially the whole line) is part of a C-style comment; otherwise - returns false. -*/ -bool Indenter::bottomLineStartsInCComment() -{ - /* - We could use the linizer here, but that would slow us down - terribly. We are better to trim only the code lines we need. - */ - Iterator p = yyProgramEnd; - --p; // skip bottom line - - for (int i = 0; i < BigRoof; i++) { - if (p == yyProgramBegin) - return false; - --p; - - if ((*p).contains(m_constants.m_slashAster) || (*p).contains(m_constants.m_asterSlash)) { - QString trimmed = trimmedCodeLine(*p); - - if (trimmed.contains(m_constants.m_slashAster)) { - return true; - } else if (trimmed.contains(m_constants.m_asterSlash)) { - return false; - } - } - } - return false; -} - -/* - 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. -*/ -int Indenter::indentWhenBottomLineStartsInCComment() const -{ - int k = yyLine->lastIndexOf(m_constants.m_slashAster); - 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. - */ - const int indent = columnForIndex(*yyLine, k); - k += 2; - while (k < yyLine->length()) { - if (!(*yyLine)[k].isSpace()) - return columnForIndex(*yyLine, k); - k++; - } - return indent + ppCommentOffset; - } -} - -/* - A function called match...() modifies the linizer state. If it - returns true, yyLine is the top line of the matched construct; - otherwise, the linizer is left in an unknown state. - - A function called is...() keeps the linizer state intact. -*/ - -/* - Returns true if the current line (and upwards) forms a braceless - control statement; otherwise returns false. - - The first line of the following example is a "braceless control - statement": - - if (x) - y; -*/ -bool Indenter::matchBracelessControlStatement() -{ - int delimDepth = 0; - - const QChar semicolon = QLatin1Char(';'); - - - if (yyLine->endsWith(m_constants.m_else)) - return true; - - if (!yyLine->endsWith(QLatin1Char(')'))) - return false; - - for (int i = 0; i < SmallRoof; i++) { - int j = yyLine->length(); - while (j > 0) { - j--; - QChar ch = (*yyLine)[j]; - - switch (ch.unicode()) { - case ')': - delimDepth++; - break; - case '(': - delimDepth--; - if (delimDepth == 0) { - if (yyLine->contains(m_constants.m_iflikeKeyword)) { - /* - We have - - if (x) - y - - "if (x)" is not part of the statement - "y". - */ - return true; - } - } - if (delimDepth == -1) { - /* - We have - - if ((1 + - 2) - - and not - - if (1 + - 2) - */ - return false; - } - break; - case '{': - case '}': - case ';': - /* - We met a statement separator, but not where we - expected it. What follows is probably a weird - continuation line. Be careful with ';' in for, - though. - */ - if (ch != semicolon || delimDepth == 0) - return false; - } - } - - if (!readLine()) - break; - } - return false; -} - -/* - Returns true if yyLine is an unfinished line; otherwise returns - false. - - In many places we'll use the terms "standalone line", "unfinished - line" and "continuation line". The meaning of these should be - evident from this code example: - - a = b; // standalone line - c = d + // unfinished line - e + // unfinished continuation line - f + // unfinished continuation line - g; // continuation line -*/ -bool Indenter::isUnfinishedLine() -{ - bool unf = false; - - YY_SAVE(); - - const QChar openingParenthesis = QLatin1Char('('); - const QChar semicolon = QLatin1Char(';'); - - if (yyLine->isEmpty()) - return false; - - const QChar lastCh = (*yyLine)[ yyLine->length() - 1]; - if (! m_constants.m_bracesSemicolon.contains(lastCh) && !yyLine->endsWith(m_constants.m_3dots)) { - /* - It doesn't end with ';' or similar. If it's neither - "Q_OBJECT" nor "if (x)" nor is a template function, it must be an unfinished line. - */ - unf = (!yyLine->contains(m_constants.m_qobject) && - !matchBracelessControlStatement() && - !yyLine->contains(m_constants.m_templateFunc)); - } else if (lastCh == semicolon) { - if (lastParen(*yyLine) == openingParenthesis) { - /* - Exception: - - for (int i = 1; i < 10; - */ - unf = true; - } else if (readLine() && yyLine->endsWith(semicolon) && - lastParen(*yyLine) == openingParenthesis) { - /* - Exception: - - for (int i = 1; - i < 10; - */ - unf = true; - } - } - - YY_RESTORE(); - return unf; -} - -/* - Returns true if yyLine is a continuation line; otherwise returns - false. -*/ -bool Indenter::isContinuationLine() -{ - YY_SAVE(); - const bool cont = readLine() && isUnfinishedLine(); - YY_RESTORE(); - return cont; -} - -/* - 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 '='. -*/ -int Indenter::indentForContinuationLine() -{ - int braceDepth = 0; - int delimDepth = 0; - - bool leftBraceFollowed = *yyLeftBraceFollows; - - const QChar equals = QLatin1Char('='); - const QChar comma = QLatin1Char(','); - const QChar openingParenthesis = QLatin1Char('('); - const QChar closingParenthesis = QLatin1Char(')'); - - 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 < 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 (j > 0 && j < yyLine->length() - 1 - && !m_constants.m_operators.contains((*yyLine)[j - 1]) - && (*yyLine)[j + 1] != equals) { - if (braceDepth == 0 && delimDepth == 0 && - !yyLine->endsWith(comma) && - (yyLine->contains(openingParenthesis) == yyLine->contains(closingParenthesis))) - 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 < 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(comma)) { - /* - 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; -} - -/* - Returns the recommended indent for the bottom line of yyProgram if - that line is standalone (or should be indented likewise). - - Indenting a standalone line is tricky, mostly because of braceless - control statements. Grossly, we are looking backwards for a special - line, a "hook line", that we can use as a starting point to indent, - and then modify the indentation level according to the braces met - along the way to that hook. - - Let's consider a few examples. In all cases, we want to indent the - bottom line. - - Example 1: - - x = 1; - y = 2; - - The hook line is "x = 1;". We met 0 opening braces and 0 closing - braces. Therefore, "y = 2;" inherits the indent of "x = 1;". - - Example 2: - - if (x) { - y; - - The hook line is "if (x) {". No matter what precedes it, "y;" has - to be indented one level deeper than the hook line, since we met one - opening brace along the way. - - Example 3: - - if (a) - while (b) { - c; - } - d; - - To indent "d;" correctly, we have to go as far as the "if (a)". - Compare with - - if (a) { - while (b) { - c; - } - d; - - Still, we are striving to go back as little as possible to accommodate - people with irregular indentation schemes. A hook line near at hand - is much more reliable than a remote one. -*/ -int Indenter::indentForStandaloneLine() -{ - const QChar semicolon = QLatin1Char(';'); - const QChar openingBrace = QLatin1Char('{'); - - for (int i = 0; i < SmallRoof; i++) { - if (!*yyLeftBraceFollows) { - YY_SAVE(); - - if (matchBracelessControlStatement()) { - /* - The situation is this, and we want to indent "z;": - - if (x && - y) - z; - - yyLine is "if (x &&". - */ - return indentOfLine(*yyLine) + ppIndentSize; - } - YY_RESTORE(); - } - - if (yyLine->endsWith(semicolon) || yyLine->count(openingBrace) > 0) { - /* - The situation is possibly this, and we want to indent - "z;": - - while (x) - y; - z; - - We return the indent of "while (x)". In place of "y;", - any arbitrarily complex compound statement can appear. - */ - - if (*yyBraceDepth > 0) { - do { - if (!readLine()) - break; - } while (*yyBraceDepth > 0); - } - - LinizerState hookState; - - while (isContinuationLine()) - readLine(); - hookState = *yyLinizerState; - - readLine(); - if (*yyBraceDepth <= 0) { - do { - if (!matchBracelessControlStatement()) - break; - hookState = *yyLinizerState; - } while (readLine()); - } - - *yyLinizerState = hookState; - - while (isContinuationLine()) - readLine(); - - /* - Never trust lines containing only '{' or '}', as some - people (Richard M. Stallman) format them weirdly. - */ - if (yyLine->trimmed().length() > 1) { - if (!ppDoubleIndentBlocks) - return indentOfLine(*yyLine) - *yyBraceDepth * ppIndentSize; - else { - if (*yyBraceDepth == -1 && indentOfLine(*yyLine) == 0) - return ppIndentSize; // don't do double indent for upper level blocks - return indentOfLine(*yyLine) - *yyBraceDepth * ppIndentSize * 2; - } - } - } - - if (!readLine()) - return -*yyBraceDepth * ppIndentSize; - } - return 0; -} - -/* - Returns the recommended indent for the bottom line of program. - Unless null, typedIn stores the character of yyProgram that - triggered reindentation. - - This function works better if typedIn is set properly; it is - slightly more conservative if typedIn is completely wild, and - slighly more liberal if typedIn is always null. The user might be - annoyed by the liberal behavior. -*/ -int Indenter::indentForBottomLine(const Iterator ¤t, - const Iterator &programBegin, - const Iterator &programEnd, - QChar typedIn) -{ - if (programBegin == programEnd) - return 0; - - yyProgramBegin = programBegin; - yyProgramEnd = programEnd; - - startLinizer(); - - Iterator lastIt = current; - - QString bottomLine = *lastIt; - QChar firstCh = firstNonWhiteSpace(bottomLine); - int indent; - - const QChar hash = QLatin1Char('#'); - const QChar openingBrace = QLatin1Char('{'); - const QChar closingBrace = QLatin1Char('}'); - const QChar colon = QLatin1Char(':'); - - if (bottomLineStartsInCComment()) { - /* - The bottom line starts in a C-style comment. Indent it - smartly, unless the user has already played around with it, - in which case it's better to leave her stuff alone. - */ - if (isOnlyWhiteSpace(bottomLine)) { - indent = indentWhenBottomLineStartsInCComment(); - } else { - indent = indentOfLine(bottomLine); - } - } else if (okay(typedIn, hash) && firstCh == hash) { - /* - Preprocessor directives go flush left. - */ - indent = 0; - } else { - if (isUnfinishedLine()) { - indent = indentForContinuationLine(); - } else { - indent = indentForStandaloneLine(); - } - - if (ppIndentBraces && firstCh == openingBrace) { - indent += ppIndentSize; - } else if (firstCh == closingBrace) { - /* - A closing brace is one level more to the left than the - code it follows. - */ - indent -= ppIndentSize; - /* - But if braces indenting is enabled the shift exists - */ - if (ppIndentBraces) - indent += ppIndentSize; - /* - Double indenting of code blocks makes block righter, so move our brace back - */ - if (ppDoubleIndentBlocks) - indent -= ppIndentSize; - - } else if (okay(typedIn, colon)) { - if (m_constants.m_caseLabel.indexIn(bottomLine) != -1) { - /* - Move a case label (or the ':' in front of a - constructor initialization list) one level to the - left, but only if the user did not play around with - it yet. Some users have exotic tastes in the - matter, and most users probably are not patient - enough to wait for the final ':' to format their - code properly. - - We don't attempt the same for goto labels, as the - user is probably the middle of "foo::bar". (Who - uses goto, anyway?) - */ - if (indentOfLine(bottomLine) <= indent) - indent -= ppIndentSize; - else - indent = indentOfLine(bottomLine); - } - } - } - if (ppIndentBraces && indent == ppIndentSize && - (firstCh == openingBrace || firstCh == closingBrace) ) { - indent = 0; - } - return qMax(0, indent); -} - -} // namespace SharedTools diff --git a/src/shared/indenter/indenter.h b/src/shared/indenter/indenter.h deleted file mode 100644 index b767d6978be..00000000000 --- a/src/shared/indenter/indenter.h +++ /dev/null @@ -1,147 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation ([email protected]) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef INDENTER_H -#define INDENTER_H - -#include "texteditor/basetexteditor.h" -#include "texteditor/textblockiterator.h" - -#include <QtCore/QString> -#include <QtCore/QStringList> - -namespace SharedTools { -namespace IndenterInternal { - -/* String constants and regexps required by the indenter. Separate for code cleanliness*/ -struct Constants { - Constants(); - const QString m_slashAster; - const QString m_asterSlash; - const QString m_slashSlash; - const QString m_else; - const QString m_qobject; - const QString m_operators; - const QString m_bracesSemicolon; - const QString m_3dots; - - QRegExp m_literal; - QRegExp m_label; - QRegExp m_inlineCComment; - QRegExp m_braceX; - QRegExp m_iflikeKeyword; - QRegExp m_caseLabel; - QRegExp m_templateFunc; -}; - -/* The "linizer" is a group of functions and variables to iterate - * through the source code of the program to indent. The program is - * given as a list of strings, with the bottom line being the line to - * indent. The actual program might contain extra lines, but those are - * uninteresting and not passed over to us. */ -struct LinizerState { - - QString line; - int braceDepth; - bool leftBraceFollows; - - TextEditor::TextBlockIterator iter; - bool inCComment; - bool pendingRightBrace; -}; -} - -/* Indenter singleton as a template of a bidirectional input iterator - * of a sequence of code lines represented as QString. - * When setting the parameters, be careful to - * specify the correct template parameters (best use a typedef). */ -class Indenter { - typedef TextEditor::TextBlockIterator Iterator; - Indenter(const Indenter&); - Indenter &operator=(const Indenter&); - Indenter(); - -public: - - ~Indenter(); - - static Indenter &instance(); - - void setIndentSize(int size); - void setTabSize(int size ); - void setIndentBraces(bool indent); - void setDoubleIndentBlocks(bool indent); - /* Return indentation for the last line of the sequence - * based on the previous lines. */ - int indentForBottomLine(const Iterator ¤t, - const Iterator &programBegin, - const Iterator &programEnd, - QChar typedIn); - - // Helpers. - static bool isOnlyWhiteSpace( const QString& t); - static QChar firstNonWhiteSpace( const QString& t ); - -private: - int columnForIndex( const QString& t, int index ) const; - int indentOfLine( const QString& t ) const; - QString trimmedCodeLine( const QString& t ); - bool readLine(); - void startLinizer(); - bool bottomLineStartsInCComment(); - int indentWhenBottomLineStartsInCComment() const; - bool matchBracelessControlStatement(); - bool isUnfinishedLine(); - bool isContinuationLine(); - int indentForContinuationLine(); - - int indentForStandaloneLine(); - - IndenterInternal::Constants m_constants; - int ppHardwareTabSize; - int ppIndentSize; - bool ppIndentBraces; - int ppContinuationIndentSize; - bool ppDoubleIndentBlocks; - - Iterator yyProgramBegin; - Iterator yyProgramEnd; - - typedef IndenterInternal::LinizerState LinizerState; - - LinizerState *yyLinizerState ; - - // shorthands - const QString *yyLine; - const int *yyBraceDepth; - const bool *yyLeftBraceFollows; -}; -} - -#endif // INDENTER_H diff --git a/src/shared/indenter/indenter.pri b/src/shared/indenter/indenter.pri deleted file mode 100644 index d0f523c2abd..00000000000 --- a/src/shared/indenter/indenter.pri +++ /dev/null @@ -1,4 +0,0 @@ -INCLUDEPATH *= $$PWD - -SOURCES += $$PWD/constants.cpp $$PWD/indenter.cpp -HEADERS += $$PWD/indenter.h diff --git a/src/shared/indenter/test/main.cpp b/src/shared/indenter/test/main.cpp deleted file mode 100644 index fe79870b517..00000000000 --- a/src/shared/indenter/test/main.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation ([email protected]) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "indenter.h" - -#include <QtCore/QFile> -#include <QtCore/QStringList> -#include <QtCore/QDebug> -#include <QtCore/QTextStream> -#include <QtCore/QFileInfo> - -#include <stdio.h> - -typedef SharedTools::Indenter<QStringList::const_iterator> Indenter; - -static QString fileContents(const QString &fileName) -{ - QFile f(fileName); - if (!f.open(QIODevice::ReadOnly)) { - const QString msg = QString(QLatin1String("error: Cannot open file '%1' for reading: %2")). - arg(fileName).arg(f.errorString()); - qWarning(msg.toLatin1().constData()); - return QString::null; - } - - const QString contents = QString::fromUtf8(f.readAll()); - f.close(); - if ( contents.isEmpty() ) { - const QString msg = QString(QLatin1String("error: File '%1' is empty")).arg(fileName); - qWarning(msg.toLatin1().constData()); - return QString::null; - } - return contents; -} - -static void printUsage(char *a0) -{ - const QFileInfo fi(QString::fromUtf8(a0)); - const QString usage = QString(QLatin1String("Usage: %1 [-i indent-size] [-t tab-size] file.cpp")). - arg(fi.fileName()); - qWarning(usage.toUtf8().constData()); -} - -static int integerOptionArgument(char ** &aptr, char **end) -{ - if (++aptr == end) - return -1; - const QString arg = QString::fromUtf8(*aptr); - bool ok; - const int rc = arg.toInt (&ok); - if (!ok) - return -1; - return rc; -} - -static QStringList parseCommandLine(char **begin, char **end) -{ - char **aptr = begin; - if (++aptr == end) - return QStringList(); - - QStringList fileNames; - for ( ; aptr != end; ++aptr) { - const char *arg = *aptr; - if (arg[0] == '-') { - switch (arg[1]) { - case 't': { - const int tabSize = integerOptionArgument(aptr, end); - if ( tabSize == -1) - return QStringList(); - Indenter::instance().setTabSize(tabSize); - } - break; - case 'i': { - const int indentSize = integerOptionArgument(aptr, end); - if (indentSize == -1) - return QStringList(); - Indenter::instance().setIndentSize(indentSize); - } - break; - default: - return QStringList(); - } - } else { - fileNames.push_back(QString::fromUtf8(arg)); - } - } - return fileNames; -} - -int format(const QString &fileName) -{ - const QString code = fileContents(fileName); - if (code.isEmpty()) - return 1; - - QStringList program = code.split(QLatin1Char('\n'), QString::KeepEmptyParts); - while (!program.isEmpty()) { - if (!program.back().trimmed().isEmpty()) - break; - program.pop_back(); - } - - QStringList p; - QString out; - - const QChar colon = QLatin1Char(':'); - const QChar blank = QLatin1Char(' '); - const QChar newLine = QLatin1Char('\n'); - - QStringList::const_iterator cend = program.constEnd(); - for (QStringList::const_iterator it = program.constBegin(); it != cend; ++it) { - p.push_back(*it); - QString &line = p.back(); - - QChar typedIn = Indenter::instance().firstNonWhiteSpace(line); - if (p.last().endsWith(colon)) - typedIn = colon; - - const int indent = Indenter::instance().indentForBottomLine(it, p.constBegin(), p.constEnd(), typedIn); - - const QString trimmed = line.trimmed(); - // Indent the line in the list so that the formatter code sees the indented line. - if (!trimmed.isEmpty()) { - line = QString(indent, blank); - line += trimmed; - } - out += line; - out += newLine ; - } - - while (out.endsWith(newLine)) - out.truncate(out.length() - 1 ); - - fputs(out.toUtf8().constData(), stdout); - return 0; -} - -int main(int argc, char **argv) -{ - const QStringList fileNames = parseCommandLine(argv, argv + argc); - if (fileNames.empty()) { - printUsage(argv[0]); - return 1; - } - - foreach (const QString &fileName, fileNames) - if (const int rc = format(fileName)) - return rc; - - return 0; -} diff --git a/src/shared/indenter/test/test.pro b/src/shared/indenter/test/test.pro deleted file mode 100644 index 9600b7abeb4..00000000000 --- a/src/shared/indenter/test/test.pro +++ /dev/null @@ -1,10 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Mon Apr 16 13:02:01 2007 -###################################################################### - -TEMPLATE = app -TARGET=indenter -CONFIG += console - -include(../indenter.pri) -SOURCES += main.cpp |