/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmOutputConverter.h"

#include "cmAlgorithms.h"
#include "cmake.h"

#include <assert.h>

#include <ctype.h>  /* isalpha */
#include <string.h> /* strlen */

cmOutputConverter::cmOutputConverter(cmState::Snapshot snapshot)
  : StateSnapshot(snapshot)
  , LinkScriptShell(false)
{
  assert(this->StateSnapshot.IsValid());
}

std::string cmOutputConverter::ConvertToOutputForExistingCommon(
  const std::string& remote, std::string const& result,
  OutputFormat format) const
{
  // If this is a windows shell, the result has a space, and the path
  // already exists, we can use a short-path to reference it without a
  // space.
  if (this->GetState()->UseWindowsShell() && result.find(' ') != result.npos &&
      cmSystemTools::FileExists(remote.c_str())) {
    std::string tmp;
    if (cmSystemTools::GetShortPath(remote, tmp)) {
      return this->ConvertToOutputFormat(tmp, format);
    }
  }

  // Otherwise, leave it unchanged.
  return result;
}

std::string cmOutputConverter::ConvertToOutputForExisting(
  const std::string& remote, RelativeRoot local, OutputFormat format) const
{
  static_cast<void>(local);

  // Perform standard conversion.
  std::string result = this->ConvertToOutputFormat(remote, format);

  // Consider short-path.
  return this->ConvertToOutputForExistingCommon(remote, result, format);
}

std::string cmOutputConverter::ConvertToOutputForExisting(
  RelativeRoot remote, const std::string& local, OutputFormat format) const
{
  // Perform standard conversion.
  std::string result = this->Convert(remote, local, format, true);

  // Consider short-path.
  const char* remotePath = this->GetRelativeRootPath(remote);
  return this->ConvertToOutputForExistingCommon(remotePath, result, format);
}

const char* cmOutputConverter::GetRelativeRootPath(RelativeRoot relroot) const
{
  switch (relroot) {
    case HOME:
      return this->GetState()->GetSourceDirectory();
    case START:
      return this->StateSnapshot.GetDirectory().GetCurrentSource();
    case HOME_OUTPUT:
      return this->GetState()->GetBinaryDirectory();
    case START_OUTPUT:
      return this->StateSnapshot.GetDirectory().GetCurrentBinary();
    default:
      break;
  }
  return 0;
}

std::string cmOutputConverter::Convert(const std::string& source,
                                       RelativeRoot relative,
                                       OutputFormat output) const
{
  // Convert the path to a relative path.
  std::string result = source;

  switch (relative) {
    case HOME:
      result = this->ConvertToRelativePath(
        this->GetState()->GetSourceDirectoryComponents(), result);
      break;
    case START:
      result = this->ConvertToRelativePath(
        this->StateSnapshot.GetDirectory().GetCurrentSourceComponents(),
        result);
      break;
    case HOME_OUTPUT:
      result = this->ConvertToRelativePath(
        this->GetState()->GetBinaryDirectoryComponents(), result);
      break;
    case START_OUTPUT:
      result = this->ConvertToRelativePath(
        this->StateSnapshot.GetDirectory().GetCurrentBinaryComponents(),
        result);
      break;
    case FULL:
      result = cmSystemTools::CollapseFullPath(result);
      break;
    case NONE:
      break;
  }
  return this->ConvertToOutputFormat(result, output);
}

std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
                                                     OutputFormat output) const
{
  std::string result = source;
  // Convert it to an output path.
  if (output == MAKERULE) {
    result = cmSystemTools::ConvertToOutputPath(result.c_str());
  } else if (output == SHELL || output == WATCOMQUOTE) {
    result = this->ConvertDirectorySeparatorsForShell(source);
    result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
  } else if (output == RESPONSE) {
    result = this->EscapeForShell(result, false, false, false);
  }
  return result;
}

std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
  const std::string& source) const
{
  std::string result = source;
  // For the MSYS shell convert drive letters to posix paths, so
  // that c:/some/path becomes /c/some/path.  This is needed to
  // avoid problems with the shell path translation.
  if (this->GetState()->UseMSYSShell() && !this->LinkScriptShell) {
    if (result.size() > 2 && result[1] == ':') {
      result[1] = result[0];
      result[0] = '/';
    }
  }
  if (this->GetState()->UseWindowsShell()) {
    std::replace(result.begin(), result.end(), '/', '\\');
  }
  return result;
}

