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

KDECore

kmacroexpander_unix.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the KDE libraries
00003 
00004     Copyright (c) 2002-2003 Oswald Buddenhagen <ossi@kde.org>
00005     Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kmacroexpander_p.h"
00024 
00025 #include "kshell.h"
00026 
00027 #include <QtCore/QStringList>
00028 #include <QtCore/QStack>
00029 #include <QtCore/QRegExp>
00030 
00031 namespace KMacroExpander {
00032 
00033     enum Quoting { noquote, singlequote, doublequote, dollarquote, 
00034                    paren, subst, group, math };
00035     typedef struct {
00036         Quoting current;
00037         bool dquote;
00038     } State;
00039     typedef struct {
00040         QString str;
00041         int pos;
00042     } Save;
00043 
00044 }
00045 
00046 using namespace KMacroExpander;
00047 
00048 bool KMacroExpanderBase::expandMacrosShellQuote( QString &str, int &pos )
00049 {
00050     int len;
00051     int pos2;
00052     QChar ec( d->escapechar );
00053     State state = { noquote, false };
00054     QStack<State> sstack;
00055     QStack<Save> ostack;
00056     QStringList rst;
00057     QString rsts;
00058 
00059     while (pos < str.length()) {
00060         QChar cc( str.unicode()[pos] );
00061         if (ec != QLatin1Char(0)) {
00062             if (cc != ec)
00063                 goto nohit;
00064             if (!(len = expandEscapedMacro( str, pos, rst )))
00065                 goto nohit;
00066         } else {
00067             if (!(len = expandPlainMacro( str, pos, rst )))
00068                 goto nohit;
00069         }
00070             if (len < 0) {
00071                 pos -= len;
00072                 continue;
00073             }
00074             if (state.dquote) {
00075                 rsts = rst.join( QLatin1String(" ") );
00076                 rsts.replace( QRegExp(QLatin1String("([$`\"\\\\])")), QLatin1String("\\\\1") );
00077             } else if (state.current == dollarquote) {
00078                 rsts = rst.join( QLatin1String(" ") );
00079                 rsts.replace( QRegExp(QLatin1String("(['\\\\])")), QLatin1String("\\\\1") );
00080             } else if (state.current == singlequote) {
00081                 rsts = rst.join( QLatin1String(" ") );
00082                 rsts.replace( QLatin1Char('\''), QLatin1String("'\\''") );
00083             } else {
00084                 if (rst.isEmpty()) {
00085                     str.remove( pos, len );
00086                     continue;
00087                 } else {
00088                     rsts = KShell::joinArgs( rst );
00089                 }
00090             }
00091             rst.clear();
00092             str.replace( pos, len, rsts );
00093             pos += rsts.length();
00094             continue;
00095       nohit:
00096         if (state.current == singlequote) {
00097             if (cc == QLatin1Char('\''))
00098                 state = sstack.pop();
00099         } else if (cc == QLatin1Char('\\')) {
00100             // always swallow the char -> prevent anomalies due to expansion
00101             pos += 2;
00102             continue;
00103         } else if (state.current == dollarquote) {
00104             if (cc == QLatin1Char('\''))
00105                 state = sstack.pop();
00106         } else if (cc == QLatin1Char('$')) {
00107             cc = str[++pos];
00108             if (cc == QLatin1Char('(')) {
00109                 sstack.push( state );
00110                 if (str[pos + 1] == QLatin1Char('(')) {
00111                     Save sav = { str, pos + 2 };
00112                     ostack.push( sav );
00113                     state.current = math;
00114                     pos += 2;
00115                     continue;
00116                 } else {
00117                     state.current = paren;
00118                     state.dquote = false;
00119                 }
00120             } else if (cc == QLatin1Char('{')) {
00121                 sstack.push( state );
00122                 state.current = subst;
00123             } else if (!state.dquote) {
00124                 if (cc == QLatin1Char('\'')) {
00125                     sstack.push( state );
00126                     state.current = dollarquote;
00127                 } else if (cc == QLatin1Char('"')) {
00128                     sstack.push( state );
00129                     state.current = doublequote;
00130                     state.dquote = true;
00131                 }
00132             }
00133             // always swallow the char -> prevent anomalies due to expansion
00134         } else if (cc == QLatin1Char('`')) {
00135             str.replace( pos, 1, QLatin1String("$( " )); // add space -> avoid creating $((
00136             pos2 = pos += 3;
00137             for (;;) {
00138                 if (pos2 >= str.length()) {
00139                     pos = pos2;
00140                     return false;
00141                 }
00142                 cc = str.unicode()[pos2];
00143                 if (cc == QLatin1Char('`'))
00144                     break;
00145                 if (cc == QLatin1Char('\\')) {
00146                     cc = str[++pos2];
00147                     if (cc == QLatin1Char('$') || cc == QLatin1Char('`') || cc == QLatin1Char('\\') ||
00148                         (cc == QLatin1Char('"') && state.dquote))
00149                     {
00150                         str.remove( pos2 - 1, 1 );
00151                         continue;
00152                     }
00153                 }
00154                 pos2++;
00155             }
00156             str[pos2] = QLatin1Char(')');
00157             sstack.push( state );
00158             state.current = paren;
00159             state.dquote = false;
00160             continue;
00161         } else if (state.current == doublequote) {
00162             if (cc == QLatin1Char('"'))
00163                 state = sstack.pop();
00164         } else if (cc == QLatin1Char('\'')) {
00165             if (!state.dquote) {
00166                 sstack.push( state );
00167                 state.current = singlequote;
00168             }
00169         } else if (cc == QLatin1Char('"')) {
00170             if (!state.dquote) {
00171                 sstack.push( state );
00172                 state.current = doublequote;
00173                 state.dquote = true;
00174             }
00175         } else if (state.current == subst) {
00176             if (cc == QLatin1Char('}'))
00177                 state = sstack.pop();
00178         } else if (cc == QLatin1Char(')')) {
00179             if (state.current == math) {
00180                 if (str[pos + 1] == QLatin1Char(')')) {
00181                     state = sstack.pop();
00182                     pos += 2;
00183                 } else {
00184                     // false hit: the $(( was a $( ( in fact
00185                     // ash does not care, but bash does
00186                     pos = ostack.top().pos;
00187                     str = ostack.top().str;
00188                     ostack.pop();
00189                     state.current = paren;
00190                     state.dquote = false;
00191                     sstack.push( state );
00192                 }
00193                 continue;
00194             } else if (state.current == paren)
00195                 state = sstack.pop();
00196             else
00197                 break;
00198         } else if (cc == QLatin1Char('}')) {
00199             if (state.current == KMacroExpander::group)
00200                 state = sstack.pop();
00201             else
00202                 break;
00203         } else if (cc == QLatin1Char('(')) {
00204             sstack.push( state );
00205             state.current = paren;
00206         } else if (cc == QLatin1Char('{')) {
00207             sstack.push( state );
00208             state.current = KMacroExpander::group;
00209         }
00210         pos++;
00211     }
00212     return sstack.empty();
00213 }

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
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
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