• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • util
kmacroexpander_unix.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3
4 Copyright (c) 2002-2003 Oswald Buddenhagen <ossi@kde.org>
5 Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "kmacroexpander_p.h"
24
25#include "kshell.h"
26
27#include <QtCore/QStringList>
28#include <QtCore/QStack>
29#include <QtCore/QRegExp>
30
31namespace KMacroExpander {
32
33 enum Quoting { noquote, singlequote, doublequote, dollarquote,
34 paren, subst, group, math };
35 typedef struct {
36 Quoting current;
37 bool dquote;
38 } State;
39 typedef struct {
40 QString str;
41 int pos;
42 } Save;
43
44}
45
46using namespace KMacroExpander;
47
48bool KMacroExpanderBase::expandMacrosShellQuote( QString &str, int &pos )
49{
50 int len;
51 int pos2;
52 ushort ec = d->escapechar.unicode();
53 State state = { noquote, false };
54 QStack<State> sstack;
55 QStack<Save> ostack;
56 QStringList rst;
57 QString rsts;
58
59 while (pos < str.length()) {
60 ushort cc = str.unicode()[pos].unicode();
61 if (ec != 0) {
62 if (cc != ec)
63 goto nohit;
64 if (!(len = expandEscapedMacro( str, pos, rst )))
65 goto nohit;
66 } else {
67 if (!(len = expandPlainMacro( str, pos, rst )))
68 goto nohit;
69 }
70 if (len < 0) {
71 pos -= len;
72 continue;
73 }
74 if (state.dquote) {
75 rsts = rst.join( QLatin1String(" ") );
76 rsts.replace( QRegExp(QLatin1String("([$`\"\\\\])")), QLatin1String("\\\\1") );
77 } else if (state.current == dollarquote) {
78 rsts = rst.join( QLatin1String(" ") );
79 rsts.replace( QRegExp(QLatin1String("(['\\\\])")), QLatin1String("\\\\1") );
80 } else if (state.current == singlequote) {
81 rsts = rst.join( QLatin1String(" ") );
82 rsts.replace( QLatin1Char('\''), QLatin1String("'\\''") );
83 } else {
84 if (rst.isEmpty()) {
85 str.remove( pos, len );
86 continue;
87 } else {
88 rsts = KShell::joinArgs( rst );
89 }
90 }
91 rst.clear();
92 str.replace( pos, len, rsts );
93 pos += rsts.length();
94 continue;
95 nohit:
96 if (state.current == singlequote) {
97 if (cc == '\'')
98 state = sstack.pop();
99 } else if (cc == '\\') {
100 // always swallow the char -> prevent anomalies due to expansion
101 pos += 2;
102 continue;
103 } else if (state.current == dollarquote) {
104 if (cc == '\'')
105 state = sstack.pop();
106 } else if (cc == '$') {
107 cc = str.unicode()[++pos].unicode();
108 if (cc == '(') {
109 sstack.push( state );
110 if (str.unicode()[pos + 1].unicode() == '(') {
111 Save sav = { str, pos + 2 };
112 ostack.push( sav );
113 state.current = math;
114 pos += 2;
115 continue;
116 } else {
117 state.current = paren;
118 state.dquote = false;
119 }
120 } else if (cc == '{') {
121 sstack.push( state );
122 state.current = subst;
123 } else if (!state.dquote) {
124 if (cc == '\'') {
125 sstack.push( state );
126 state.current = dollarquote;
127 } else if (cc == '"') {
128 sstack.push( state );
129 state.current = doublequote;
130 state.dquote = true;
131 }
132 }
133 // always swallow the char -> prevent anomalies due to expansion
134 } else if (cc == '`') {
135 str.replace( pos, 1, QLatin1String("$( " )); // add space -> avoid creating $((
136 pos2 = pos += 3;
137 for (;;) {
138 if (pos2 >= str.length()) {
139 pos = pos2;
140 return false;
141 }
142 cc = str.unicode()[pos2].unicode();
143 if (cc == '`')
144 break;
145 if (cc == '\\') {
146 cc = str.unicode()[++pos2].unicode();
147 if (cc == '$' || cc == '`' || cc == '\\' ||
148 (cc == '"' && state.dquote))
149 {
150 str.remove( pos2 - 1, 1 );
151 continue;
152 }
153 }
154 pos2++;
155 }
156 str[pos2] = QLatin1Char(')');
157 sstack.push( state );
158 state.current = paren;
159 state.dquote = false;
160 continue;
161 } else if (state.current == doublequote) {
162 if (cc == '"')
163 state = sstack.pop();
164 } else if (cc == '\'') {
165 if (!state.dquote) {
166 sstack.push( state );
167 state.current = singlequote;
168 }
169 } else if (cc == '"') {
170 if (!state.dquote) {
171 sstack.push( state );
172 state.current = doublequote;
173 state.dquote = true;
174 }
175 } else if (state.current == subst) {
176 if (cc == '}')
177 state = sstack.pop();
178 } else if (cc == ')') {
179 if (state.current == math) {
180 if (str.unicode()[pos + 1].unicode() == ')') {
181 state = sstack.pop();
182 pos += 2;
183 } else {
184 // false hit: the $(( was a $( ( in fact
185 // ash does not care, but bash does
186 pos = ostack.top().pos;
187 str = ostack.top().str;
188 ostack.pop();
189 state.current = paren;
190 state.dquote = false;
191 sstack.push( state );
192 }
193 continue;
194 } else if (state.current == paren)
195 state = sstack.pop();
196 else
197 break;
198 } else if (cc == '}') {
199 if (state.current == KMacroExpander::group)
200 state = sstack.pop();
201 else
202 break;
203 } else if (cc == '(') {
204 sstack.push( state );
205 state.current = paren;
206 } else if (cc == '{') {
207 sstack.push( state );
208 state.current = KMacroExpander::group;
209 }
210 pos++;
211 }
212 return sstack.empty();
213}
KMacroExpanderBasePrivate::escapechar
QChar escapechar
Definition: kmacroexpander_p.h:31
KMacroExpanderBase::expandPlainMacro
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.
Definition: kmacroexpander.cpp:88
KMacroExpanderBase::expandEscapedMacro
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.
Definition: kmacroexpander.cpp:91
KMacroExpanderBase::expandMacrosShellQuote
bool expandMacrosShellQuote(QString &str, int &pos)
Perform safe macro expansion (substitution) on a string for use in shell commands.
Definition: kmacroexpander_unix.cpp:48
QStringList
QString
kmacroexpander_p.h
kshell.h
KMacroExpander
A group of functions providing macro expansion (substitution) in strings, optionally with quoting app...
Definition: kmacroexpander.cpp:338
KMacroExpander::Quoting
Quoting
Definition: kmacroexpander_unix.cpp:33
KMacroExpander::group
@ group
Definition: kmacroexpander_unix.cpp:34
KMacroExpander::paren
@ paren
Definition: kmacroexpander_unix.cpp:34
KMacroExpander::subst
@ subst
Definition: kmacroexpander_unix.cpp:34
KMacroExpander::noquote
@ noquote
Definition: kmacroexpander_unix.cpp:33
KMacroExpander::doublequote
@ doublequote
Definition: kmacroexpander_unix.cpp:33
KMacroExpander::singlequote
@ singlequote
Definition: kmacroexpander_unix.cpp:33
KMacroExpander::dollarquote
@ dollarquote
Definition: kmacroexpander_unix.cpp:33
KMacroExpander::math
@ math
Definition: kmacroexpander_unix.cpp:34
KShell::joinArgs
QString joinArgs(const QStringList &args)
Quotes and joins args together according to system shell rules.
Definition: kshell.cpp:38
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal