1/*
2 This file is part of the KDE libraries
3
4 Copyright (c) 2003,2007 Oswald Buddenhagen <ossi@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library 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 GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21#ifndef KSHELL_H
22#define KSHELL_H
23
24#include <kdecore_export.h>
25
26class QStringList;
27class QString;
28
29/**
30 * \namespace KShell
31 * Emulates some basic system shell functionality.
32 * @see KStringHandler
33 */
34namespace KShell {
35
36 /**
37 * Flags for splitArgs().
38 */
39 enum Option {
40 NoOptions = 0,
41
42 /**
43 * Perform tilde expansion.
44 * On Windows, this flag is ignored, as the Windows shell has no
45 * equivalent functionality.
46 */
47 TildeExpand = 1,
48
49 /**
50 * Put the parser into full shell mode and bail out if a too complex
51 * construct is encoutered.
52 * A particular purpose of this flag is finding out whether the
53 * command line being split would be executable directly (via
54 * KProcess::setProgram()) or whether it needs to be run through
55 * a real shell (via KProcess::setShellCommand()). Note, however,
56 * that shell builtins are @em not recognized - you need to do that
57 * yourself (compare with a list of known commands or verify that an
58 * executable exists for the named command).
59 *
60 * Meta characters that cause a bail-out are the command separators
61 * @c semicolon and @c ampersand, the redirection symbols @c less-than,
62 * @c greater-than and the @c pipe @c symbol and the grouping symbols
63 * opening and closing @c parentheses.
64 *
65 * Further meta characters on *NIX are the grouping symbols
66 * opening and closing @c braces, the command substitution symbol
67 * @c backquote, the generic substitution symbol @c dollar (if
68 * not followed by an apostrophe), the wildcards @c asterisk,
69 * @c question @c mark and opening and closing @c square @c brackets
70 * and the comment symbol @c hash @c mark.
71 * Additionally, a variable assignment in the first word is recognized.
72 *
73 * A further meta character on Windows is the environment variable
74 * expansion symbol @c percent. Occurrences of @c \%PERCENT_SIGN% as
75 * inserted by quoteArg() are converted back and cause no bail-out,
76 * though.
77 */
78 AbortOnMeta = 2
79 };
80 Q_DECLARE_FLAGS(Options, Option)
81
82 /**
83 * Status codes from splitArgs()
84 */
85 enum Errors {
86 /**
87 * Success.
88 */
89 NoError = 0,
90
91 /**
92 * Indicates a parsing error, like an unterminated quoted string.
93 */
94 BadQuoting,
95
96 /**
97 * The AbortOnMeta flag was set and an unhandled shell meta character
98 * was encoutered.
99 */
100 FoundMeta
101 };
102
103 /**
104 * Splits @p cmd according to system shell word splitting and quoting rules.
105 * Can optionally perform tilde expansion and/or abort if it finds shell
106 * meta characters it cannot process.
107 *
108 * On *NIX the behavior is based on the POSIX shell and bash:
109 * - Whitespace splits tokens
110 * - The backslash quotes the following character
111 * - A string enclosed in single quotes is not split. No shell meta
112 * characters are interpreted.
113 * - A string enclosed in double quotes is not split. Within the string,
114 * the backslash quotes shell meta characters - if it is followed
115 * by a "meaningless" character, the backslash is output verbatim.
116 * - A string enclosed in $'' is not split. Within the string, the
117 * backslash has a similar meaning to the one in C strings. Consult
118 * the bash manual for more information.
119 *
120 * On Windows, the behavior is defined by the Microsoft C runtime. Qt and
121 * many other implementations comply with this standard, but many do not.
122 * - Whitespace splits tokens
123 * - A string enclosed in double quotes is not split
124 * - 2N double quotes within a quoted string yield N literal quotes.
125 * This is not documented on MSDN.
126 * - Backslashes have special semantics iff they are followed by a double
127 * quote:
128 * - 2N backslashes + double quote => N backslashes and begin/end quoting
129 * - 2N+1 backslashes + double quote => N backslashes + literal quote
130 *
131 * If AbortOnMeta is used on Windows, this function applies cmd shell
132 * semantics before proceeding with word splitting:
133 * - Cmd ignores @em all special chars between double quotes.
134 * Note that the quotes are @em not removed at this stage - the
135 * tokenization rules described above still apply.
136 * - The @c circumflex is the escape char for everything including
137 * itself.
138 *
139 * @param cmd the command to split
140 * @param flags operation flags, see \ref Option
141 * @param err if not NULL, a status code will be stored at the pointer
142 * target, see \ref Errors
143 * @return a list of unquoted words or an empty list if an error occurred
144 */
145 KDECORE_EXPORT QStringList splitArgs( const QString &cmd, Options flags = NoOptions, Errors *err = 0 );
146
147 /**
148 * Quotes and joins @p args together according to system shell rules.
149 *
150 * If the output is fed back into splitArgs(), the AbortOnMeta flag
151 * needs to be used on Windows. On *NIX, no such requirement exists.
152 *
153 * See quoteArg() for more info.
154 *
155 * @param args a list of strings to quote and join
156 * @return a command suitable for shell execution
157 */
158 KDECORE_EXPORT QString joinArgs( const QStringList &args );
159
160 /**
161 * Quotes @p arg according to system shell rules.
162 *
163 * This function can be used to quote an argument string such that
164 * the shell processes it properly. This is e.g. necessary for
165 * user-provided file names which may contain spaces or quotes.
166 * It also prevents expansion of wild cards and environment variables.
167 *
168 * On *NIX, the output is POSIX shell compliant.
169 * On Windows, it is compliant with the argument splitting code of the
170 * Microsoft C runtime and the cmd shell used together.
171 * Occurrences of the @c percent @c sign are replaced with
172 * @c \%PERCENT_SIGN% to prevent spurious variable expansion;
173 * related KDE functions are prepared for this.
174 *
175 * @param arg the argument to quote
176 * @return the quoted argument
177 */
178 KDECORE_EXPORT QString quoteArg( const QString &arg );
179
180 /**
181 * Performs tilde expansion on @p path. Interprets "~/path" and
182 * "~user/path". If the path starts with an escaped tilde ("\~" on UNIX,
183 * "^~" on Windows), the escape char is removed and the path is returned
184 * as is.
185 *
186 * Note that if @p path starts with a tilde but cannot be properly expanded,
187 * this function will return an empty string.
188 *
189 * @param path the path to tilde-expand
190 * @return the expanded path
191 */
192 KDECORE_EXPORT QString tildeExpand( const QString &path );
193}
194
195Q_DECLARE_OPERATORS_FOR_FLAGS(KShell::Options)
196
197#endif /* KSHELL_H */
198