| //===-- Args.h --------------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef liblldb_Command_h_ |
| #define liblldb_Command_h_ |
| |
| // C Includes |
| // C++ Includes |
| #include <list> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| // Other libraries and framework includes |
| #include "llvm/ADT/ArrayRef.h" |
| #include "llvm/ADT/StringRef.h" |
| // Project includes |
| #include "lldb/Utility/Environment.h" |
| #include "lldb/Utility/Status.h" |
| #include "lldb/lldb-private-types.h" |
| #include "lldb/lldb-types.h" |
| |
| namespace lldb_private { |
| |
| typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector; |
| typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP; |
| |
| struct OptionArgElement { |
| enum { eUnrecognizedArg = -1, eBareDash = -2, eBareDoubleDash = -3 }; |
| |
| OptionArgElement(int defs_index, int pos, int arg_pos) |
| : opt_defs_index(defs_index), opt_pos(pos), opt_arg_pos(arg_pos) {} |
| |
| int opt_defs_index; |
| int opt_pos; |
| int opt_arg_pos; |
| }; |
| |
| typedef std::vector<OptionArgElement> OptionElementVector; |
| |
| //---------------------------------------------------------------------- |
| /// @class Args Args.h "lldb/Interpreter/Args.h" |
| /// @brief A command line argument class. |
| /// |
| /// The Args class is designed to be fed a command line. The |
| /// command line is copied into an internal buffer and then split up |
| /// into arguments. Arguments are space delimited if there are no quotes |
| /// (single, double, or backtick quotes) surrounding the argument. Spaces |
| /// can be escaped using a \ character to avoid having to surround an |
| /// argument that contains a space with quotes. |
| //---------------------------------------------------------------------- |
| class Args { |
| public: |
| struct ArgEntry { |
| private: |
| friend class Args; |
| std::unique_ptr<char[]> ptr; |
| |
| char *data() { return ptr.get(); } |
| |
| public: |
| ArgEntry() = default; |
| ArgEntry(llvm::StringRef str, char quote); |
| |
| llvm::StringRef ref; |
| char quote; |
| const char *c_str() const { return ptr.get(); } |
| }; |
| |
| //------------------------------------------------------------------ |
| /// Construct with an option command string. |
| /// |
| /// @param[in] command |
| /// A NULL terminated command that will be copied and split up |
| /// into arguments. |
| /// |
| /// @see Args::SetCommandString(llvm::StringRef) |
| //------------------------------------------------------------------ |
| Args(llvm::StringRef command = llvm::StringRef()); |
| |
| Args(const Args &rhs); |
| explicit Args(const StringList &list); |
| |
| Args &operator=(const Args &rhs); |
| |
| //------------------------------------------------------------------ |
| /// Destructor. |
| //------------------------------------------------------------------ |
| ~Args(); |
| |
| explicit Args(const Environment &env) : Args() { |
| SetArguments(const_cast<const char **>(env.getEnvp().get())); |
| } |
| |
| explicit operator Environment() const { return GetConstArgumentVector(); } |
| |
| //------------------------------------------------------------------ |
| /// Dump all entries to the stream \a s using label \a label_name. |
| /// |
| /// If label_name is nullptr, the dump operation is skipped. |
| /// |
| /// @param[in] s |
| /// The stream to which to dump all arguments in the argument |
| /// vector. |
| /// @param[in] label_name |
| /// The label_name to use as the label printed for each |
| /// entry of the args like so: |
| /// {label_name}[{index}]={value} |
| //------------------------------------------------------------------ |
| void Dump(Stream &s, const char *label_name = "argv") const; |
| |
| //------------------------------------------------------------------ |
| /// Sets the command string contained by this object. |
| /// |
| /// The command string will be copied and split up into arguments |
| /// that can be accessed via the accessor functions. |
| /// |
| /// @param[in] command |
| /// A command StringRef that will be copied and split up |
| /// into arguments. |
| /// |
| /// @see Args::GetArgumentCount() const |
| /// @see Args::GetArgumentAtIndex (size_t) const |
| /// @see Args::GetArgumentVector () |
| /// @see Args::Shift () |
| /// @see Args::Unshift (const char *) |
| //------------------------------------------------------------------ |
| void SetCommandString(llvm::StringRef command); |
| |
| bool GetCommandString(std::string &command) const; |
| |
| bool GetQuotedCommandString(std::string &command) const; |
| |
| //------------------------------------------------------------------ |
| /// Gets the number of arguments left in this command object. |
| /// |
| /// @return |
| /// The number or arguments in this object. |
| //------------------------------------------------------------------ |
| size_t GetArgumentCount() const; |
| bool empty() const { return GetArgumentCount() == 0; } |
| |
| //------------------------------------------------------------------ |
| /// Gets the NULL terminated C string argument pointer for the |
| /// argument at index \a idx. |
| /// |
| /// @return |
| /// The NULL terminated C string argument pointer if \a idx is a |
| /// valid argument index, NULL otherwise. |
| //------------------------------------------------------------------ |
| const char *GetArgumentAtIndex(size_t idx) const; |
| |
| llvm::ArrayRef<ArgEntry> entries() const { return m_entries; } |
| char GetArgumentQuoteCharAtIndex(size_t idx) const; |
| |
| using const_iterator = std::vector<ArgEntry>::const_iterator; |
| |
| const_iterator begin() const { return m_entries.begin(); } |
| const_iterator end() const { return m_entries.end(); } |
| |
| size_t size() const { return GetArgumentCount(); } |
| const ArgEntry &operator[](size_t n) const { return m_entries[n]; } |
| |
| //------------------------------------------------------------------ |
| /// Gets the argument vector. |
| /// |
| /// The value returned by this function can be used by any function |
| /// that takes and vector. The return value is just like \a argv |
| /// in the standard C entry point function: |
| /// \code |
| /// int main (int argc, const char **argv); |
| /// \endcode |
| /// |
| /// @return |
| /// An array of NULL terminated C string argument pointers that |
| /// also has a terminating NULL C string pointer |
| //------------------------------------------------------------------ |
| char **GetArgumentVector(); |
| |
| //------------------------------------------------------------------ |
| /// Gets the argument vector. |
| /// |
| /// The value returned by this function can be used by any function |
| /// that takes and vector. The return value is just like \a argv |
| /// in the standard C entry point function: |
| /// \code |
| /// int main (int argc, const char **argv); |
| /// \endcode |
| /// |
| /// @return |
| /// An array of NULL terminate C string argument pointers that |
| /// also has a terminating NULL C string pointer |
| //------------------------------------------------------------------ |
| const char **GetConstArgumentVector() const; |
| |
| //------------------------------------------------------------------ |
| /// Gets the argument as an ArrayRef. Note that the return value does *not* |
| /// have a nullptr const char * at the end, as the size of the list is |
| /// embedded in the ArrayRef object. |
| //------------------------------------------------------------------ |
| llvm::ArrayRef<const char *> GetArgumentArrayRef() const { |
| return llvm::makeArrayRef(m_argv).drop_back(); |
| } |
| |
| //------------------------------------------------------------------ |
| /// Appends a new argument to the end of the list argument list. |
| /// |
| /// @param[in] arg_cstr |
| /// The new argument as a NULL terminated C string. |
| /// |
| /// @param[in] quote_char |
| /// If the argument was originally quoted, put in the quote char here. |
| //------------------------------------------------------------------ |
| void AppendArgument(llvm::StringRef arg_str, char quote_char = '\0'); |
| |
| void AppendArguments(const Args &rhs); |
| |
| void AppendArguments(const char **argv); |
| |
| //------------------------------------------------------------------ |
| /// Insert the argument value at index \a idx to \a arg_cstr. |
| /// |
| /// @param[in] idx |
| /// The index of where to insert the argument. |
| /// |
| /// @param[in] arg_cstr |
| /// The new argument as a NULL terminated C string. |
| /// |
| /// @param[in] quote_char |
| /// If the argument was originally quoted, put in the quote char here. |
| /// |
| /// @return |
| /// The NULL terminated C string of the copy of \a arg_cstr. |
| //------------------------------------------------------------------ |
| void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, |
| char quote_char = '\0'); |
| |
| //------------------------------------------------------------------ |
| /// Replaces the argument value at index \a idx to \a arg_cstr |
| /// if \a idx is a valid argument index. |
| /// |
| /// @param[in] idx |
| /// The index of the argument that will have its value replaced. |
| /// |
| /// @param[in] arg_cstr |
| /// The new argument as a NULL terminated C string. |
| /// |
| /// @param[in] quote_char |
| /// If the argument was originally quoted, put in the quote char here. |
| //------------------------------------------------------------------ |
| void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, |
| char quote_char = '\0'); |
| |
| //------------------------------------------------------------------ |
| /// Deletes the argument value at index |
| /// if \a idx is a valid argument index. |
| /// |
| /// @param[in] idx |
| /// The index of the argument that will have its value replaced. |
| /// |
| //------------------------------------------------------------------ |
| void DeleteArgumentAtIndex(size_t idx); |
| |
| //------------------------------------------------------------------ |
| /// Sets the argument vector value, optionally copying all |
| /// arguments into an internal buffer. |
| /// |
| /// Sets the arguments to match those found in \a argv. All argument |
| /// strings will be copied into an internal buffers. |
| // |
| // FIXME: Handle the quote character somehow. |
| //------------------------------------------------------------------ |
| void SetArguments(size_t argc, const char **argv); |
| |
| void SetArguments(const char **argv); |
| |
| //------------------------------------------------------------------ |
| /// Shifts the first argument C string value of the array off the |
| /// argument array. |
| /// |
| /// The string value will be freed, so a copy of the string should |
| /// be made by calling Args::GetArgumentAtIndex (size_t) const |
| /// first and copying the returned value before calling |
| /// Args::Shift(). |
| /// |
| /// @see Args::GetArgumentAtIndex (size_t) const |
| //------------------------------------------------------------------ |
| void Shift(); |
| |
| //------------------------------------------------------------------ |
| /// Inserts a class owned copy of \a arg_cstr at the beginning of |
| /// the argument vector. |
| /// |
| /// A copy \a arg_cstr will be made. |
| /// |
| /// @param[in] arg_cstr |
| /// The argument to push on the front of the argument stack. |
| /// |
| /// @param[in] quote_char |
| /// If the argument was originally quoted, put in the quote char here. |
| //------------------------------------------------------------------ |
| void Unshift(llvm::StringRef arg_str, char quote_char = '\0'); |
| |
| //------------------------------------------------------------------ |
| // Clear the arguments. |
| // |
| // For re-setting or blanking out the list of arguments. |
| //------------------------------------------------------------------ |
| void Clear(); |
| |
| static const char *StripSpaces(std::string &s, bool leading = true, |
| bool trailing = true, |
| bool return_null_if_empty = true); |
| |
| static bool UInt64ValueIsValidForByteSize(uint64_t uval64, |
| size_t total_byte_size) { |
| if (total_byte_size > 8) |
| return false; |
| |
| if (total_byte_size == 8) |
| return true; |
| |
| const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1; |
| return uval64 <= max; |
| } |
| |
| static bool SInt64ValueIsValidForByteSize(int64_t sval64, |
| size_t total_byte_size) { |
| if (total_byte_size > 8) |
| return false; |
| |
| if (total_byte_size == 8) |
| return true; |
| |
| const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1; |
| const int64_t min = ~(max); |
| return min <= sval64 && sval64 <= max; |
| } |
| |
| static lldb::addr_t StringToAddress(const ExecutionContext *exe_ctx, |
| llvm::StringRef s, |
| lldb::addr_t fail_value, Status *error); |
| |
| static bool StringToBoolean(llvm::StringRef s, bool fail_value, |
| bool *success_ptr); |
| |
| static char StringToChar(llvm::StringRef s, char fail_value, |
| bool *success_ptr); |
| |
| static int64_t StringToOptionEnum(llvm::StringRef s, |
| OptionEnumValueElement *enum_values, |
| int32_t fail_value, Status &error); |
| |
| static lldb::ScriptLanguage |
| StringToScriptLanguage(llvm::StringRef s, lldb::ScriptLanguage fail_value, |
| bool *success_ptr); |
| |
| // TODO: Use StringRef |
| static Status StringToFormat(const char *s, lldb::Format &format, |
| size_t *byte_size_ptr); // If non-NULL, then a |
| // byte size can precede |
| // the format character |
| |
| static lldb::Encoding |
| StringToEncoding(llvm::StringRef s, |
| lldb::Encoding fail_value = lldb::eEncodingInvalid); |
| |
| static uint32_t StringToGenericRegister(llvm::StringRef s); |
| |
| static bool StringToVersion(llvm::StringRef string, uint32_t &major, |
| uint32_t &minor, uint32_t &update); |
| |
| static const char *GetShellSafeArgument(const FileSpec &shell, |
| const char *unsafe_arg, |
| std::string &safe_arg); |
| |
| // EncodeEscapeSequences will change the textual representation of common |
| // escape sequences like "\n" (two characters) into a single '\n'. It does |
| // this for all of the supported escaped sequences and for the \0ooo (octal) |
| // and \xXX (hex). The resulting "dst" string will contain the character |
| // versions of all supported escape sequences. The common supported escape |
| // sequences are: "\a", "\b", "\f", "\n", "\r", "\t", "\v", "\'", "\"", "\\". |
| |
| static void EncodeEscapeSequences(const char *src, std::string &dst); |
| |
| // ExpandEscapeSequences will change a string of possibly non-printable |
| // characters and expand them into text. So '\n' will turn into two characters |
| // like "\n" which is suitable for human reading. When a character is not |
| // printable and isn't one of the common in escape sequences listed in the |
| // help for EncodeEscapeSequences, then it will be encoded as octal. Printable |
| // characters are left alone. |
| static void ExpandEscapedCharacters(const char *src, std::string &dst); |
| |
| static std::string EscapeLLDBCommandArgument(const std::string &arg, |
| char quote_char); |
| |
| private: |
| std::vector<ArgEntry> m_entries; |
| std::vector<char *> m_argv; |
| }; |
| |
| } // namespace lldb_private |
| |
| #endif // liblldb_Command_h_ |