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

KDECore

  • sources
  • kde-4.12
  • kdelibs
  • kdecore
  • util
kshell_unix.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE libraries
3 
4  Copyright (c) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "kshell.h"
23 #include "kshell_p.h"
24 
25 #include <kuser.h>
26 
27 #include <QtCore/QChar>
28 #include <QtCore/QStringList>
29 
30 static int fromHex( QChar cUnicode )
31 {
32  char c = cUnicode.toLatin1 ();
33 
34  if (c >= '0' && c <= '9')
35  return c - '0';
36  else if (c >= 'A' && c <= 'F')
37  return c - 'A' + 10;
38  else if (c >= 'a' && c <= 'f')
39  return c - 'a' + 10;
40  return -1;
41 }
42 
43 inline static bool isQuoteMeta( QChar cUnicode )
44 {
45 #if 0 // it's not worth it, especially after seeing gcc's asm output ...
46  static const uchar iqm[] = {
47  0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
48  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
49  }; // \'"$
50 
51  return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
52 #else
53  char c = cUnicode.toLatin1();
54  return c == '\\' || c == '\'' || c == '"' || c == '$';
55 #endif
56 }
57 
58 inline static bool isMeta( QChar cUnicode )
59 {
60  static const uchar iqm[] = {
61  0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00, 0xd8,
62  0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x38
63  }; // \'"$`<>|;&(){}*?#[]
64 
65  uint c = cUnicode.unicode();
66 
67  return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
68 }
69 
70 QStringList KShell::splitArgs( const QString &args, Options flags, Errors *err)
71 {
72  QStringList ret;
73  bool firstword = flags & AbortOnMeta;
74 
75  for (int pos = 0; ; ) {
76  QChar c;
77  do {
78  if (pos >= args.length())
79  goto okret;
80  c = args.unicode()[pos++];
81  } while (c.isSpace());
82  QString cret;
83  if ((flags & TildeExpand) && c == QLatin1Char('~')) {
84  int opos = pos;
85  for (; ; pos++) {
86  if (pos >= args.length())
87  break;
88  c = args.unicode()[pos];
89  if (c == QLatin1Char('/') || c.isSpace())
90  break;
91  if (isQuoteMeta( c )) {
92  pos = opos;
93  c = QLatin1Char('~');
94  goto notilde;
95  }
96  if ((flags & AbortOnMeta) && isMeta( c ))
97  goto metaerr;
98  }
99  QString ccret = homeDir( args.mid(opos, pos-opos) );
100  if (ccret.isEmpty()) {
101  pos = opos;
102  c = QLatin1Char('~');
103  goto notilde;
104  }
105  if (pos >= args.length()) {
106  ret += ccret;
107  goto okret;
108  }
109  pos++;
110  if (c.isSpace()) {
111  ret += ccret;
112  firstword = false;
113  continue;
114  }
115  cret = ccret;
116  }
117  // before the notilde label, as a tilde does not match anyway
118  if (firstword) {
119  if (c == QLatin1Char('_') ||
120  (c >= QLatin1Char('A') && c <= QLatin1Char('Z')) ||
121  (c >= QLatin1Char('a') && c <= QLatin1Char('z')))
122  {
123  int pos2 = pos;
124  QChar cc;
125  do {
126  if (pos2 >= args.length()) {
127  // Exactly one word
128  ret += args.mid(pos - 1);
129  goto okret;
130  }
131  cc = args.unicode()[pos2++];
132  } while (cc == QLatin1Char('_') ||
133  (cc >= QLatin1Char('A') && cc <= QLatin1Char('Z')) ||
134  (cc >= QLatin1Char('a') && cc <= QLatin1Char('z')) ||
135  (cc >= QLatin1Char('0') && cc <= QLatin1Char('9')));
136  if (cc == QLatin1Char('='))
137  goto metaerr;
138  }
139  }
140  notilde:
141  do {
142  if (c == QLatin1Char('\'')) {
143  int spos = pos;
144  do {
145  if (pos >= args.length())
146  goto quoteerr;
147  c = args.unicode()[pos++];
148  } while (c != QLatin1Char('\''));
149  cret += args.mid(spos, pos-spos-1);
150  } else if (c == QLatin1Char('"')) {
151  for (;;) {
152  if (pos >= args.length())
153  goto quoteerr;
154  c = args.unicode()[pos++];
155  if (c == QLatin1Char('"'))
156  break;
157  if (c == QLatin1Char('\\')) {
158  if (pos >= args.length())
159  goto quoteerr;
160  c = args.unicode()[pos++];
161  if (c != QLatin1Char('"') &&
162  c != QLatin1Char('\\') &&
163  !((flags & AbortOnMeta) &&
164  (c == QLatin1Char('$') ||
165  c == QLatin1Char('`'))))
166  cret += QLatin1Char('\\');
167  } else if ((flags & AbortOnMeta) &&
168  (c == QLatin1Char('$') ||
169  c == QLatin1Char('`')))
170  goto metaerr;
171  cret += c;
172  }
173  } else if (c == QLatin1Char('$') && pos < args.length() &&
174  args.unicode()[pos] == QLatin1Char('\'')) {
175  pos++;
176  for (;;) {
177  if (pos >= args.length())
178  goto quoteerr;
179  c = args.unicode()[pos++];
180  if (c == QLatin1Char('\''))
181  break;
182  if (c == QLatin1Char('\\')) {
183  if (pos >= args.length())
184  goto quoteerr;
185  c = args.unicode()[pos++];
186  switch (c.toLatin1()) {
187  case 'a': cret += QLatin1Char('\a'); break;
188  case 'b': cret += QLatin1Char('\b'); break;
189  case 'e': cret += QLatin1Char('\033'); break;
190  case 'f': cret += QLatin1Char('\f'); break;
191  case 'n': cret += QLatin1Char('\n'); break;
192  case 'r': cret += QLatin1Char('\r'); break;
193  case 't': cret += QLatin1Char('\t'); break;
194  case '\\': cret += QLatin1Char('\\'); break;
195  case '\'': cret += QLatin1Char('\''); break;
196  case 'c':
197  if (pos >= args.length())
198  goto quoteerr;
199  cret += args.unicode()[pos++].toLatin1() & 31;
200  break;
201  case 'x':
202  {
203  if (pos >= args.length())
204  goto quoteerr;
205  int hv = fromHex( args.unicode()[pos++] );
206  if (hv < 0)
207  goto quoteerr;
208  if (pos < args.length()) {
209  int hhv = fromHex( args.unicode()[pos] );
210  if (hhv > 0) {
211  hv = hv * 16 + hhv;
212  pos++;
213  }
214  cret += QChar( hv );
215  }
216  break;
217  }
218  default:
219  if (c.toLatin1() >= '0' && c.toAscii() <= '7') {
220  char cAscii = c.toLatin1();
221  int hv = cAscii - '0';
222  for (int i = 0; i < 2; i++) {
223  if (pos >= args.length())
224  break;
225  c = args.unicode()[pos];
226  if (c.toLatin1() < '0' || c.toAscii() > '7')
227  break;
228  hv = hv * 8 + (c.toLatin1() - '0');
229  pos++;
230  }
231  cret += QChar( hv );
232  } else {
233  cret += QLatin1Char('\\');
234  cret += c;
235  }
236  break;
237  }
238  } else
239  cret += c;
240  }
241  } else {
242  if (c == QLatin1Char('\\')) {
243  if (pos >= args.length())
244  goto quoteerr;
245  c = args.unicode()[pos++];
246  } else if ((flags & AbortOnMeta) && isMeta( c ))
247  goto metaerr;
248  cret += c;
249  }
250  if (pos >= args.length())
251  break;
252  c = args.unicode()[pos++];
253  } while (!c.isSpace());
254  ret += cret;
255  firstword = false;
256  }
257 
258  okret:
259  if (err)
260  *err = NoError;
261  return ret;
262 
263  quoteerr:
264  if (err)
265  *err = BadQuoting;
266  return QStringList();
267 
268  metaerr:
269  if (err)
270  *err = FoundMeta;
271  return QStringList();
272 }
273 
274 inline static bool isSpecial( QChar cUnicode )
275 {
276  static const uchar iqm[] = {
277  0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
278  0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
279  }; // 0-32 \'"$`<>|;&(){}*?#!~[]
280 
281  uint c = cUnicode.unicode ();
282  return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
283 }
284 
285 QString KShell::quoteArg( const QString &arg )
286 {
287  if (!arg.length())
288  return QString::fromLatin1("''");
289  for (int i = 0; i < arg.length(); i++)
290  if (isSpecial( arg.unicode()[i] )) {
291  QChar q( QLatin1Char('\'') );
292  return QString( arg ).replace( q, QLatin1String("'\\''") ).prepend( q ).append( q );
293  }
294  return arg;
295 }
kuser.h
kshell_p.h
isSpecial
static bool isSpecial(QChar cUnicode)
Definition: kshell_unix.cpp:274
kshell.h
QString
KShell::splitArgs
QStringList splitArgs(const QString &cmd, Options flags=NoOptions, Errors *err=0)
Splits cmd according to system shell word splitting and quoting rules.
Definition: kshell_unix.cpp:70
KShell::FoundMeta
The AbortOnMeta flag was set and an unhandled shell meta character was encoutered.
Definition: kshell.h:100
QStringList
KShell::Errors
Errors
Status codes from splitArgs()
Definition: kshell.h:85
KShell::quoteArg
QString quoteArg(const QString &arg)
Quotes arg according to system shell rules.
Definition: kshell_unix.cpp:285
KShell::homeDir
QString homeDir(const QString &user)
Definition: kshell.cpp:29
KShell::BadQuoting
Indicates a parsing error, like an unterminated quoted string.
Definition: kshell.h:94
KShell::NoError
Success.
Definition: kshell.h:89
isMeta
static bool isMeta(QChar cUnicode)
Definition: kshell_unix.cpp:58
isQuoteMeta
static bool isQuoteMeta(QChar cUnicode)
Definition: kshell_unix.cpp:43
fromHex
static int fromHex(QChar cUnicode)
Definition: kshell_unix.cpp:30
KShell::AbortOnMeta
Put the parser into full shell mode and bail out if a too complex construct is encoutered.
Definition: kshell.h:78
KShell::TildeExpand
Perform tilde expansion.
Definition: kshell.h:47
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:47:09 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • 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