aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor/codesniphelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor/codesniphelpers.cpp')
-rw-r--r--sources/shiboken6/ApiExtractor/codesniphelpers.cpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/sources/shiboken6/ApiExtractor/codesniphelpers.cpp b/sources/shiboken6/ApiExtractor/codesniphelpers.cpp
new file mode 100644
index 000000000..775cf10af
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/codesniphelpers.cpp
@@ -0,0 +1,77 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "codesniphelpers.h"
+
+#include <QtCore/QStringList>
+
+#include <algorithm>
+
+static inline int firstNonBlank(QStringView s)
+{
+ const auto it = std::find_if(s.cbegin(), s.cend(),
+ [] (QChar c) { return !c.isSpace(); });
+ return int(it - s.cbegin());
+}
+
+static inline bool isEmpty(QStringView s)
+{
+ return s.isEmpty()
+ || std::all_of(s.cbegin(), s.cend(),
+ [] (QChar c) { return c.isSpace(); });
+}
+
+QString CodeSnipHelpers::dedent(const QString &code)
+{
+ if (code.isEmpty())
+ return code;
+ // Right trim if indent=0, or trim if single line
+ if (!code.at(0).isSpace() || !code.contains(u'\n'))
+ return code.trimmed();
+ const auto lines = QStringView{code}.split(u'\n');
+ int spacesToRemove = std::numeric_limits<int>::max();
+ for (const auto &line : lines) {
+ if (!isEmpty(line)) {
+ const int nonSpacePos = firstNonBlank(line);
+ if (nonSpacePos < spacesToRemove)
+ spacesToRemove = nonSpacePos;
+ if (spacesToRemove == 0)
+ return code;
+ }
+ }
+ QString result;
+ for (const auto &line : lines) {
+ if (!isEmpty(line) && spacesToRemove < line.size())
+ result += line.mid(spacesToRemove).toString();
+ result += u'\n';
+ }
+ return result;
+}
+
+QString CodeSnipHelpers::fixSpaces(QString code)
+{
+ code.remove(u'\r');
+ // Check for XML <tag>\n<space>bla...
+ if (code.startsWith(u"\n "))
+ code.remove(0, 1);
+ while (!code.isEmpty() && code.back().isSpace())
+ code.chop(1);
+ code = dedent(code);
+ if (!code.isEmpty() && !code.endsWith(u'\n'))
+ code.append(u'\n');
+ return code;
+}
+
+// Prepend a line to the code, observing indentation
+void CodeSnipHelpers::prependCode(QString *code, QString firstLine)
+{
+ while (!code->isEmpty() && code->front() == u'\n')
+ code->remove(0, 1);
+ if (!code->isEmpty() && code->front().isSpace()) {
+ const int indent = firstNonBlank(*code);
+ firstLine.prepend(QString(indent, u' '));
+ }
+ if (!firstLine.endsWith(u'\n'))
+ firstLine += u'\n';
+ code->prepend(firstLine);
+}