//===-- Args.h --------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UTILITY_ARGS_H
#define LLDB_UTILITY_ARGS_H

#include "lldb/Utility/Environment.h"
#include "lldb/lldb-private-types.h"
#include "lldb/lldb-types.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/YAMLTraits.h"
#include <string>
#include <utility>
#include <vector>

namespace lldb_private {

/// \class Args Args.h "lldb/Utility/Args.h"
/// 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;
    friend struct llvm::yaml::MappingTraits<Args>;
    friend struct llvm::yaml::MappingTraits<Args::ArgEntry>;

    std::unique_ptr<char[]> ptr;
    char quote;

    char *data() { return ptr.get(); }

  public:
    ArgEntry() = default;
    ArgEntry(llvm::StringRef str, char quote);

    llvm::StringRef ref() const { return c_str(); }
    const char *c_str() const { return ptr.get(); }

    /// Returns true if this argument was quoted in any way.
    bool IsQuoted() const { return quote != '\0'; }
    char GetQuoteChar() const { return quote; }
  };

  /// 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);
  explicit Args(llvm::ArrayRef<llvm::StringRef> args);

  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; }

  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_str
  ///     The new argument.
  ///
  /// \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_str.
  ///
  /// \param[in] idx
  ///     The index of where to insert the argument.
  ///
  /// \param[in] arg_str
  ///     The new argument.
  ///
  /// \param[in] quote_char
  ///     If the argument was originally quoted, put in the quote char here.
  void InsertArgumentAtIndex(size_t idx, llvm::StringRef arg_str,
                             char quote_char = '\0');

  /// Replaces the argument value at index \a idx to \a arg_str 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_str
  ///     The new argument.
  ///
  /// \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_str at the beginning of the
  /// argument vector.
  ///
  /// A copy \a arg_str will be made.
  ///
  /// \param[in] arg_str
  ///     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 lldb::Encoding
  StringToEncoding(llvm::StringRef s,
                   lldb::Encoding fail_value = lldb::eEncodingInvalid);

  static uint32_t StringToGenericRegister(llvm::StringRef s);

  static std::string GetShellSafeArgument(const FileSpec &shell,
                                          llvm::StringRef unsafe_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:
  friend struct llvm::yaml::MappingTraits<Args>;

  std::vector<ArgEntry> m_entries;
  std::vector<char *> m_argv;
};

/// \class OptionsWithRaw Args.h "lldb/Utility/Args.h"
/// A pair of an option list with a 'raw' string as a suffix.
///
/// This class works similar to Args, but handles the case where we have a
/// trailing string that shouldn't be interpreted as a list of arguments but
/// preserved as is. It is also only useful for handling command line options
/// (e.g. '-foo bar -i0') that start with a dash.
///
/// The leading option list is optional. If the first non-space character
/// in the string starts with a dash, and the string contains an argument
/// that is an unquoted double dash (' -- '), then everything up to the double
/// dash is parsed as a list of arguments. Everything after the double dash
/// is interpreted as the raw suffix string. Note that the space behind the
/// double dash is not part of the raw suffix.
///
/// All strings not matching the above format as considered to be just a raw
/// string without any options.
///
/// \see Args
class OptionsWithRaw {
public:
  /// Parse the given string as a list of optional arguments with a raw suffix.
  ///
  /// See the class description for a description of the input format.
  ///
  /// \param[in] argument_string
  ///     The string that should be parsed.
  explicit OptionsWithRaw(llvm::StringRef argument_string);

  /// Returns true if there are any arguments before the raw suffix.
  bool HasArgs() const { return m_has_args; }

  /// Returns the list of arguments.
  ///
  /// You can only call this method if HasArgs returns true.
  Args &GetArgs() {
    assert(m_has_args);
    return m_args;
  }

  /// Returns the list of arguments.
  ///
  /// You can only call this method if HasArgs returns true.
  const Args &GetArgs() const {
    assert(m_has_args);
    return m_args;
  }

  /// Returns the part of the input string that was used for parsing the
  /// argument list. This string also includes the double dash that is used
  /// for separating the argument list from the suffix.
  ///
  /// You can only call this method if HasArgs returns true.
  llvm::StringRef GetArgStringWithDelimiter() const {
    assert(m_has_args);
    return m_arg_string_with_delimiter;
  }

  /// Returns the part of the input string that was used for parsing the
  /// argument list.
  ///
  /// You can only call this method if HasArgs returns true.
  llvm::StringRef GetArgString() const {
    assert(m_has_args);
    return m_arg_string;
  }

  /// Returns the raw suffix part of the parsed string.
  const std::string &GetRawPart() const { return m_suffix; }

private:
  void SetFromString(llvm::StringRef arg_string);

  /// Keeps track if we have parsed and stored any arguments.
  bool m_has_args = false;
  Args m_args;
  llvm::StringRef m_arg_string;
  llvm::StringRef m_arg_string_with_delimiter;

  // FIXME: This should be a StringRef, but some of the calling code expect a
  // C string here so only a real std::string is possible.
  std::string m_suffix;
};

} // namespace lldb_private

namespace llvm {
namespace yaml {
template <> struct MappingTraits<lldb_private::Args::ArgEntry> {
  class NormalizedArgEntry {
  public:
    NormalizedArgEntry(IO &) {}
    NormalizedArgEntry(IO &, lldb_private::Args::ArgEntry &entry)
        : value(entry.ref()), quote(entry.quote) {}
    lldb_private::Args::ArgEntry denormalize(IO &) {
      return lldb_private::Args::ArgEntry(value, quote);
    }
    StringRef value;
    uint8_t quote;
  };
  static void mapping(IO &io, lldb_private::Args::ArgEntry &v);
};
template <> struct MappingTraits<lldb_private::Args> {
  static void mapping(IO &io, lldb_private::Args &v);
};
} // namespace yaml
} // namespace llvm

LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::Args::ArgEntry)

#endif // LLDB_UTILITY_ARGS_H
