// 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 "base/containers/stack_container.h"
#include "base/logging.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, 1, 0, 1, 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.
template<typename DestString>
inline void NinjaEscapeChar(char ch, DestString* dest) {
  if (ch == '$' || ch == ' ' || ch == ':')
    dest->push_back('$');
  dest->push_back(ch);
}

template<typename DestString>
void EscapeStringToString_Ninja(const base::StringPiece& str,
                                const EscapeOptions& options,
                                DestString* dest,
                                bool* needed_quoting) {
  for (size_t i = 0; i < str.size(); i++)
    NinjaEscapeChar(str[i], dest);
  if (needed_quoting)
    *needed_quoting = false;
}

// 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
template<typename DestString>
void EscapeStringToString_WindowsNinjaFork(const base::StringPiece& str,
                                           const EscapeOptions& options,
                                           DestString* 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;
  }
}

template<typename DestString>
void EscapeStringToString_PosixNinjaFork(const base::StringPiece& str,
                                         const EscapeOptions& options,
                                         DestString* dest,
                                         bool* needed_quoting) {
  for (size_t i = 0; i < str.size(); i++) {
    if (str[i] == '$' || str[i] == ' ') {
      // 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(str[i]);
    } else if (str[i] == ':') {
      // 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>(str[i]) >= 0x80 ||
               !kShellValid[static_cast<int>(str[i])]) {
      // All other invalid shell chars get backslash-escaped.
      dest->push_back('\\');
      dest->push_back(str[i]);
    } else {
      // Everything else is a literal.
      dest->push_back(str[i]);
    }
  }
}

template<typename DestString>
void EscapeStringToString(const base::StringPiece& str,
                          const EscapeOptions& options,
                          DestString* 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;
    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) {
  base::StackString<256> escaped;
  EscapeStringToString(str, options, &escaped.container(), NULL);
  if (!escaped->empty())
    out.write(escaped->data(), escaped->size());
}
