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
15class QString;
16
17/**
18 * \namespace KShell
19 * Emulates some basic system shell functionality.
20 * @see KStringHandler
21 */
22namespace KShell
23{
24/**
25 * Flags for splitArgs().
26 * @see Options
27 */
28enum 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 */
72Q_DECLARE_FLAGS(Options, Option)
73Q_DECLARE_OPERATORS_FOR_FLAGS(Options)
74
75/**
76 * Status codes from splitArgs()
77 */
78enum 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 */
138KCOREADDONS_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 */
151KCOREADDONS_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 */
171KCOREADDONS_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 */
185KCOREADDONS_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 */
195KCOREADDONS_EXPORT QString tildeCollapse(const QString &path);
196}
197
198#endif /* KSHELL_H */
199

source code of kcoreaddons/src/lib/util/kshell.h