Args.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. //===-- Args.h --------------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLDB_UTILITY_ARGS_H
  9. #define LLDB_UTILITY_ARGS_H
  10. #include "lldb/Utility/Environment.h"
  11. #include "lldb/lldb-private-types.h"
  12. #include "lldb/lldb-types.h"
  13. #include "llvm/ADT/ArrayRef.h"
  14. #include "llvm/ADT/StringRef.h"
  15. #include "llvm/Support/YAMLTraits.h"
  16. #include <string>
  17. #include <utility>
  18. #include <vector>
  19. namespace lldb_private {
  20. /// \class Args Args.h "lldb/Utility/Args.h"
  21. /// A command line argument class.
  22. ///
  23. /// The Args class is designed to be fed a command line. The command line is
  24. /// copied into an internal buffer and then split up into arguments. Arguments
  25. /// are space delimited if there are no quotes (single, double, or backtick
  26. /// quotes) surrounding the argument. Spaces can be escaped using a \
  27. /// character to avoid having to surround an argument that contains a space
  28. /// with quotes.
  29. class Args {
  30. public:
  31. struct ArgEntry {
  32. private:
  33. friend class Args;
  34. friend struct llvm::yaml::MappingTraits<Args>;
  35. friend struct llvm::yaml::MappingTraits<Args::ArgEntry>;
  36. std::unique_ptr<char[]> ptr;
  37. char quote;
  38. char *data() { return ptr.get(); }
  39. public:
  40. ArgEntry() = default;
  41. ArgEntry(llvm::StringRef str, char quote);
  42. llvm::StringRef ref() const { return c_str(); }
  43. const char *c_str() const { return ptr.get(); }
  44. /// Returns true if this argument was quoted in any way.
  45. bool IsQuoted() const { return quote != '\0'; }
  46. char GetQuoteChar() const { return quote; }
  47. };
  48. /// Construct with an option command string.
  49. ///
  50. /// \param[in] command
  51. /// A NULL terminated command that will be copied and split up
  52. /// into arguments.
  53. ///
  54. /// \see Args::SetCommandString(llvm::StringRef)
  55. Args(llvm::StringRef command = llvm::StringRef());
  56. Args(const Args &rhs);
  57. explicit Args(const StringList &list);
  58. explicit Args(llvm::ArrayRef<llvm::StringRef> args);
  59. Args &operator=(const Args &rhs);
  60. /// Destructor.
  61. ~Args();
  62. explicit Args(const Environment &env) : Args() {
  63. SetArguments(const_cast<const char **>(env.getEnvp().get()));
  64. }
  65. explicit operator Environment() const { return GetConstArgumentVector(); }
  66. /// Dump all entries to the stream \a s using label \a label_name.
  67. ///
  68. /// If label_name is nullptr, the dump operation is skipped.
  69. ///
  70. /// \param[in] s
  71. /// The stream to which to dump all arguments in the argument
  72. /// vector.
  73. /// \param[in] label_name
  74. /// The label_name to use as the label printed for each
  75. /// entry of the args like so:
  76. /// {label_name}[{index}]={value}
  77. void Dump(Stream &s, const char *label_name = "argv") const;
  78. /// Sets the command string contained by this object.
  79. ///
  80. /// The command string will be copied and split up into arguments that can
  81. /// be accessed via the accessor functions.
  82. ///
  83. /// \param[in] command
  84. /// A command StringRef that will be copied and split up
  85. /// into arguments.
  86. ///
  87. /// \see Args::GetArgumentCount() const
  88. /// \see Args::GetArgumentAtIndex (size_t) const @see
  89. /// Args::GetArgumentVector () \see Args::Shift () \see Args::Unshift (const
  90. /// char *)
  91. void SetCommandString(llvm::StringRef command);
  92. bool GetCommandString(std::string &command) const;
  93. bool GetQuotedCommandString(std::string &command) const;
  94. /// Gets the number of arguments left in this command object.
  95. ///
  96. /// \return
  97. /// The number or arguments in this object.
  98. size_t GetArgumentCount() const { return m_entries.size(); }
  99. bool empty() const { return GetArgumentCount() == 0; }
  100. /// Gets the NULL terminated C string argument pointer for the argument at
  101. /// index \a idx.
  102. ///
  103. /// \return
  104. /// The NULL terminated C string argument pointer if \a idx is a
  105. /// valid argument index, NULL otherwise.
  106. const char *GetArgumentAtIndex(size_t idx) const;
  107. llvm::ArrayRef<ArgEntry> entries() const { return m_entries; }
  108. using const_iterator = std::vector<ArgEntry>::const_iterator;
  109. const_iterator begin() const { return m_entries.begin(); }
  110. const_iterator end() const { return m_entries.end(); }
  111. size_t size() const { return GetArgumentCount(); }
  112. const ArgEntry &operator[](size_t n) const { return m_entries[n]; }
  113. /// Gets the argument vector.
  114. ///
  115. /// The value returned by this function can be used by any function that
  116. /// takes and vector. The return value is just like \a argv in the standard
  117. /// C entry point function:
  118. /// \code
  119. /// int main (int argc, const char **argv);
  120. /// \endcode
  121. ///
  122. /// \return
  123. /// An array of NULL terminated C string argument pointers that
  124. /// also has a terminating NULL C string pointer
  125. char **GetArgumentVector();
  126. /// Gets the argument vector.
  127. ///
  128. /// The value returned by this function can be used by any function that
  129. /// takes and vector. The return value is just like \a argv in the standard
  130. /// C entry point function:
  131. /// \code
  132. /// int main (int argc, const char **argv);
  133. /// \endcode
  134. ///
  135. /// \return
  136. /// An array of NULL terminate C string argument pointers that
  137. /// also has a terminating NULL C string pointer
  138. const char **GetConstArgumentVector() const;
  139. /// Gets the argument as an ArrayRef. Note that the return value does *not*
  140. /// have a nullptr const char * at the end, as the size of the list is
  141. /// embedded in the ArrayRef object.
  142. llvm::ArrayRef<const char *> GetArgumentArrayRef() const {
  143. return llvm::makeArrayRef(m_argv).drop_back();
  144. }
  145. /// Appends a new argument to the end of the list argument list.
  146. ///
  147. /// \param[in] arg_str
  148. /// The new argument.
  149. ///
  150. /// \param[in] quote_char
  151. /// If the argument was originally quoted, put in the quote char here.
  152. void AppendArgument(llvm::StringRef arg_str, char quote_char = '\0');
  153. void AppendArguments(const Args &rhs);
  154. void AppendArguments(const char **argv);
  155. /// Insert the argument value at index \a idx to \a arg_str.
  156. ///
  157. /// \param[in] idx
  158. /// The index of where to insert the argument.
  159. ///
  160. /// \param[in] arg_str
  161. /// The new argument.
  162. ///
  163. /// \param[in] quote_char
  164. /// If the argument was originally quoted, put in the quote char here.
  165. void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
  166. char quote_char = '\0');
  167. /// Replaces the argument value at index \a idx to \a arg_str if \a idx is
  168. /// a valid argument index.
  169. ///
  170. /// \param[in] idx
  171. /// The index of the argument that will have its value replaced.
  172. ///
  173. /// \param[in] arg_str
  174. /// The new argument.
  175. ///
  176. /// \param[in] quote_char
  177. /// If the argument was originally quoted, put in the quote char here.
  178. void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
  179. char quote_char = '\0');
  180. /// Deletes the argument value at index
  181. /// if \a idx is a valid argument index.
  182. ///
  183. /// \param[in] idx
  184. /// The index of the argument that will have its value replaced.
  185. ///
  186. void DeleteArgumentAtIndex(size_t idx);
  187. /// Sets the argument vector value, optionally copying all arguments into an
  188. /// internal buffer.
  189. ///
  190. /// Sets the arguments to match those found in \a argv. All argument strings
  191. /// will be copied into an internal buffers.
  192. //
  193. // FIXME: Handle the quote character somehow.
  194. void SetArguments(size_t argc, const char **argv);
  195. void SetArguments(const char **argv);
  196. /// Shifts the first argument C string value of the array off the argument
  197. /// array.
  198. ///
  199. /// The string value will be freed, so a copy of the string should be made
  200. /// by calling Args::GetArgumentAtIndex (size_t) const first and copying the
  201. /// returned value before calling Args::Shift().
  202. ///
  203. /// \see Args::GetArgumentAtIndex (size_t) const
  204. void Shift();
  205. /// Inserts a class owned copy of \a arg_str at the beginning of the
  206. /// argument vector.
  207. ///
  208. /// A copy \a arg_str will be made.
  209. ///
  210. /// \param[in] arg_str
  211. /// The argument to push on the front of the argument stack.
  212. ///
  213. /// \param[in] quote_char
  214. /// If the argument was originally quoted, put in the quote char here.
  215. void Unshift(llvm::StringRef arg_str, char quote_char = '\0');
  216. /// Clear the arguments.
  217. ///
  218. /// For re-setting or blanking out the list of arguments.
  219. void Clear();
  220. static lldb::Encoding
  221. StringToEncoding(llvm::StringRef s,
  222. lldb::Encoding fail_value = lldb::eEncodingInvalid);
  223. static uint32_t StringToGenericRegister(llvm::StringRef s);
  224. static std::string GetShellSafeArgument(const FileSpec &shell,
  225. llvm::StringRef unsafe_arg);
  226. /// EncodeEscapeSequences will change the textual representation of common
  227. /// escape sequences like "\n" (two characters) into a single '\n'. It does
  228. /// this for all of the supported escaped sequences and for the \0ooo (octal)
  229. /// and \xXX (hex). The resulting "dst" string will contain the character
  230. /// versions of all supported escape sequences. The common supported escape
  231. /// sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\".
  232. static void EncodeEscapeSequences(const char *src, std::string &dst);
  233. /// ExpandEscapeSequences will change a string of possibly non-printable
  234. /// characters and expand them into text. So '\n' will turn into two
  235. /// characters like "\n" which is suitable for human reading. When a character
  236. /// is not printable and isn't one of the common in escape sequences listed in
  237. /// the help for EncodeEscapeSequences, then it will be encoded as octal.
  238. /// Printable characters are left alone.
  239. static void ExpandEscapedCharacters(const char *src, std::string &dst);
  240. static std::string EscapeLLDBCommandArgument(const std::string &arg,
  241. char quote_char);
  242. private:
  243. friend struct llvm::yaml::MappingTraits<Args>;
  244. std::vector<ArgEntry> m_entries;
  245. /// The arguments as C strings with a trailing nullptr element.
  246. ///
  247. /// These strings are owned by the ArgEntry object in m_entries with the
  248. /// same index.
  249. std::vector<char *> m_argv;
  250. };
  251. /// \class OptionsWithRaw Args.h "lldb/Utility/Args.h"
  252. /// A pair of an option list with a 'raw' string as a suffix.
  253. ///
  254. /// This class works similar to Args, but handles the case where we have a
  255. /// trailing string that shouldn't be interpreted as a list of arguments but
  256. /// preserved as is. It is also only useful for handling command line options
  257. /// (e.g. '-foo bar -i0') that start with a dash.
  258. ///
  259. /// The leading option list is optional. If the first non-space character
  260. /// in the string starts with a dash, and the string contains an argument
  261. /// that is an unquoted double dash (' -- '), then everything up to the double
  262. /// dash is parsed as a list of arguments. Everything after the double dash
  263. /// is interpreted as the raw suffix string. Note that the space behind the
  264. /// double dash is not part of the raw suffix.
  265. ///
  266. /// All strings not matching the above format as considered to be just a raw
  267. /// string without any options.
  268. ///
  269. /// \see Args
  270. class OptionsWithRaw {
  271. public:
  272. /// Parse the given string as a list of optional arguments with a raw suffix.
  273. ///
  274. /// See the class description for a description of the input format.
  275. ///
  276. /// \param[in] argument_string
  277. /// The string that should be parsed.
  278. explicit OptionsWithRaw(llvm::StringRef argument_string);
  279. /// Returns true if there are any arguments before the raw suffix.
  280. bool HasArgs() const { return m_has_args; }
  281. /// Returns the list of arguments.
  282. ///
  283. /// You can only call this method if HasArgs returns true.
  284. Args &GetArgs() {
  285. assert(m_has_args);
  286. return m_args;
  287. }
  288. /// Returns the list of arguments.
  289. ///
  290. /// You can only call this method if HasArgs returns true.
  291. const Args &GetArgs() const {
  292. assert(m_has_args);
  293. return m_args;
  294. }
  295. /// Returns the part of the input string that was used for parsing the
  296. /// argument list. This string also includes the double dash that is used
  297. /// for separating the argument list from the suffix.
  298. ///
  299. /// You can only call this method if HasArgs returns true.
  300. llvm::StringRef GetArgStringWithDelimiter() const {
  301. assert(m_has_args);
  302. return m_arg_string_with_delimiter;
  303. }
  304. /// Returns the part of the input string that was used for parsing the
  305. /// argument list.
  306. ///
  307. /// You can only call this method if HasArgs returns true.
  308. llvm::StringRef GetArgString() const {
  309. assert(m_has_args);
  310. return m_arg_string;
  311. }
  312. /// Returns the raw suffix part of the parsed string.
  313. const std::string &GetRawPart() const { return m_suffix; }
  314. private:
  315. void SetFromString(llvm::StringRef arg_string);
  316. /// Keeps track if we have parsed and stored any arguments.
  317. bool m_has_args = false;
  318. Args m_args;
  319. llvm::StringRef m_arg_string;
  320. llvm::StringRef m_arg_string_with_delimiter;
  321. // FIXME: This should be a StringRef, but some of the calling code expect a
  322. // C string here so only a real std::string is possible.
  323. std::string m_suffix;
  324. };
  325. } // namespace lldb_private
  326. namespace llvm {
  327. namespace yaml {
  328. template <> struct MappingTraits<lldb_private::Args::ArgEntry> {
  329. class NormalizedArgEntry {
  330. public:
  331. NormalizedArgEntry(IO &) {}
  332. NormalizedArgEntry(IO &, lldb_private::Args::ArgEntry &entry)
  333. : value(entry.ref()), quote(entry.quote) {}
  334. lldb_private::Args::ArgEntry denormalize(IO &) {
  335. return lldb_private::Args::ArgEntry(value, quote);
  336. }
  337. StringRef value;
  338. uint8_t quote;
  339. };
  340. static void mapping(IO &io, lldb_private::Args::ArgEntry &v);
  341. };
  342. template <> struct MappingTraits<lldb_private::Args> {
  343. static void mapping(IO &io, lldb_private::Args &v);
  344. };
  345. } // namespace yaml
  346. } // namespace llvm
  347. LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::Args::ArgEntry)
  348. #endif // LLDB_UTILITY_ARGS_H