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