File indexing completed on 2024-04-14 03:55:32

0001 /*
0002     SPDX-FileCopyrightText: 2016 Dominik Haumann <dhaumann@kde.org>
0003     SPDX-FileCopyrightText: 2007 Mirko Stocker <me@misto.ch>
0004     SPDX-FileCopyrightText: 2003-2005 Hamish Rodda <rodda@kde.org>
0005     SPDX-FileCopyrightText: 2002 Christian Couder <christian@kdevelop.org>
0006     SPDX-FileCopyrightText: 2001, 2003 Christoph Cullmann <cullmann@kde.org>
0007     SPDX-FileCopyrightText: 2001 Joseph Wenninger <jowenn@kde.org>
0008     SPDX-FileCopyrightText: 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
0009 
0010     SPDX-License-Identifier: LGPL-2.0-or-later
0011 */
0012 
0013 #include "range.h"
0014 
0015 #include <QByteArray>
0016 #include <QDebug>
0017 #include <QHash>
0018 #include <QString>
0019 
0020 using namespace KTextEditor;
0021 
0022 Range Range::fromString(QStringView str) noexcept
0023 {
0024     const int startIndex = str.indexOf(QLatin1Char('['));
0025     const int endIndex = str.indexOf(QLatin1Char(']'));
0026     const int closeIndex = str.indexOf(QLatin1Char(')')); // end of first cursor
0027 
0028     if (startIndex < 0 || endIndex < 0 || closeIndex < 0 || closeIndex < startIndex || endIndex < closeIndex || endIndex < startIndex) {
0029         return invalid();
0030     }
0031 
0032     return Range(Cursor::fromString(str.mid(startIndex + 1, closeIndex - startIndex)), Cursor::fromString(str.mid(closeIndex + 2, endIndex - closeIndex - 2)));
0033 }
0034 
0035 void Range::setRange(Range range) noexcept
0036 {
0037     m_start = range.start();
0038     m_end = range.end();
0039 }
0040 
0041 void Range::setRange(Cursor start, Cursor end) noexcept
0042 {
0043     if (start > end) {
0044         setRange(Range(end, start));
0045     } else {
0046         setRange(Range(start, end));
0047     }
0048 }
0049 
0050 bool Range::confineToRange(Range range) noexcept
0051 {
0052     if (start() < range.start()) {
0053         if (end() > range.end()) {
0054             setRange(range);
0055         } else {
0056             setStart(range.start());
0057         }
0058     } else if (end() > range.end()) {
0059         setEnd(range.end());
0060     } else {
0061         return false;
0062     }
0063 
0064     return true;
0065 }
0066 
0067 bool Range::expandToRange(Range range) noexcept
0068 {
0069     if (start() > range.start()) {
0070         if (end() < range.end()) {
0071             setRange(range);
0072         } else {
0073             setStart(range.start());
0074         }
0075     } else if (end() < range.end()) {
0076         setEnd(range.end());
0077     } else {
0078         return false;
0079     }
0080 
0081     return true;
0082 }
0083 
0084 void Range::setBothLines(int line) noexcept
0085 {
0086     setRange(Range(line, start().column(), line, end().column()));
0087 }
0088 
0089 void KTextEditor::Range::setBothColumns(int column) noexcept
0090 {
0091     setRange(Range(start().line(), column, end().line(), column));
0092 }
0093 
0094 LineRange LineRange::fromString(QStringView str) noexcept
0095 {
0096     // parse format "[start, end]"
0097     const int startIndex = str.indexOf(QLatin1Char('['));
0098     const int endIndex = str.indexOf(QLatin1Char(']'));
0099     const int commaIndex = str.indexOf(QLatin1Char(','));
0100 
0101     if (startIndex < 0 || endIndex < 0 || commaIndex < 0 || commaIndex < startIndex || endIndex < commaIndex || endIndex < startIndex) {
0102         return invalid();
0103     }
0104 
0105     bool ok1 = false;
0106     bool ok2 = false;
0107 
0108     const int start = str.mid(startIndex + 1, commaIndex - startIndex - 1).toInt(&ok1);
0109     const int end = str.mid(commaIndex + 1, endIndex - commaIndex - 1).toInt(&ok2);
0110 
0111     if (!ok1 || !ok2) {
0112         return invalid();
0113     }
0114 
0115     return {start, end};
0116 }
0117 
0118 QDebug operator<<(QDebug s, KTextEditor::Range range)
0119 {
0120     s << "[" << range.start() << " -> " << range.end() << "]";
0121     return s;
0122 }
0123 
0124 QDebug operator<<(QDebug s, KTextEditor::LineRange range)
0125 {
0126     s << "[" << range.start() << " -> " << range.end() << "]";
0127     return s;
0128 }
0129 
0130 size_t KTextEditor::qHash(KTextEditor::LineRange range, size_t seed) noexcept
0131 {
0132     return qHashMulti(seed, range.start(), range.end());
0133 }
0134 
0135 size_t KTextEditor::qHash(KTextEditor::Range range, size_t seed) noexcept
0136 {
0137     return qHashMulti(seed, range.start(), range.end());
0138 }
0139 
0140 QString Range::toString() const
0141 {
0142     return QStringLiteral("[%1, %2]").arg(m_start.toString()).arg(m_end.toString());
0143 }
0144 
0145 QString LineRange::toString() const
0146 {
0147     return QStringLiteral("[%1, %2]").arg(m_start).arg(m_end);
0148 }
0149 
0150 namespace QTest
0151 {
0152 // Cursor: template specialization for QTest::toString()
0153 template<>
0154 char *toString(const KTextEditor::Cursor &cursor)
0155 {
0156     QByteArray ba = "Cursor[" + QByteArray::number(cursor.line()) + ", " + QByteArray::number(cursor.column()) + ']';
0157     return qstrdup(ba.data());
0158 }
0159 
0160 // Range: template specialization for QTest::toString()
0161 template<>
0162 char *toString(const KTextEditor::Range &range)
0163 {
0164     QByteArray ba = "Range[";
0165     ba += QByteArray::number(range.start().line()) + ", " + QByteArray::number(range.start().column()) + " - ";
0166     ba += QByteArray::number(range.end().line()) + ", " + QByteArray::number(range.end().column());
0167     ba += ']';
0168     return qstrdup(ba.data());
0169 }
0170 
0171 // LineRange: template specialization for QTest::toString()
0172 template<>
0173 char *toString(const KTextEditor::LineRange &range)
0174 {
0175     QByteArray ba = "LineRange[";
0176     ba += QByteArray::number(range.start()) + ", " + QByteArray::number(range.end());
0177     ba += ']';
0178     return qstrdup(ba.data());
0179 }
0180 }