summaryrefslogtreecommitdiff
path: root/Source/cmOutputConverter.h
blob: ae15055ed160383c57d4aacdd787feb693f3ac63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmOutputConverter_h
#define cmOutputConverter_h

#include "cmConfigure.h" // IWYU pragma: keep

#include <string>

#include "cmStateSnapshot.h"

class cmState;
class cmStateDirectory;

class cmOutputConverter
{
public:
  cmOutputConverter(cmStateSnapshot const& snapshot);

  enum OutputFormat
  {
    SHELL,
    WATCOMQUOTE,
    RESPONSE
  };
  std::string ConvertToOutputFormat(const std::string& source,
                                    OutputFormat output) const;
  std::string ConvertDirectorySeparatorsForShell(
    const std::string& source) const;

  ///! for existing files convert to output path and short path if spaces
  std::string ConvertToOutputForExisting(const std::string& remote,
                                         OutputFormat format = SHELL) const;

  void SetLinkScriptShell(bool linkScriptShell);

  /**
   * Flags to pass to Shell_GetArgument.  These modify the generated
   * quoting and escape sequences to work under alternative
   * environments.
   */
  enum Shell_Flag_e
  {
    /** The target shell is in a makefile.  */
    Shell_Flag_Make = (1 << 0),

    /** The target shell is in a VS project file.  Do not use with
        Shell_Flag_Make.  */
    Shell_Flag_VSIDE = (1 << 1),

    /** In a windows shell the argument is being passed to "echo".  */
    Shell_Flag_EchoWindows = (1 << 2),

    /** The target shell is in a Watcom WMake makefile.  */
    Shell_Flag_WatcomWMake = (1 << 3),

    /** The target shell is in a MinGW Make makefile.  */
    Shell_Flag_MinGWMake = (1 << 4),

    /** The target shell is in a NMake makefile.  */
    Shell_Flag_NMake = (1 << 5),

    /** Make variable reference syntax $(MAKEVAR) should not be escaped
        to allow a build tool to replace it.  Replacement values
        containing spaces, quotes, backslashes, or other
        non-alphanumeric characters that have significance to some makes
        or shells produce undefined behavior.  */
    Shell_Flag_AllowMakeVariables = (1 << 6),

    /** The target shell quoting uses extra single Quotes for Watcom tools.  */
    Shell_Flag_WatcomQuote = (1 << 7),

    Shell_Flag_IsUnix = (1 << 8)
  };

  std::string EscapeForShell(const std::string& str, bool makeVars = false,
                             bool forEcho = false,
                             bool useWatcomQuote = false) const;

  static std::string EscapeForCMake(const std::string& str);

  /** Compute an escaped version of the given argument for use in a
      windows shell.  */
  static std::string EscapeWindowsShellArgument(const char* arg,
                                                int shell_flags);

  enum FortranFormat
  {
    FortranFormatNone,
    FortranFormatFixed,
    FortranFormatFree
  };
  static FortranFormat GetFortranFormat(const char* value);

  static bool ContainedInDirectory(std::string const& local_path,
                                   std::string const& remote_path,
                                   cmStateDirectory const& directory);

  /**
   * Convert the given remote path to a relative path with respect to
   * the given local path.  Both paths must use forward slashes and not
   * already be escaped or quoted.
   * The conversion is skipped if the paths are not both in the source
   * or both in the binary tree.
   */
  std::string ConvertToRelativePath(std::string const& local_path,
                                    std::string const& remote_path) const;

  /**
   * Convert the given remote path to a relative path with respect to
   * the given local path.  Both paths must use forward slashes and not
   * already be escaped or quoted.
   */
  static std::string ForceToRelativePath(std::string const& local_path,
                                         std::string const& remote_path);

private:
  cmState* GetState() const;

  static int Shell__CharIsWhitespace(char c);
  static int Shell__CharNeedsQuotesOnUnix(char c);
  static int Shell__CharNeedsQuotesOnWindows(char c);
  static int Shell__CharNeedsQuotes(char c, int flags);
  static int Shell__CharIsMakeVariableName(char c);
  static const char* Shell__SkipMakeVariables(const char* c);
  static int Shell__ArgumentNeedsQuotes(const char* in, int flags);
  static std::string Shell__GetArgument(const char* in, int flags);

private:
  cmStateSnapshot StateSnapshot;

  bool LinkScriptShell;
};

#endif