std::string cmOutputConverter::Convert(RelativeRoot remote,
                                       const std::string& local,
                                       OutputFormat output,
                                       bool optional) const
{
  const char* remotePath = this->GetRelativeRootPath(remote);

  // The relative root must have a path (i.e. not FULL or NONE)
  assert(remotePath != 0);

  if (!local.empty() && !optional) {
    std::vector<std::string> components;
    cmSystemTools::SplitPath(local, components);
    std::string result = this->ConvertToRelativePath(components, remotePath);
    return this->ConvertToOutputFormat(result, output);
  }

  return this->ConvertToOutputFormat(remotePath, output);
}

static bool cmOutputConverterNotAbove(const char* a, const char* b)
{
  return (cmSystemTools::ComparePath(a, b) ||
          cmSystemTools::IsSubDirectory(a, b));
}

std::string cmOutputConverter::ConvertToRelativePath(
  const std::vector<std::string>& local, const std::string& in_remote,
  bool force) const
{
  // The path should never be quoted.
  assert(in_remote[0] != '\"');

  // The local path should never have a trailing slash.
  assert(!local.empty() && !(local[local.size() - 1] == ""));

  // If the path is already relative then just return the path.
  if (!cmSystemTools::FileIsFullPath(in_remote.c_str())) {
    return in_remote;
  }

  if (!force) {
    // Skip conversion if the path and local are not both in the source
    // or both in the binary tree.
    std::string local_path = cmSystemTools::JoinPath(local);
    if (!((cmOutputConverterNotAbove(
             local_path.c_str(),
             this->StateSnapshot.GetDirectory().GetRelativePathTopBinary()) &&
           cmOutputConverterNotAbove(
             in_remote.c_str(),
             this->StateSnapshot.GetDirectory().GetRelativePathTopBinary())) ||
          (cmOutputConverterNotAbove(
             local_path.c_str(),
             this->StateSnapshot.GetDirectory().GetRelativePathTopSource()) &&
           cmOutputConverterNotAbove(in_remote.c_str(),
                                     this->StateSnapshot.GetDirectory()
                                       .GetRelativePathTopSource())))) {
      return in_remote;
    }
  }

  // Identify the longest shared path component between the remote
  // path and the local path.
  std::vector<std::string> remote;
  cmSystemTools::SplitPath(in_remote, remote);
  unsigned int common = 0;
  while (common < remote.size() && common < local.size() &&
         cmSystemTools::ComparePath(remote[common], local[common])) {
    ++common;
  }

  // If no part of the path is in common then return the full path.
  if (common == 0) {
    return in_remote;
  }

  // If the entire path is in common then just return a ".".
  if (common == remote.size() && common == local.size()) {
    return ".";
  }

  // If the entire path is in common except for a trailing slash then
  // just return a "./".
  if (common + 1 == remote.size() && remote[common].empty() &&
      common == local.size()) {
    return "./";
  }

  // Construct the relative path.
  std::string relative;

  // First add enough ../ to get up to the level of the shared portion
  // of the path.  Leave off the trailing slash.  Note that the last
  // component of local will never be empty because local should never
  // have a trailing slash.
  for (unsigned int i = common; i < local.size(); ++i) {
    relative += "..";
    if (i < local.size() - 1) {
      relative += "/";
    }
  }

  // Now add the portion of the destination path that is not included
  // in the shared portion of the path.  Add a slash the first time
  // only if there was already something in the path.  If there was a
  // trailing slash in the input then the last iteration of the loop
  // will add a slash followed by an empty string which will preserve
  // the trailing slash in the output.

  if (!relative.empty() && !remote.empty()) {
    relative += "/";
  }
  relative += cmJoin(cmMakeRange(remote).advance(common), "/");

  // Finally return the path.
  return relative;
}

static bool cmOutputConverterIsShellOperator(const std::string& str)
{
  static std::set<std::string> shellOperators;
  if (shellOperators.empty()) {
    shellOperators.insert("<");
    shellOperators.insert(">");
    shellOperators.insert("<<");
    shellOperators.insert(">>");
    shellOperators.insert("|");
    shellOperators.insert("||");
    shellOperators.insert("&&");
    shellOperators.insert("&>");
    shellOperators.insert("1>");
    shellOperators.insert("2>");
    shellOperators.insert("2>&1");
    shellOperators.insert("1>&2");
  }
  return shellOperators.count(str) > 0;
}

