/**************************************************************************** ** ** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "quoter.h" #include #include #include QT_BEGIN_NAMESPACE QHash Quoter::commentHash; static void replaceMultipleNewlines(QString &s) { const int n = s.size(); bool slurping = false; int j = -1; const QChar newLine = QLatin1Char('\n'); QChar *d = s.data(); for (int i = 0; i != n; ++i) { const QChar c = d[i]; bool hit = (c == newLine); if (slurping && hit) continue; d[++j] = c; slurping = hit; } s.resize(++j); } // This is equivalent to line.split( QRegExp("\n(?!\n|$)") ) but much faster QStringList Quoter::splitLines(const QString &line) { QStringList result; int i = line.size(); while (true) { int j = i - 1; while (j >= 0 && line.at(j) == QLatin1Char('\n')) --j; while (j >= 0 && line.at(j) != QLatin1Char('\n')) --j; result.prepend(line.mid(j + 1, i - j - 1)); if (j < 0) break; i = j; } return result; } /* Transforms 'int x = 3 + 4' into 'int x=3+4'. A white space is kept between 'int' and 'x' because it is meaningful in C++. */ static void trimWhiteSpace(QString &str) { enum { Normal, MetAlnum, MetSpace } state = Normal; const int n = str.length(); int j = -1; QChar *d = str.data(); for (int i = 0; i != n; ++i) { const QChar c = d[i]; if (c.isLetterOrNumber()) { if (state == Normal) { state = MetAlnum; } else { if (state == MetSpace) str[++j] = c; state = Normal; } str[++j] = c; } else if (c.isSpace()) { if (state == MetAlnum) state = MetSpace; } else { state = Normal; str[++j] = c; } } str.resize(++j); } Quoter::Quoter() : silent(false) { /* We're going to hard code these delimiters: * C++, Qt, Qt Script, Java: //! [] * .pro, .py, CMake files: #! [] * .html, .qrc, .ui, .xq, .xml .dita files: */ if (!commentHash.size()) { commentHash["pro"] = "#!"; commentHash["py"] = "#!"; commentHash["cmake"] = "#!"; commentHash["html"] = "