1 | /* |
2 | Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> |
3 | |
4 | Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008 |
5 | |
6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | This program 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 |
14 | GNU General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with this program; if not, write to the Free Software |
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
19 | 02110-1301 USA. |
20 | */ |
21 | |
22 | // Own |
23 | #include "ShellCommand.h" |
24 | |
25 | //some versions of gcc(4.3) require explicit include |
26 | #include <cstdlib> |
27 | |
28 | |
29 | using namespace Konsole; |
30 | |
31 | // expands environment variables in 'text' |
32 | // function copied from kdelibs/kio/kio/kurlcompletion.cpp |
33 | static bool expandEnv(QString & text); |
34 | |
35 | ShellCommand::ShellCommand(const QString & fullCommand) |
36 | { |
37 | bool inQuotes = false; |
38 | |
39 | QString builder; |
40 | |
41 | for ( int i = 0 ; i < fullCommand.count() ; i++ ) { |
42 | QChar ch = fullCommand[i]; |
43 | |
44 | const bool isLastChar = ( i == fullCommand.count() - 1 ); |
45 | const bool isQuote = ( ch == QLatin1Char('\'') || ch == QLatin1Char('\"') ); |
46 | |
47 | if ( !isLastChar && isQuote ) { |
48 | inQuotes = !inQuotes; |
49 | } else { |
50 | if ( (!ch.isSpace() || inQuotes) && !isQuote ) { |
51 | builder.append(ch); |
52 | } |
53 | |
54 | if ( (ch.isSpace() && !inQuotes) || ( i == fullCommand.count()-1 ) ) { |
55 | _arguments << builder; |
56 | builder.clear(); |
57 | } |
58 | } |
59 | } |
60 | } |
61 | ShellCommand::ShellCommand(const QString & command , const QStringList & arguments) |
62 | { |
63 | _arguments = arguments; |
64 | |
65 | if ( !_arguments.isEmpty() ) { |
66 | _arguments[0] = command; |
67 | } |
68 | } |
69 | QString ShellCommand::fullCommand() const |
70 | { |
71 | return _arguments.join(QLatin1Char(' ')); |
72 | } |
73 | QString ShellCommand::command() const |
74 | { |
75 | if ( !_arguments.isEmpty() ) { |
76 | return _arguments[0]; |
77 | } else { |
78 | return QString(); |
79 | } |
80 | } |
81 | QStringList ShellCommand::arguments() const |
82 | { |
83 | return _arguments; |
84 | } |
85 | bool ShellCommand::isRootCommand() const |
86 | { |
87 | Q_ASSERT(0); // not implemented yet |
88 | return false; |
89 | } |
90 | bool ShellCommand::isAvailable() const |
91 | { |
92 | Q_ASSERT(0); // not implemented yet |
93 | return false; |
94 | } |
95 | QStringList ShellCommand::expand(const QStringList & items) |
96 | { |
97 | QStringList result; |
98 | |
99 | for(const QString &item : items) { |
100 | result << expand(item); |
101 | } |
102 | |
103 | return result; |
104 | } |
105 | QString ShellCommand::expand(const QString & text) |
106 | { |
107 | QString result = text; |
108 | expandEnv(result); |
109 | return result; |
110 | } |
111 | |
112 | /* |
113 | * expandEnv |
114 | * |
115 | * Expand environment variables in text. Escaped '$' characters are ignored. |
116 | * Return true if any variables were expanded |
117 | */ |
118 | static bool expandEnv( QString & text ) |
119 | { |
120 | // Find all environment variables beginning with '$' |
121 | // |
122 | int pos = 0; |
123 | |
124 | bool expanded = false; |
125 | |
126 | while ( (pos = text.indexOf(QLatin1Char('$'), pos)) != -1 ) { |
127 | |
128 | // Skip escaped '$' |
129 | // |
130 | if ( pos > 0 && text.at(pos-1) == QLatin1Char('\\') ) { |
131 | pos++; |
132 | } |
133 | // Variable found => expand |
134 | // |
135 | else { |
136 | // Find the end of the variable = next '/' or ' ' |
137 | // |
138 | int pos2 = text.indexOf( QLatin1Char(' '), pos+1 ); |
139 | int pos_tmp = text.indexOf( QLatin1Char('/'), pos+1 ); |
140 | |
141 | if ( pos2 == -1 || (pos_tmp != -1 && pos_tmp < pos2) ) { |
142 | pos2 = pos_tmp; |
143 | } |
144 | |
145 | if ( pos2 == -1 ) { |
146 | pos2 = text.length(); |
147 | } |
148 | |
149 | // Replace if the variable is terminated by '/' or ' ' |
150 | // and defined |
151 | // |
152 | if ( pos2 >= 0 ) { |
153 | int len = pos2 - pos; |
154 | QString key = text.mid( pos+1, len-1); |
155 | QString value = |
156 | QString::fromLocal8Bit( qgetenv(key.toLocal8Bit().constData()) ); |
157 | |
158 | if ( !value.isEmpty() ) { |
159 | expanded = true; |
160 | text.replace( pos, len, value ); |
161 | pos = pos + value.length(); |
162 | } else { |
163 | pos = pos2; |
164 | } |
165 | } |
166 | } |
167 | } |
168 | |
169 | return expanded; |
170 | } |
171 | |