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