std::string cmOutputConverter::EscapeForShell(const std::string& str,
                                              bool makeVars, bool forEcho,
                                              bool useWatcomQuote) const
{
  // Do not escape shell operators.
  if (cmOutputConverterIsShellOperator(str)) {
    return str;
  }

  // Compute the flags for the target shell environment.
  int flags = 0;
  if (this->GetState()->UseWindowsVSIDE()) {
    flags |= Shell_Flag_VSIDE;
  } else if (!this->LinkScriptShell) {
    flags |= Shell_Flag_Make;
  }
  if (makeVars) {
    flags |= Shell_Flag_AllowMakeVariables;
  }
  if (forEcho) {
    flags |= Shell_Flag_EchoWindows;
  }
  if (useWatcomQuote) {
    flags |= Shell_Flag_WatcomQuote;
  }
  if (this->GetState()->UseWatcomWMake()) {
    flags |= Shell_Flag_WatcomWMake;
  }
  if (this->GetState()->UseMinGWMake()) {
    flags |= Shell_Flag_MinGWMake;
  }
  if (this->GetState()->UseNMake()) {
    flags |= Shell_Flag_NMake;
  }

  // Compute the buffer size needed.
  int size = (this->GetState()->UseWindowsShell()
                ? Shell_GetArgumentSizeForWindows(str.c_str(), flags)
                : Shell_GetArgumentSizeForUnix(str.c_str(), flags));

  // Compute the shell argument itself.
  std::vector<char> arg(size);
  if (this->GetState()->UseWindowsShell()) {
    Shell_GetArgumentForWindows(str.c_str(), &arg[0], flags);
  } else {
    Shell_GetArgumentForUnix(str.c_str(), &arg[0], flags);
  }
  return std::string(&arg[0]);
}

std::string cmOutputConverter::EscapeForCMake(const std::string& str)
{
  // Always double-quote the argument to take care of most escapes.
  std::string result = "\"";
  for (const char* c = str.c_str(); *c; ++c) {
    if (*c == '"') {
      // Escape the double quote to avoid ending the argument.
      result += "\\\"";
    } else if (*c == '$') {
      // Escape the dollar to avoid expanding variables.
      result += "\\$";
    } else if (*c == '\\') {
      // Escape the backslash to avoid other escapes.
      result += "\\\\";
    } else {
      // Other characters will be parsed correctly.
      result += *c;
    }
  }
  result += "\"";
  return result;
}

std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
                                                          int shell_flags)
{
  char local_buffer[1024];
  char* buffer = local_buffer;
  int size = Shell_GetArgumentSizeForWindows(arg, shell_flags);
  if (size > 1024) {
    buffer = new char[size];
  }
  Shell_GetArgumentForWindows(arg, buffer, shell_flags);
  std::string result(buffer);
  if (buffer != local_buffer) {
    delete[] buffer;
  }
  return result;
}

cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
  const char* value)
{
  FortranFormat format = FortranFormatNone;
  if (value && *value) {
    std::vector<std::string> fmt;
    cmSystemTools::ExpandListArgument(value, fmt);
    for (std::vector<std::string>::iterator fi = fmt.begin(); fi != fmt.end();
         ++fi) {
      if (*fi == "FIXED") {
        format = FortranFormatFixed;
      }
      if (*fi == "FREE") {
        format = FortranFormatFree;
      }
    }
  }
  return format;
}

void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
{
  this->LinkScriptShell = linkScriptShell;
}

cmState* cmOutputConverter::GetState() const
{
  return this->StateSnapshot.GetState();
}

/*

Notes:

Make variable replacements open a can of worms.  Sometimes they should
be quoted and sometimes not.  Sometimes their replacement values are
already quoted.

VS variables cause problems.  In order to pass the referenced value
with spaces the reference must be quoted.  If the variable value ends
in a backslash then it will escape the ending quote!  In order to make
the ending backslash appear we need this:

  "$(InputDir)\"

However if there is not a trailing backslash then this will put a
quote in the value so we need:

  "$(InputDir)"

Make variable references are platform specific so we should probably
just NOT quote them and let the listfile author deal with it.

*/

