13#include "llvm/ADT/StringSwitch.h" 
   24                                         std::string &result) {
 
   26  static const char *k_escapable_characters = 
"\"\\";
 
   29    size_t regular = quoted.find_first_of(k_escapable_characters);
 
   30    result += quoted.substr(0, regular);
 
   31    quoted = quoted.substr(regular);
 
   34    if (quoted.empty() || quoted.front() == 
'"')
 
   38    quoted = quoted.drop_front();
 
   48    if (strchr(k_escapable_characters, quoted.front()) == 
nullptr)
 
   51    result += quoted.front();
 
   52    quoted = quoted.drop_front();
 
 
   69static llvm::StringRef 
ltrimForArgs(llvm::StringRef str, 
size_t &shift) {
 
   70  static const char *k_space_separators = 
" \t";
 
   71  llvm::StringRef result = str.ltrim(k_space_separators);
 
   72  shift = result.data() - str.data();
 
 
   81static std::tuple<std::string, char, llvm::StringRef>
 
   94  char first_quote_char = 
'\0';
 
   96  bool arg_complete = 
false;
 
   99    size_t regular = command.find_first_of(
" \t\r\"'`\\");
 
  100    arg += command.substr(0, regular);
 
  101    command = command.substr(regular);
 
  106    char special = command.front();
 
  107    command = command.drop_front();
 
  110      if (command.empty()) {
 
  117      if (strchr(
" \t\\'\"`", command.front()) == 
nullptr)
 
  120      arg += command.front();
 
  121      command = command.drop_front();
 
  137      if (first_quote_char == 
'\0')
 
  138        first_quote_char = special;
 
  145        size_t quoted = command.find(special);
 
  146        arg += command.substr(0, quoted);
 
  147        command = command.substr(quoted);
 
  151      if (!command.empty())
 
  152        command = command.drop_front();
 
  156  } 
while (!arg_complete);
 
  158  return std::make_tuple(arg, first_quote_char, command);
 
 
  162                         std::optional<uint16_t> 
column)
 
  164  size_t size = str.size();
 
  167  ::memcpy(
data(), str.data() ? str.data() : 
"", 
size);
 
 
  177  for (
const std::string &arg : list)
 
 
  182  for (llvm::StringRef arg : args)
 
 
  192    m_entries.emplace_back(entry.ref(), entry.quote, entry.column);
 
  195  m_argv.push_back(
nullptr);
 
 
  209    s.
Format(
"{0}[{1}]=\"{2}\"\n", label_name, i++, entry.ref());
 
  211  s.
Format(
"{0}[{1}]=NULL\n", label_name, i);
 
 
  218  for (
size_t i = 0; i < 
m_entries.size(); ++i) {
 
 
  235  for (
size_t i = 0; i < 
m_entries.size(); ++i) {
 
 
  261  while (!command.empty()) {
 
  262    const char *prev = command.data();
 
  264    m_entries.emplace_back(arg, quote, column);
 
  268    column += command.data() - prev;
 
  270  m_argv.push_back(
nullptr);
 
 
  291  return (
m_argv.size() > 1) ? 
const_cast<const char **
>(
m_argv.data())
 
 
  309  assert(
m_argv.back() == 
nullptr);
 
  312    m_entries.emplace_back(entry.ref(), entry.quote, entry.column);
 
  315  m_argv.push_back(
nullptr);
 
 
  322  assert(
m_argv.back() == 
nullptr);
 
  324  for (
auto arg : llvm::ArrayRef(argv, argc)) {
 
  325    m_entries.emplace_back(arg, 
'\0', std::nullopt);
 
  329  m_argv.push_back(
nullptr);
 
 
  339  assert(
m_argv.back() == 
nullptr);
 
 
  350  assert(
m_argv.back() == 
nullptr);
 
 
  370  auto args = llvm::ArrayRef(argv, argc);
 
  373  for (
size_t i = 0; i < args.size(); ++i) {
 
  375        ((args[i][0] == 
'\'') || (args[i][0] == 
'"') || (args[i][0] == 
'`'))
 
 
  391  m_argv.push_back(
nullptr);
 
 
  395                                       llvm::StringRef unsafe_arg) {
 
  396  struct ShellDescriptor {
 
  397    llvm::StringRef m_basename;
 
  398    llvm::StringRef m_escapables;
 
  401  static ShellDescriptor g_Shells[] = {{
"bash", 
" '\"<>()&;"},
 
  402                                       {
"fish", 
" '\"<>()&\\|;"},
 
  403                                       {
"tcsh", 
" '\"<>()&;"},
 
  404                                       {
"zsh", 
" '\"<>()&;\\|"},
 
  405                                       {
"sh", 
" '\"<>()&;"}};
 
  408  llvm::StringRef escapables = 
" '\"";
 
  411  if (!basename.empty()) {
 
  412    for (
const auto &Shell : g_Shells) {
 
  413      if (Shell.m_basename == basename) {
 
  414        escapables = Shell.m_escapables;
 
  420  std::string safe_arg;
 
  421  safe_arg.reserve(unsafe_arg.size());
 
  423  for (
char c : unsafe_arg) {
 
  424    if (escapables.contains(c))
 
  425      safe_arg.push_back(
'\\');
 
  426    safe_arg.push_back(c);
 
 
  433  return llvm::StringSwitch<lldb::Encoding>(s)
 
  438      .Default(fail_value);
 
 
  444  uint32_t result = llvm::StringSwitch<uint32_t>(s)
 
 
  466    for (
const char *p = src; *p != 
'\0'; ++p) {
 
  467      size_t non_special_chars = ::strcspn(p, 
"\\");
 
  468      if (non_special_chars > 0) {
 
  469        dst.append(p, non_special_chars);
 
  470        p += non_special_chars;
 
  513            char oct_str[5] = {
'\0', 
'\0', 
'\0', 
'\0', 
'\0'};
 
  516            for (i = 0; (p[i] >= 
'0' && p[i] <= 
'7') && i < 4; ++i)
 
  523            unsigned long octal_value = ::strtoul(oct_str, 
nullptr, 8);
 
  524            if (octal_value <= UINT8_MAX) {
 
  525              dst.append(1, 
static_cast<char>(octal_value));
 
  532          if (isxdigit(p[1])) {
 
  537            char hex_str[3] = {*p, 
'\0', 
'\0'};
 
  538            if (isxdigit(p[1])) {
 
  543            unsigned long hex_value = strtoul(hex_str, 
nullptr, 16);
 
  544            if (hex_value <= UINT8_MAX)
 
  545              dst.append(1, 
static_cast<char>(hex_value));
 
 
  565    for (
const char *p = src; *p != 
'\0'; ++p) {
 
  566      if (llvm::isPrint(*p))
 
  604          snprintf(octal_str, 
sizeof(octal_str), 
"%o", *p);
 
  605          dst.append(octal_str);
 
 
  615  const char *chars_to_escape = 
nullptr;
 
  616  switch (quote_char) {
 
  618    chars_to_escape = 
" \t\\'\"`";
 
  621    chars_to_escape = 
"$\"`\\";
 
  627    assert(
false && 
"Unhandled quote character");
 
  632  res.reserve(arg.size());
 
  634    if (::strchr(chars_to_escape, c))
 
 
  646  const llvm::StringRef original_args = arg_string;
 
  655  if (!arg_string.starts_with(
"-")) {
 
  656    m_suffix = std::string(original_args);
 
  660  bool found_suffix = 
false;
 
  661  while (!arg_string.empty()) {
 
  663    std::size_t prev_prefix_length = original_args.size() - arg_string.size();
 
  671    if (!entry.
IsQuoted() && arg == 
"--") {
 
  679      std::size_t prefix_length = original_args.size() - arg_string.size();
 
  683      llvm::StringRef prefix = original_args.take_front(prev_prefix_length);
 
  700    m_suffix = std::string(original_args);
 
 
static std::tuple< std::string, char, llvm::StringRef > ParseSingleArgument(llvm::StringRef command)
static llvm::StringRef ltrimForArgs(llvm::StringRef str, size_t &shift)
static size_t ArgvToArgc(const char **argv)
static llvm::StringRef ParseDoubleQuotes(llvm::StringRef quoted, std::string &result)
A command line argument class.
char ** GetArgumentVector()
Gets the argument vector.
void Dump(Stream &s, const char *label_name="argv") const
Dump all entries to the stream s using label label_name.
static std::string EscapeLLDBCommandArgument(const std::string &arg, char quote_char)
void Unshift(llvm::StringRef arg_str, char quote_char='\0')
Inserts a class owned copy of arg_str at the beginning of the argument vector.
void Shift()
Shifts the first argument C string value of the array off the argument array.
void DeleteArgumentAtIndex(size_t idx)
Deletes the argument value at index if idx is a valid argument index.
static void ExpandEscapedCharacters(const char *src, std::string &dst)
ExpandEscapeSequences will change a string of possibly non-printable characters and expand them into ...
void SetArguments(size_t argc, const char **argv)
Sets the argument vector value, optionally copying all arguments into an internal buffer.
void AppendArguments(const Args &rhs)
static lldb::Encoding StringToEncoding(llvm::StringRef s, lldb::Encoding fail_value=lldb::eEncodingInvalid)
static uint32_t StringToGenericRegister(llvm::StringRef s)
Args(llvm::StringRef command=llvm::StringRef())
Construct with an option command string.
Args & operator=(const Args &rhs)
std::vector< ArgEntry > m_entries
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
void SetCommandString(llvm::StringRef command)
Sets the command string contained by this object.
static void EncodeEscapeSequences(const char *src, std::string &dst)
EncodeEscapeSequences will change the textual representation of common escape sequences like "\n" (tw...
void ReplaceArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Replaces the argument value at index idx to arg_str if idx is a valid argument index.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
std::vector< char * > m_argv
The arguments as C strings with a trailing nullptr element.
static std::string GetShellSafeArgument(const FileSpec &shell, llvm::StringRef unsafe_arg)
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
bool GetCommandString(std::string &command) const
void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str, char quote_char='\0')
Insert the argument value at index idx to arg_str.
const char ** GetConstArgumentVector() const
Gets the argument vector.
bool GetQuotedCommandString(std::string &command) const
void Clear()
Clear the arguments.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const ConstString & GetFilename() const
Filename string const get accessor.
bool m_has_args
Keeps track if we have parsed and stored any arguments.
void SetFromString(llvm::StringRef arg_string)
OptionsWithRaw(llvm::StringRef argument_string)
Parse the given string as a list of optional arguments with a raw suffix.
llvm::StringRef m_arg_string
llvm::StringRef m_arg_string_with_delimiter
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t EOL()
Output and End of Line character to the stream.
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_ARG8
#define LLDB_REGNUM_GENERIC_ARG6
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_ARG7
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_TP
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_ARG5
A class that represents a running process on the host machine.
Encoding
Register encoding definitions.
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
@ eEncodingSint
signed integer
std::optional< uint16_t > column
The position of the argument in the original argument string.
std::unique_ptr< char[]> ptr
bool IsQuoted() const
Returns true if this argument was quoted in any way.