// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/escape.h"

#include <stddef.h>

#include "base/logging.h"
#include "build_config.h"

namespace {

// A "1" in this lookup table means that char is valid in the Posix shell.
const char kShellValid[0x80] = {
    // 00-1f: all are invalid
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0,
    // ' ' !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
    //  0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
    //  @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    //  P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
    //  `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    //  p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};

// Append one character to the given string, escaping it for Ninja.
//
// Ninja's escaping rules are very simple. We always escape colons even
// though they're OK in many places, in case the resulting string is used on
// the left-hand-side of a rule.
inline void NinjaEscapeChar(char ch, std::string* dest) {
  if (ch == '$' || ch == ' ' || ch == ':')
    dest->push_back('$');
  dest->push_back(ch);
}

void EscapeStringToString_Ninja(const base::StringPiece& str,
                                const EscapeOptions& options,
                                std::string* dest,
                                bool* needed_quoting) {
  for (const auto& elem : str)
    NinjaEscapeChar(elem, dest);
}

void EscapeStringToString_NinjaPreformatted(const base::StringPiece& str,
                                            std::string* dest) {
  // Only Ninja-escape $.
  for (const auto& elem : str) {
    if (elem == '$')
      dest->push_back('$');
    dest->push_back(elem);
  }
}

// Escape for CommandLineToArgvW and additionally escape Ninja characters.
//
// The basic algorithm is if the string doesn't contain any parse-affecting
// characters, don't do anything (other than the Ninja processing). If it does,
// quote the string, and backslash-escape all quotes and backslashes.
// See:
//   http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
//   http://blogs.msdn.com/b/oldnewthing/archive/2010/09/17/10063629.aspx
void EscapeStringToString_WindowsNinjaFork(const base::StringPiece& str,
                                           const EscapeOptions& options,
                                           std::string* dest,
                                           bool* needed_quoting) {
  // We assume we don't have any whitespace chars that aren't spaces.
  DCHECK(str.find_first_of("\r\n\v\t") == std::string::npos);

  if (str.find_first_of(" \"") == std::string::npos) {
    // Simple case, don't quote.
    EscapeStringToString_Ninja(str, options, dest, needed_quoting);
  } else {
    if (!options.inhibit_quoting)
      dest->push_back('"');

    for (size_t i = 0; i < str.size(); i++) {
      // Count backslashes in case they're followed by a quote.
      size_t backslash_count = 0;
      while (i < str.size() && str[i] == '\\') {
        i++;
        backslash_count++;
      }
      if (i == str.size()) {
        // Backslashes at end of string. Backslash-escape all of them since
        // they'll be followed by a quote.
        dest->append(backslash_count * 2, '\\');
      } else if (str[i] == '"') {
        // 0 or more backslashes followed by a quote. Backslash-escape the
        // backslashes, then backslash-escape the quote.
        dest->append(backslash_count * 2 + 1, '\\');
        dest->push_back('"');
      } else {
        // Non-special Windows character, just escape for Ninja. Also, add any
        // backslashes we read previously, these are literals.
        dest->append(backslash_count, '\\');
        NinjaEscapeChar(str[i], dest);
      }
    }

    if (!options.inhibit_quoting)
      dest->push_back('"');
    if (needed_quoting)
      *needed_quoting = true;
  }
}

void EscapeStringToString_PosixNinjaFork(const base::StringPiece& str,
                                         const EscapeOptions& options,
                                         std::string* dest,
                                         bool* needed_quoting) {
  for (const auto& elem : str) {
    if (elem == '$' || elem == ' ') {
      // Space and $ are special to both Ninja and the shell. '$' escape for
      // Ninja, then backslash-escape for the shell.
      dest->push_back('\\');
      dest->push_back('$');
      dest->push_back(elem);
    } else if (elem == ':') {
      // Colon is the only other Ninja special char, which is not special to
      // the shell.
      dest->push_back('$');
      dest->push_back(':');
    } else if (static_cast<unsigned>(elem) >= 0x80 ||
               !kShellValid[static_cast<int>(elem)]) {
      // All other invalid shell chars get backslash-escaped.
      dest->push_back('\\');
      dest->push_back(elem);
    } else {
      // Everything else is a literal.
      dest->push_back(elem);
    }
  }
}

void EscapeStringToString(const base::StringPiece& str,
                          const EscapeOptions& options,
                          std::string* dest,
                          bool* needed_quoting) {
  switch (options.mode) {
    case ESCAPE_NONE:
      dest->append(str.data(), str.size());
      break;
    case ESCAPE_NINJA:
      EscapeStringToString_Ninja(str, options, dest, needed_quoting);
      break;
    case ESCAPE_NINJA_COMMAND:
      switch (options.platform) {
        case ESCAPE_PLATFORM_CURRENT:
#if defined(OS_WIN)
          EscapeStringToString_WindowsNinjaFork(str, options, dest,
                                                needed_quoting);
#else
          EscapeStringToString_PosixNinjaFork(str, options, dest,
                                              needed_quoting);
#endif
          break;
        case ESCAPE_PLATFORM_WIN:
          EscapeStringToString_WindowsNinjaFork(str, options, dest,
                                                needed_quoting);
          break;
        case ESCAPE_PLATFORM_POSIX:
          EscapeStringToString_PosixNinjaFork(str, options, dest,
                                              needed_quoting);
          break;
        default:
          NOTREACHED();
      }
      break;
    case ESCAPE_NINJA_PREFORMATTED_COMMAND:
      EscapeStringToString_NinjaPreformatted(str, dest);
      break;
    default:
      NOTREACHED();
  }
}

}  // namespace

std::string EscapeString(const base::StringPiece& str,
                         const EscapeOptions& options,
                         bool* needed_quoting) {
  std::string result;
  result.reserve(str.size() + 4);  // Guess we'll add a couple of extra chars.
  EscapeStringToString(str, options, &result, needed_quoting);
  return result;
}

void EscapeStringToStream(std::ostream& out,
                          const base::StringPiece& str,
                          const EscapeOptions& options) {
  std::string escaped;
  EscapeStringToString(str, options, &escaped, nullptr);
  if (!escaped.empty())
    out.write(escaped.data(), escaped.size());
}
