KCoreAddons

kmacroexpander_win.cpp
1/*
2 This file is part of the KDE libraries
3
4 SPDX-FileCopyrightText: 2008 Oswald Buddenhagen <ossi@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "kmacroexpander_p.h"
10#include "kshell_p.h"
11
12#include "kshell.h"
13
14#include <QString>
15#include <QStringList>
16
18{
19 int len;
20 int pos2;
21 ushort uc;
22 ushort ec = d->escapechar.unicode();
23 bool shellQuote = false; // shell is in quoted state
24 bool crtQuote = false; // c runtime is in quoted state
25 bool escaped = false; // previous char was a circumflex
26 int bslashes = 0; // previous chars were backslashes
27 int parens = 0; // parentheses nesting level
28 QStringList rst;
29 QString rsts;
30
31 while (pos < str.length()) {
32 ushort cc = str.unicode()[pos].unicode();
33 if (escaped) { // prevent anomalies due to expansion
34 goto notcf;
35 }
36 if (ec != 0) {
37 if (cc != ec) {
38 goto nohit;
39 }
40 if (!(len = expandEscapedMacro(str, pos, rst))) {
41 goto nohit;
42 }
43 } else {
44 if (!(len = expandPlainMacro(str, pos, rst))) {
45 goto nohit;
46 }
47 }
48 if (len < 0) {
49 pos -= len;
50 continue;
51 }
52 if (shellQuote != crtQuote) { // Silly, isn't it? Ahoy to Redmond.
53 return false;
54 }
55 if (shellQuote) {
56 rsts = KShell::quoteArgInternal(rst.join(QLatin1Char(' ')), true);
57 } else {
58 if (rst.isEmpty()) {
59 str.remove(pos, len);
60 continue;
61 }
62 rsts = KShell::joinArgs(rst);
63 }
64 pos2 = 0;
65 while (pos2 < rsts.length() && ((uc = rsts.unicode()[pos2].unicode()) == '\\' || uc == '^')) {
66 pos2++;
67 }
68 if (pos2 < rsts.length() && rsts.unicode()[pos2].unicode() == '"') {
69 QString bsl;
70 bsl.reserve(bslashes);
71 for (; bslashes; bslashes--) {
72 bsl.append(QLatin1String("\\"));
73 }
74 rsts.prepend(bsl);
75 }
76 bslashes = 0;
77 rst.clear();
78 str.replace(pos, len, rsts);
79 pos += rsts.length();
80 continue;
81 nohit:
82 if (!escaped && !shellQuote && cc == '^') {
83 escaped = true;
84 } else {
85 notcf:
86 if (cc == '\\') {
87 bslashes++;
88 } else {
89 if (cc == '"') {
90 if (!escaped) {
91 shellQuote = !shellQuote;
92 }
93 if (!(bslashes & 1)) {
94 crtQuote = !crtQuote;
95 }
96 } else if (!shellQuote) {
97 if (cc == '(') {
98 parens++;
99 } else if (cc == ')')
100 if (--parens < 0) {
101 break;
102 }
103 }
104 bslashes = 0;
105 }
106 escaped = false;
107 }
108 pos++;
109 }
110 return true;
111}
virtual int expandPlainMacro(const QString &str, int pos, QStringList &ret)
This function is called for every single char within the string if the escape char is QChar::null.
virtual int expandEscapedMacro(const QString &str, int pos, QStringList &ret)
This function is called every time the escape char is found if it is not QChar::null.
bool expandMacrosShellQuote(QString &str, int &pos)
Perform safe macro expansion (substitution) on a string for use in shell commands.
KCOREADDONS_EXPORT QString joinArgs(const QStringList &args)
Quotes and joins args together according to system shell rules.
Definition kshell.cpp:23
char16_t & unicode()
void clear()
bool isEmpty() const const
QString & append(QChar ch)
qsizetype length() const const
QString & prepend(QChar ch)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
void reserve(qsizetype size)
const QChar * unicode() const const
QString join(QChar separator) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.