File indexing completed on 2024-04-14 05:38:47

0001 /*******************************************************************************
0002  * Copyright (C) 2008-2013 Konstantinos Smanis <konstantinos.smanis@gmail.com> *
0003  *                                                                             *
0004  * This program is free software: you can redistribute it and/or modify it     *
0005  * under the terms of the GNU General Public License as published by the Free  *
0006  * Software Foundation, either version 3 of the License, or (at your option)   *
0007  * any later version.                                                          *
0008  *                                                                             *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT *
0010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
0011  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
0012  * more details.                                                               *
0013  *                                                                             *
0014  * You should have received a copy of the GNU General Public License along     *
0015  * with this program. If not, see <http://www.gnu.org/licenses/>.              *
0016  *******************************************************************************/
0017 
0018 //Own
0019 #include "common.h"
0020 
0021 //Qt
0022 #include <QTextStream>
0023 
0024 //KDE
0025 #include <KProcess>
0026 #include <KShell>
0027 
0028 QString quoteWord(const QString &word)
0029 {
0030     return !word.startsWith(QLatin1Char('`')) || !word.endsWith(QLatin1Char('`')) ? KShell::quoteArg(word) : word;
0031 }
0032 QString unquoteWord(const QString &word)
0033 {
0034     if (word.isEmpty()) {
0035         return QString();
0036     }
0037 
0038     KProcess echo;
0039     echo.setShellCommand(QStringLiteral("echo -n %1").arg(word));
0040     echo.setOutputChannelMode(KProcess::OnlyStdoutChannel);
0041     if (echo.execute() == 0) {
0042         return QString::fromLocal8Bit(echo.readAllStandardOutput().constData());
0043     }
0044 
0045     QChar ch;
0046     QString quotedWord = word, unquotedWord;
0047     QTextStream stream(&quotedWord, QIODevice::ReadOnly | QIODevice::Text);
0048     while (!stream.atEnd()) {
0049         stream >> ch;
0050         if (ch == QLatin1Char('\'')) {
0051             Q_FOREVER {
0052                 if (stream.atEnd()) {
0053                     return QString();
0054                 }
0055                 stream >> ch;
0056                 if (ch == QLatin1Char('\'')) {
0057                     return unquotedWord;
0058                 } else {
0059                     unquotedWord.append(ch);
0060                 }
0061             }
0062         } else if (ch == QLatin1Char('"')) {
0063             Q_FOREVER {
0064                 if (stream.atEnd()) {
0065                     return QString();
0066                 }
0067                 stream >> ch;
0068                 if (ch == QLatin1Char('\\')) {
0069                     if (stream.atEnd()) {
0070                         return QString();
0071                     }
0072                     stream >> ch;
0073                     switch (ch.toLatin1()) {
0074                         case '$':
0075                         case '"':
0076                         case '\\':
0077                             unquotedWord.append(ch);
0078                             break;
0079                         case '\n':
0080                             unquotedWord.append(QLatin1Char(' '));
0081                             break;
0082                         default:
0083                             unquotedWord.append(QLatin1Char('\\')).append(ch);
0084                             break;
0085                     }
0086                 } else if (ch == QLatin1Char('"')) {
0087                     return unquotedWord;
0088                 } else {
0089                     unquotedWord.append(ch);
0090                 }
0091             }
0092         } else {
0093             Q_FOREVER {
0094                 if (ch == QLatin1Char('\\')) {
0095                     if (stream.atEnd()) {
0096                         return unquotedWord;
0097                     }
0098                     stream >> ch;
0099                     switch (ch.toLatin1()) {
0100                         case '\n':
0101                             break;
0102                         default:
0103                             unquotedWord.append(ch);
0104                             break;
0105                     }
0106                 } else if (ch.isSpace()) {
0107                     return unquotedWord;
0108                 } else {
0109                     unquotedWord.append(ch);
0110                 }
0111                 if (stream.atEnd()) {
0112                     return unquotedWord;
0113                 }
0114                 stream >> ch;
0115             }
0116         }
0117     }
0118     return QString();
0119 }