/*
TODO: For windows echo:

To display a pipe (|) or redirection character (< or >) when using the
echo command, use a caret character immediately before the pipe or
redirection character (for example, ^>, ^<, or ^| ). If you need to
use the caret character itself (^), use two in a row (^^).
*/

int cmOutputConverter::Shell__CharIsWhitespace(char c)
{
  return ((c == ' ') || (c == '\t'));
}

int cmOutputConverter::Shell__CharNeedsQuotesOnUnix(char c)
{
  return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
          (c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') ||
          (c == '<') || (c == '>') || (c == '|') || (c == '*') || (c == '^') ||
          (c == '\\'));
}

int cmOutputConverter::Shell__CharNeedsQuotesOnWindows(char c)
{
  return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') ||
          (c == '>') || (c == '|') || (c == '^'));
}

int cmOutputConverter::Shell__CharNeedsQuotes(char c, int isUnix, int flags)
{
  /* On Windows the built-in command shell echo never needs quotes.  */
  if (!isUnix && (flags & Shell_Flag_EchoWindows)) {
    return 0;
  }

  /* On all platforms quotes are needed to preserve whitespace.  */
  if (Shell__CharIsWhitespace(c)) {
    return 1;
  }

  if (isUnix) {
    /* On UNIX several special characters need quotes to preserve them.  */
    if (Shell__CharNeedsQuotesOnUnix(c)) {
      return 1;
    }
  } else {
    /* On Windows several special characters need quotes to preserve them.  */
    if (Shell__CharNeedsQuotesOnWindows(c)) {
      return 1;
    }
  }
  return 0;
}

int cmOutputConverter::Shell__CharIsMakeVariableName(char c)
{
  return c && (c == '_' || isalpha(((int)c)));
}

const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
{
  while (*c == '$' && *(c + 1) == '(') {
    const char* skip = c + 2;
    while (Shell__CharIsMakeVariableName(*skip)) {
      ++skip;
    }
    if (*skip == ')') {
      c = skip + 1;
    } else {
      break;
    }
  }
  return c;
}

/*
Allowing make variable replacements opens a can of worms.  Sometimes
they should be quoted and sometimes not.  Sometimes their replacement
values are already quoted or contain escapes.

Some Visual Studio variables cause problems.  In order to pass the
referenced value with spaces the reference must be quoted.  If the
variable value ends in a backslash then it will escape the ending
quote!  In order to make the ending backslash appear we need this:

  "$(InputDir)\"

However if there is not a trailing backslash then this will put a
quote in the value so we need:

  "$(InputDir)"

This macro decides whether we quote an argument just because it
contains a make variable reference.  This should be replaced with a
flag later when we understand applications of this better.
*/
#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0

int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int isUnix,
                                                  int flags)
{
  /* The empty string needs quotes.  */
  if (!*in) {
    return 1;
  }

  /* Scan the string for characters that require quoting.  */
  {
    const char* c;
    for (c = in; *c; ++c) {
      /* Look for $(MAKEVAR) syntax if requested.  */
      if (flags & Shell_Flag_AllowMakeVariables) {
#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
        const char* skip = Shell__SkipMakeVariables(c);
        if (skip != c) {
          /* We need to quote make variable references to preserve the
             string with contents substituted in its place.  */
          return 1;
        }
#else
        /* Skip over the make variable references if any are present.  */
        c = Shell__SkipMakeVariables(c);

        /* Stop if we have reached the end of the string.  */
        if (!*c) {
          break;
        }
#endif
      }

      /* Check whether this character needs quotes.  */
      if (Shell__CharNeedsQuotes(*c, isUnix, flags)) {
        return 1;
      }
    }
  }

  /* On Windows some single character arguments need quotes.  */
  if (!isUnix && *in && !*(in + 1)) {
    char c = *in;
    if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
      return 1;
    }
  }

  return 0;
}

