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

KDECore

kshell_unix.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the KDE libraries
00003 
00004     Copyright (c) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019     Boston, MA 02110-1301, USA. 
00020 */
00021 
00022 #include "kshell.h"
00023 #include "kshell_p.h"
00024 
00025 #include <kuser.h>
00026 
00027 #include <QtCore/QChar>
00028 #include <QtCore/QStringList>
00029 
00030 static int fromHex( QChar cUnicode )
00031 {
00032     char c = cUnicode.toAscii ();
00033 
00034     if (c >= '0' && c <= '9')
00035         return c - '0';
00036     else if (c >= 'A' && c <= 'F')
00037         return c - 'A' + 10;
00038     else if (c >= 'a' && c <= 'f')
00039         return c - 'a' + 10;
00040     return -1;
00041 }
00042 
00043 inline static bool isQuoteMeta( QChar cUnicode )
00044 {
00045 #if 0 // it's not worth it, especially after seeing gcc's asm output ...
00046     static const uchar iqm[] = {
00047         0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
00048         0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00
00049     }; // \'"$
00050 
00051     return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
00052 #else
00053     char c = cUnicode.toAscii();
00054     return c == '\\' || c == '\'' || c == '"' || c == '$';
00055 #endif
00056 }
00057 
00058 inline static bool isMeta( QChar cUnicode )
00059 {
00060     static const uchar iqm[] = {
00061         0x00, 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00, 0xd8,
00062         0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x38
00063     }; // \'"$`<>|;&(){}*?#
00064 
00065     uint c = cUnicode.unicode();
00066 
00067     return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
00068 }
00069 
00070 QStringList KShell::splitArgs( const QString &args, Options flags, Errors *err)
00071 {
00072     QStringList ret;
00073     bool firstword = flags & AbortOnMeta;
00074 
00075     for (int pos = 0; ; ) {
00076         QChar c;
00077         do {
00078             if (pos >= args.length())
00079                 goto okret;
00080             c = args.unicode()[pos++];
00081         } while (c.isSpace());
00082         QString cret;
00083         if ((flags & TildeExpand) && c == QLatin1Char('~')) {
00084             int opos = pos;
00085             for (; ; pos++) {
00086                 if (pos >= args.length())
00087                     break;
00088                 c = args.unicode()[pos];
00089                 if (c == QLatin1Char('/') || c.isSpace())
00090                     break;
00091                 if (isQuoteMeta( c )) {
00092                     pos = opos;
00093                     c = QLatin1Char('~');
00094                     goto notilde;
00095                 }
00096                 if ((flags & AbortOnMeta) && isMeta( c ))
00097                     goto metaerr;
00098             }
00099             QString ccret = homeDir( args.mid(opos, pos-opos) );
00100             if (ccret.isEmpty()) {
00101                 pos = opos;
00102                 c = QLatin1Char('~');
00103                 goto notilde;
00104             }
00105             if (pos >= args.length()) {
00106                 ret += ccret;
00107                 goto okret;
00108             }
00109             pos++;
00110             if (c.isSpace()) {
00111                 ret += ccret;
00112                 firstword = false;
00113                 continue;
00114             }
00115             cret = ccret;
00116         }
00117         // before the notilde label, as a tilde does not match anyway
00118         if (firstword) {
00119             if (c == QLatin1Char('_') ||
00120                 (c >= QLatin1Char('A') && c <= QLatin1Char('Z')) ||
00121                 (c >= QLatin1Char('a') && c <= QLatin1Char('z')))
00122             {
00123                 int pos2 = pos;
00124                 QChar cc;
00125                 do {
00126                     if (pos2 >= args.length()) {
00127                         // Exactly one word
00128                         ret += args.mid(pos - 1);
00129                         goto okret;
00130                     }
00131                     cc = args[pos2++];
00132                 } while (cc == QLatin1Char('_') ||
00133                        (cc >= QLatin1Char('A') && cc <= QLatin1Char('Z')) ||
00134                        (cc >= QLatin1Char('a') && cc <= QLatin1Char('z')) ||
00135                        (cc >= QLatin1Char('0') && cc <= QLatin1Char('9')));
00136                 if (cc == QLatin1Char('='))
00137                     goto metaerr;
00138             }
00139         }
00140       notilde:
00141         do {
00142             if (c == QLatin1Char('\'')) {
00143                 int spos = pos;
00144                 do {
00145                     if (pos >= args.length())
00146                         goto quoteerr;
00147                     c = args.unicode()[pos++];
00148                 } while (c != QLatin1Char('\''));
00149                 cret += args.mid(spos, pos-spos-1);
00150             } else if (c == QLatin1Char('"')) {
00151                 for (;;) {
00152                     if (pos >= args.length())
00153                         goto quoteerr;
00154                     c = args.unicode()[pos++];
00155                     if (c == QLatin1Char('"'))
00156                         break;
00157                     if (c == QLatin1Char('\\')) {
00158                         if (pos >= args.length())
00159                             goto quoteerr;
00160                         c = args.unicode()[pos++];
00161                         if (c != QLatin1Char('"') &&
00162                             c != QLatin1Char('\\') &&
00163                             !((flags & AbortOnMeta) &&
00164                               (c == QLatin1Char('$') ||
00165                                c == QLatin1Char('`'))))
00166                             cret += QLatin1Char('\\');
00167                     } else if ((flags & AbortOnMeta) &&
00168                                 (c == QLatin1Char('$') ||
00169                                  c == QLatin1Char('`')))
00170                         goto metaerr;
00171                     cret += c;
00172                 }
00173             } else if (c == QLatin1Char('$') && args[pos] == QLatin1Char('\'')) {
00174                 pos++;
00175                 for (;;) {
00176                     if (pos >= args.length())
00177                         goto quoteerr;
00178                     c = args.unicode()[pos++];
00179                     if (c == QLatin1Char('\''))
00180                         break;
00181                     if (c == QLatin1Char('\\')) {
00182                         if (pos >= args.length())
00183                             goto quoteerr;
00184                         c = args.unicode()[pos++];
00185                         switch (c.toAscii()) {
00186                         case 'a': cret += QLatin1Char('\a'); break;
00187                         case 'b': cret += QLatin1Char('\b'); break;
00188                         case 'e': cret += QLatin1Char('\033'); break;
00189                         case 'f': cret += QLatin1Char('\f'); break;
00190                         case 'n': cret += QLatin1Char('\n'); break;
00191                         case 'r': cret += QLatin1Char('\r'); break;
00192                         case 't': cret += QLatin1Char('\t'); break;
00193                         case '\\': cret += QLatin1Char('\\'); break;
00194                         case '\'': cret += QLatin1Char('\''); break;
00195                         case 'c': cret += args[pos++].toAscii() & 31; break;
00196                         case 'x':
00197                           {
00198                             int hv = fromHex( args[pos] );
00199                             if (hv < 0) {
00200                                 cret += QLatin1String("\\x");
00201                             } else {
00202                                 int hhv = fromHex( args[++pos] );
00203                                 if (hhv > 0) {
00204                                     hv = hv * 16 + hhv;
00205                                     pos++;
00206                                 }
00207                                 cret += QChar( hv );
00208                             }
00209                             break;
00210                           }
00211                         default:
00212                             if (c.toAscii() >= '0' && c.toAscii() <= '7') {
00213                                 char cAscii = c.toAscii();
00214                                 int hv = cAscii - '0';
00215                                 for (int i = 0; i < 2; i++) {
00216                                     c = args[pos];
00217                                     if (c.toAscii() < '0' || c.toAscii() > '7')
00218                                         break;
00219                                     hv = hv * 8 + (c.toAscii() - '0');
00220                                     pos++;
00221                                 }
00222                                 cret += QChar( hv );
00223                             } else {
00224                                 cret += QLatin1Char('\\');
00225                                 cret += c;
00226                             }
00227                             break;
00228                         }
00229                     } else
00230                         cret += c;
00231                 }
00232             } else {
00233                 if (c == QLatin1Char('\\')) {
00234                     if (pos >= args.length())
00235                         goto quoteerr;
00236                     c = args.unicode()[pos++];
00237                 } else if ((flags & AbortOnMeta) && isMeta( c ))
00238                     goto metaerr;
00239                 cret += c;
00240             }
00241             if (pos >= args.length())
00242                 break;
00243             c = args.unicode()[pos++];
00244         } while (!c.isSpace());
00245         ret += cret;
00246         firstword = false;
00247     }
00248 
00249   okret:
00250     if (err)
00251         *err = NoError;
00252     return ret;
00253 
00254   quoteerr:
00255     if (err)
00256         *err = BadQuoting;
00257     return QStringList();
00258 
00259   metaerr:
00260     if (err)
00261         *err = FoundMeta;
00262     return QStringList();
00263 }
00264 
00265 inline static bool isSpecial( QChar cUnicode )
00266 {
00267     static const uchar iqm[] = {
00268         0xff, 0xff, 0xff, 0xff, 0xdd, 0x07, 0x00, 0xd8,
00269         0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x38
00270     }; // 0-32 \'"$`<>|;&(){}*?#
00271 
00272     uint c = cUnicode.unicode ();
00273     return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
00274 }
00275 
00276 QString KShell::quoteArg( const QString &arg )
00277 {
00278     if (!arg.length())
00279         return QString::fromLatin1("''");
00280     for (int i = 0; i < arg.length(); i++)
00281         if (isSpecial( arg.unicode()[i] )) {
00282             QChar q( QLatin1Char('\'') );
00283             return QString( arg ).replace( q, QLatin1String("'\\''") ).prepend( q ).append( q );
00284         }
00285     return arg;
00286 }

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal