• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • 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, 0x38, 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.unicode()[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('$') && pos < args.length() &&
00174                        args.unicode()[pos] == QLatin1Char('\'')) {
00175                 pos++;
00176                 for (;;) {
00177                     if (pos >= args.length())
00178                         goto quoteerr;
00179                     c = args.unicode()[pos++];
00180                     if (c == QLatin1Char('\''))
00181                         break;
00182                     if (c == QLatin1Char('\\')) {
00183                         if (pos >= args.length())
00184                             goto quoteerr;
00185                         c = args.unicode()[pos++];
00186                         switch (c.toAscii()) {
00187                         case 'a': cret += QLatin1Char('\a'); break;
00188                         case 'b': cret += QLatin1Char('\b'); break;
00189                         case 'e': cret += QLatin1Char('\033'); break;
00190                         case 'f': cret += QLatin1Char('\f'); break;
00191                         case 'n': cret += QLatin1Char('\n'); break;
00192                         case 'r': cret += QLatin1Char('\r'); break;
00193                         case 't': cret += QLatin1Char('\t'); break;
00194                         case '\\': cret += QLatin1Char('\\'); break;
00195                         case '\'': cret += QLatin1Char('\''); break;
00196                         case 'c':
00197                             if (pos >= args.length())
00198                                 goto quoteerr;
00199                             cret += args.unicode()[pos++].toAscii() & 31;
00200                             break;
00201                         case 'x':
00202                           {
00203                             if (pos >= args.length())
00204                                 goto quoteerr;
00205                             int hv = fromHex( args.unicode()[pos++] );
00206                             if (hv < 0)
00207                                 goto quoteerr;
00208                             if (pos < args.length()) {
00209                                 int hhv = fromHex( args.unicode()[pos] );
00210                                 if (hhv > 0) {
00211                                     hv = hv * 16 + hhv;
00212                                     pos++;
00213                                 }
00214                                 cret += QChar( hv );
00215                             }
00216                             break;
00217                           }
00218                         default:
00219                             if (c.toAscii() >= '0' && c.toAscii() <= '7') {
00220                                 char cAscii = c.toAscii();
00221                                 int hv = cAscii - '0';
00222                                 for (int i = 0; i < 2; i++) {
00223                                     if (pos >= args.length())
00224                                         break;
00225                                     c = args.unicode()[pos];
00226                                     if (c.toAscii() < '0' || c.toAscii() > '7')
00227                                         break;
00228                                     hv = hv * 8 + (c.toAscii() - '0');
00229                                     pos++;
00230                                 }
00231                                 cret += QChar( hv );
00232                             } else {
00233                                 cret += QLatin1Char('\\');
00234                                 cret += c;
00235                             }
00236                             break;
00237                         }
00238                     } else
00239                         cret += c;
00240                 }
00241             } else {
00242                 if (c == QLatin1Char('\\')) {
00243                     if (pos >= args.length())
00244                         goto quoteerr;
00245                     c = args.unicode()[pos++];
00246                 } else if ((flags & AbortOnMeta) && isMeta( c ))
00247                     goto metaerr;
00248                 cret += c;
00249             }
00250             if (pos >= args.length())
00251                 break;
00252             c = args.unicode()[pos++];
00253         } while (!c.isSpace());
00254         ret += cret;
00255         firstword = false;
00256     }
00257 
00258   okret:
00259     if (err)
00260         *err = NoError;
00261     return ret;
00262 
00263   quoteerr:
00264     if (err)
00265         *err = BadQuoting;
00266     return QStringList();
00267 
00268   metaerr:
00269     if (err)
00270         *err = FoundMeta;
00271     return QStringList();
00272 }
00273 
00274 inline static bool isSpecial( QChar cUnicode )
00275 {
00276     static const uchar iqm[] = {
00277         0xff, 0xff, 0xff, 0xff, 0xdf, 0x07, 0x00, 0xd8,
00278         0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x78
00279     }; // 0-32 \'"$`<>|;&(){}*?#!~[]
00280 
00281     uint c = cUnicode.unicode ();
00282     return (c < sizeof(iqm) * 8) && (iqm[c / 8] & (1 << (c & 7)));
00283 }
00284 
00285 QString KShell::quoteArg( const QString &arg )
00286 {
00287     if (!arg.length())
00288         return QString::fromLatin1("''");
00289     for (int i = 0; i < arg.length(); i++)
00290         if (isSpecial( arg.unicode()[i] )) {
00291             QChar q( QLatin1Char('\'') );
00292             return QString( arg ).replace( q, QLatin1String("'\\''") ).prepend( q ).append( q );
00293         }
00294     return arg;
00295 }

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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