int cmOutputConverter::Shell__GetArgumentSize(const char* in, int isUnix,
                                              int flags)
{
  /* Start with the length of the original argument, plus one for
     either a terminating null or a separating space.  */
  int size = (int)strlen(in) + 1;

  /* String iterator.  */
  const char* c;

  /* Keep track of how many backslashes have been encountered in a row.  */
  int windows_backslashes = 0;

  /* Scan the string for characters that require escaping or quoting.  */
  for (c = in; *c; ++c) {
    /* Look for $(MAKEVAR) syntax if requested.  */
    if (flags & Shell_Flag_AllowMakeVariables) {
      /* Skip over the make variable references if any are present.  */
      c = Shell__SkipMakeVariables(c);

      /* Stop if we have reached the end of the string.  */
      if (!*c) {
        break;
      }
    }

    /* Check whether this character needs escaping for the shell.  */
    if (isUnix) {
      /* On Unix a few special characters need escaping even inside a
         quoted argument.  */
      if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
        /* This character needs a backslash to escape it.  */
        ++size;
      }
    } else if (flags & Shell_Flag_EchoWindows) {
      /* On Windows the built-in command shell echo never needs escaping.  */
    } else {
      /* On Windows only backslashes and double-quotes need escaping.  */
      if (*c == '\\') {
        /* Found a backslash.  It may need to be escaped later.  */
        ++windows_backslashes;
      } else if (*c == '"') {
        /* Found a double-quote.  We need to escape it and all
           immediately preceding backslashes.  */
        size += windows_backslashes + 1;
        windows_backslashes = 0;
      } else {
        /* Found another character.  This eliminates the possibility
           that any immediately preceding backslashes will be
           escaped.  */
        windows_backslashes = 0;
      }
    }

    /* Check whether this character needs escaping for a make tool.  */
    if (*c == '$') {
      if (flags & Shell_Flag_Make) {
        /* In Makefiles a dollar is written $$ so we need one extra
           character.  */
        ++size;
      } else if (flags & Shell_Flag_VSIDE) {
        /* In a VS IDE a dollar is written "$" so we need two extra
           characters.  */
        size += 2;
      }
    } else if (*c == '#') {
      if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
        /* In Watcom WMake makefiles a pound is written $# so we need
           one extra character.  */
        ++size;
      }
    } else if (*c == '%') {
      if ((flags & Shell_Flag_VSIDE) ||
          ((flags & Shell_Flag_Make) &&
           ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
        /* In the VS IDE, NMake, or MinGW make a percent is written %%
           so we need one extra characters.  */
        size += 1;
      }
    } else if (*c == ';') {
      if (flags & Shell_Flag_VSIDE) {
        /* In a VS IDE a semicolon is written ";" so we need two extra
           characters.  */
        size += 2;
      }
    }
  }

  /* Check whether the argument needs surrounding quotes.  */
  if (Shell__ArgumentNeedsQuotes(in, isUnix, flags)) {
    /* Surrounding quotes are needed.  Allocate space for them.  */
    if ((flags & Shell_Flag_WatcomQuote) && (isUnix)) {
      size += 2;
    }
    size += 2;

    /* We must escape all ending backslashes when quoting on windows.  */
    size += windows_backslashes;
  }

  return size;
}

