File indexing completed on 2024-05-12 03:55:00
0001 /* 0002 This file is part of the KDE libraries 0003 0004 SPDX-FileCopyrightText: 2003, 2007 Oswald Buddenhagen <ossi@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 #ifndef KSHELL_H 0009 #define KSHELL_H 0010 0011 #include <QStringList> 0012 #include <kcoreaddons_export.h> 0013 #include <qglobal.h> 0014 0015 class QString; 0016 0017 /** 0018 * \namespace KShell 0019 * Emulates some basic system shell functionality. 0020 * @see KStringHandler 0021 */ 0022 namespace KShell 0023 { 0024 /** 0025 * Flags for splitArgs(). 0026 * @see Options 0027 */ 0028 enum Option { 0029 NoOptions = 0, 0030 0031 /** 0032 * Perform tilde expansion. 0033 * On Windows, this flag is ignored, as the Windows shell has no 0034 * equivalent functionality. 0035 */ 0036 TildeExpand = 1, 0037 0038 /** 0039 * Put the parser into full shell mode and bail out if a too complex 0040 * construct is encountered. 0041 * A particular purpose of this flag is finding out whether the 0042 * command line being split would be executable directly (via 0043 * KProcess::setProgram()) or whether it needs to be run through 0044 * a real shell (via KProcess::setShellCommand()). Note, however, 0045 * that shell builtins are @em not recognized - you need to do that 0046 * yourself (compare with a list of known commands or verify that an 0047 * executable exists for the named command). 0048 * 0049 * Meta characters that cause a bail-out are the command separators 0050 * @c semicolon and @c ampersand, the redirection symbols @c less-than, 0051 * @c greater-than and the @c pipe @c symbol and the grouping symbols 0052 * opening and closing @c parentheses. 0053 * 0054 * Further meta characters on *NIX are the grouping symbols 0055 * opening and closing @c braces, the command substitution symbol 0056 * @c backquote, the generic substitution symbol @c dollar (if 0057 * not followed by an apostrophe), the wildcards @c asterisk, 0058 * @c question @c mark and opening and closing @c square @c brackets 0059 * and the comment symbol @c hash @c mark. 0060 * Additionally, a variable assignment in the first word is recognized. 0061 * 0062 * A further meta character on Windows is the environment variable 0063 * expansion symbol @c percent. Occurrences of @c \%PERCENT_SIGN% as 0064 * inserted by quoteArg() are converted back and cause no bail-out, 0065 * though. 0066 */ 0067 AbortOnMeta = 2, 0068 }; 0069 /** 0070 * Stores a combination of #Option values. 0071 */ 0072 Q_DECLARE_FLAGS(Options, Option) 0073 Q_DECLARE_OPERATORS_FOR_FLAGS(Options) 0074 0075 /** 0076 * Status codes from splitArgs() 0077 */ 0078 enum Errors { 0079 /** 0080 * Success. 0081 */ 0082 NoError = 0, 0083 0084 /** 0085 * Indicates a parsing error, like an unterminated quoted string. 0086 */ 0087 BadQuoting, 0088 0089 /** 0090 * The AbortOnMeta flag was set and an unhandled shell meta character 0091 * was encountered. 0092 */ 0093 FoundMeta, 0094 }; 0095 0096 /** 0097 * Splits @p cmd according to system shell word splitting and quoting rules. 0098 * Can optionally perform tilde expansion and/or abort if it finds shell 0099 * meta characters it cannot process. 0100 * 0101 * On *NIX the behavior is based on the POSIX shell and bash: 0102 * - Whitespace splits tokens 0103 * - The backslash quotes the following character 0104 * - A string enclosed in single quotes is not split. No shell meta 0105 * characters are interpreted. 0106 * - A string enclosed in double quotes is not split. Within the string, 0107 * the backslash quotes shell meta characters - if it is followed 0108 * by a "meaningless" character, the backslash is output verbatim. 0109 * - A string enclosed in $'' is not split. Within the string, the 0110 * backslash has a similar meaning to the one in C strings. Consult 0111 * the bash manual for more information. 0112 * 0113 * On Windows, the behavior is defined by the Microsoft C runtime. Qt and 0114 * many other implementations comply with this standard, but many do not. 0115 * - Whitespace splits tokens 0116 * - A string enclosed in double quotes is not split 0117 * - 2N double quotes within a quoted string yield N literal quotes. 0118 * This is not documented on MSDN. 0119 * - Backslashes have special semantics iff they are followed by a double 0120 * quote: 0121 * - 2N backslashes + double quote => N backslashes and begin/end quoting 0122 * - 2N+1 backslashes + double quote => N backslashes + literal quote 0123 * 0124 * If AbortOnMeta is used on Windows, this function applies cmd shell 0125 * semantics before proceeding with word splitting: 0126 * - Cmd ignores @em all special chars between double quotes. 0127 * Note that the quotes are @em not removed at this stage - the 0128 * tokenization rules described above still apply. 0129 * - The @c circumflex is the escape char for everything including 0130 * itself. 0131 * 0132 * @param cmd the command to split 0133 * @param flags operation flags, see \ref Option 0134 * @param err if not NULL, a status code will be stored at the pointer 0135 * target, see \ref Errors 0136 * @return a list of unquoted words or an empty list if an error occurred 0137 */ 0138 KCOREADDONS_EXPORT QStringList splitArgs(const QString &cmd, Options flags = NoOptions, Errors *err = nullptr); 0139 0140 /** 0141 * Quotes and joins @p args together according to system shell rules. 0142 * 0143 * If the output is fed back into splitArgs(), the AbortOnMeta flag 0144 * needs to be used on Windows. On *NIX, no such requirement exists. 0145 * 0146 * See quoteArg() for more info. 0147 * 0148 * @param args a list of strings to quote and join 0149 * @return a command suitable for shell execution 0150 */ 0151 KCOREADDONS_EXPORT QString joinArgs(const QStringList &args); 0152 0153 /** 0154 * Quotes @p arg according to system shell rules. 0155 * 0156 * This function can be used to quote an argument string such that 0157 * the shell processes it properly. This is e.g. necessary for 0158 * user-provided file names which may contain spaces or quotes. 0159 * It also prevents expansion of wild cards and environment variables. 0160 * 0161 * On *NIX, the output is POSIX shell compliant. 0162 * On Windows, it is compliant with the argument splitting code of the 0163 * Microsoft C runtime and the cmd shell used together. 0164 * Occurrences of the @c percent @c sign are replaced with 0165 * @c \%PERCENT_SIGN% to prevent spurious variable expansion; 0166 * related KDE functions are prepared for this. 0167 * 0168 * @param arg the argument to quote 0169 * @return the quoted argument 0170 */ 0171 KCOREADDONS_EXPORT QString quoteArg(const QString &arg); 0172 0173 /** 0174 * Performs tilde expansion on @p path. Interprets "~/path" and 0175 * "~user/path". If the path starts with an escaped tilde ("\~" on UNIX, 0176 * "^~" on Windows), the escape char is removed and the path is returned 0177 * as is. 0178 * 0179 * Note that if @p path starts with a tilde but cannot be properly expanded, 0180 * this function will return an empty string. 0181 * 0182 * @param path the path to tilde-expand 0183 * @return the expanded path 0184 */ 0185 KCOREADDONS_EXPORT QString tildeExpand(const QString &path); 0186 0187 /** 0188 * Performs tilde collapse on @p path. If path did not start by the user 0189 * homedir returns path unchanged. 0190 * 0191 * @param path the path to tilde-collpase 0192 * @return the collapsed path 0193 * @since 5.67 0194 */ 0195 KCOREADDONS_EXPORT QString tildeCollapse(const QString &path); 0196 } 0197 0198 #endif /* KSHELL_H */