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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • 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 
31 namespace 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 
46 using namespace KMacroExpander;
47 
48 bool 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 }
KMacroExpander::singlequote
Definition: kmacroexpander_unix.cpp:33
QList::clear
void clear()
QStack::pop
T pop()
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
KMacroExpander::group
Definition: kmacroexpander_unix.cpp:34
KMacroExpander::paren
Definition: kmacroexpander_unix.cpp:34
QStack::push
void push(const T &t)
KMacroExpander::dollarquote
Definition: kmacroexpander_unix.cpp:33
kshell.h
QStringList::join
QString join(const QString &separator) const
QString::remove
QString & remove(int position, int n)
KMacroExpander::Quoting
Quoting
Definition: kmacroexpander_unix.cpp:33
QRegExp
QList::isEmpty
bool isEmpty() const
KMacroExpander::math
Definition: kmacroexpander_unix.cpp:34
KMacroExpander::noquote
Definition: kmacroexpander_unix.cpp:33
KMacroExpander::doublequote
Definition: kmacroexpander_unix.cpp:33
QString
QChar::unicode
ushort unicode() const
QStringList
QLatin1Char
KMacroExpander::subst
Definition: kmacroexpander_unix.cpp:34
QString::replace
QString & replace(int position, int n, QChar after)
QString::unicode
const QChar * unicode() const
QLatin1String
kmacroexpander_p.h
QString::length
int length() const
KShell::joinArgs
QString joinArgs(const QStringList &args)
Quotes and joins args together according to system shell rules.
Definition: kshell.cpp:38
QVector::empty
bool empty() const
QStack
QStack::top
T & top()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:11 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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