char* cmOutputConverter::Shell__GetArgument(const char* in, char* out,
                                            int isUnix, int flags)
{
  /* String iterator.  */
  const char* c;

  /* Keep track of how many backslashes have been encountered in a row.  */
  int windows_backslashes = 0;

  /* Whether the argument must be quoted.  */
  int needQuotes = Shell__ArgumentNeedsQuotes(in, isUnix, flags);
  if (needQuotes) {
    /* Add the opening quote for this argument.  */
    if (flags & Shell_Flag_WatcomQuote) {
      if (isUnix) {
        *out++ = '"';
      }
      *out++ = '\'';
    } else {
      *out++ = '"';
    }
  }

  /* Scan the string for characters that require escaping or quoting.  */
  for (c = in; *c; ++c) {
    /* Look for $(MAKEVAR) syntax if requested.  */
    if (flags & Shell_Flag_AllowMakeVariables) {
      const char* skip = Shell__SkipMakeVariables(c);
      if (skip != c) {
        /* Copy to the end of the make variable references.  */
        while (c != skip) {
          *out++ = *c++;
        }

        /* The make variable reference eliminates any escaping needed
           for preceding backslashes.  */
        windows_backslashes = 0;

        /* Stop if we have reached the end of the string.  */
        if (!*c) {
          break;
        }
      }
    }

    /* Check whether this character needs escaping for the shell.  */
    if (isUnix) {
      /* On Unix a few special characters need escaping even inside a
         quoted argument.  */
      if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
        /* This character needs a backslash to escape it.  */
        *out++ = '\\';
      }
    } else if (flags & Shell_Flag_EchoWindows) {
      /* On Windows the built-in command shell echo never needs escaping.  */
    } else {
      /* On Windows only backslashes and double-quotes need escaping.  */
      if (*c == '\\') {
        /* Found a backslash.  It may need to be escaped later.  */
        ++windows_backslashes;
      } else if (*c == '"') {
        /* Found a double-quote.  Escape all immediately preceding
           backslashes.  */
        while (windows_backslashes > 0) {
          --windows_backslashes;
          *out++ = '\\';
        }

        /* Add the backslash to escape the double-quote.  */
        *out++ = '\\';
      } else {
        /* We encountered a normal character.  This eliminates any
           escaping needed for preceding backslashes.  */
        windows_backslashes = 0;
      }
    }

    /* Check whether this character needs escaping for a make tool.  */
    if (*c == '$') {
      if (flags & Shell_Flag_Make) {
        /* In Makefiles a dollar is written $$.  The make tool will
           replace it with just $ before passing it to the shell.  */
        *out++ = '$';
        *out++ = '$';
      } else if (flags & Shell_Flag_VSIDE) {
        /* In a VS IDE a dollar is written "$".  If this is written in
           an un-quoted argument it starts a quoted segment, inserts
           the $ and ends the segment.  If it is written in a quoted
           argument it ends quoting, inserts the $ and restarts
           quoting.  Either way the $ is isolated from surrounding
           text to avoid looking like a variable reference.  */
        *out++ = '"';
        *out++ = '$';
        *out++ = '"';
      } else {
        /* Otherwise a dollar is written just $. */
        *out++ = '$';
      }
    } else if (*c == '#') {
      if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
        /* In Watcom WMake makefiles a pound is written $#.  The make
           tool will replace it with just # before passing it to the
           shell.  */
        *out++ = '$';
        *out++ = '#';
      } else {
        /* Otherwise a pound is written just #. */
        *out++ = '#';
      }
    } else if (*c == '%') {
      if ((flags & Shell_Flag_VSIDE) ||
          ((flags & Shell_Flag_Make) &&
           ((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
        /* In the VS IDE, NMake, or MinGW make a percent is written %%.  */
        *out++ = '%';
        *out++ = '%';
      } else {
        /* Otherwise a percent is written just %. */
        *out++ = '%';
      }
    } else if (*c == ';') {
      if (flags & Shell_Flag_VSIDE) {
        /* In a VS IDE a semicolon is written ";".  If this is written
           in an un-quoted argument it starts a quoted segment,
           inserts the ; and ends the segment.  If it is written in a
           quoted argument it ends quoting, inserts the ; and restarts
           quoting.  Either way the ; is isolated.  */
        *out++ = '"';
        *out++ = ';';
        *out++ = '"';
      } else {
        /* Otherwise a semicolon is written just ;. */
        *out++ = ';';
      }
    } else {
      /* Store this character.  */
      *out++ = *c;
    }
  }

  if (needQuotes) {
    /* Add enough backslashes to escape any trailing ones.  */
    while (windows_backslashes > 0) {
      --windows_backslashes;
      *out++ = '\\';
    }

    /* Add the closing quote for this argument.  */
    if (flags & Shell_Flag_WatcomQuote) {
      *out++ = '\'';
      if (isUnix) {
        *out++ = '"';
      }
    } else {
      *out++ = '"';
    }
  }

  /* Store a terminating null without incrementing.  */
  *out = 0;

  return out;
}

char* cmOutputConverter::Shell_GetArgumentForWindows(const char* in, char* out,
                                                     int flags)
{
  return Shell__GetArgument(in, out, 0, flags);
}

char* cmOutputConverter::Shell_GetArgumentForUnix(const char* in, char* out,
                                                  int flags)
{
  return Shell__GetArgument(in, out, 1, flags);
}

int cmOutputConverter::Shell_GetArgumentSizeForWindows(const char* in,
                                                       int flags)
{
  return Shell__GetArgumentSize(in, 0, flags);
}

int cmOutputConverter::Shell_GetArgumentSizeForUnix(const char* in, int flags)
{
  return Shell__GetArgumentSize(in, 1, flags);
}
