Browse Source

Merge topic 'dev/faster-evis'

90f66381 Help: Add release notes for policy CMP0053
6804cd04 Help: Add documentation on escaping changes with CMP0053
411f77d1 EVIS: Add tests for syntax corner cases and CMP0053
bc385658 EVIS: Reimplement using custom parsing code
25102efc EVIS: Add policy CMP0053
e423f1c0 Windows: Avoid () in environment variable references
c179b289 Help: Add more reference targets to cmake-language.7
c3d98bd2 Utilities/Release: Use ${VAR} instead of @VAR@ syntax
Brad King 11 years ago
parent
commit
d91c0f7a3f
100 changed files with 1114 additions and 27 deletions
  1. 17 6
      Help/manual/cmake-language.7.rst
  2. 1 0
      Help/manual/cmake-policies.7.rst
  3. 3 0
      Help/policy/CMP0010.rst
  4. 44 0
      Help/policy/CMP0053.rst
  5. 6 0
      Help/release/dev/CMP0053.rst
  6. 2 1
      Modules/InstallRequiredSystemLibraries.cmake
  7. 3 2
      Modules/Platform/WindowsPaths.cmake
  8. 445 16
      Source/cmMakefile.cxx
  9. 24 1
      Source/cmMakefile.h
  10. 5 0
      Source/cmPolicies.cxx
  11. 2 0
      Source/cmPolicies.h
  12. 1 0
      Tests/RunCMake/Syntax/CMP0053-At-NEW-stderr.txt
  13. 9 0
      Tests/RunCMake/Syntax/CMP0053-At-NEW.cmake
  14. 1 0
      Tests/RunCMake/Syntax/CMP0053-At-OLD-stderr.txt
  15. 9 0
      Tests/RunCMake/Syntax/CMP0053-At-OLD.cmake
  16. 27 0
      Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines-stderr.txt
  17. 6 0
      Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines.cmake
  18. 21 0
      Tests/RunCMake/Syntax/CMP0053-At-WARN-stderr.txt
  19. 4 0
      Tests/RunCMake/Syntax/CMP0053-At-WARN.cmake
  20. 56 0
      Tests/RunCMake/Syntax/CMP0053-NUL-stderr.txt
  21. 6 0
      Tests/RunCMake/Syntax/CMP0053-NUL.cmake
  22. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-result.txt
  23. 4 0
      Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-stderr.txt
  24. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn.cmake
  25. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturnQuoted.cmake
  26. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-result.txt
  27. 4 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-stderr.txt
  28. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces.cmake
  29. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpacesQuoted.cmake
  30. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-result.txt
  31. 4 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-stderr.txt
  32. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs.cmake
  33. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabsQuoted.cmake
  34. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithNewline-result.txt
  35. 4 0
      Tests/RunCMake/Syntax/CMP0053-NameWithNewline-stderr.txt
  36. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithNewline.cmake
  37. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithNewlineQuoted.cmake
  38. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-result.txt
  39. 12 0
      Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-stderr.txt
  40. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake
  41. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-result.txt
  42. 12 0
      Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-stderr.txt
  43. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake
  44. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithTabs-result.txt
  45. 12 0
      Tests/RunCMake/Syntax/CMP0053-NameWithTabs-stderr.txt
  46. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake
  47. 1 0
      Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-result.txt
  48. 12 0
      Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-stderr.txt
  49. 2 0
      Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake
  50. 1 0
      Tests/RunCMake/Syntax/CMP0053-ParenInENV-stderr.txt
  51. 3 0
      Tests/RunCMake/Syntax/CMP0053-ParenInENV.cmake
  52. 1 0
      Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV-stderr.txt
  53. 3 0
      Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV.cmake
  54. 28 0
      Tests/RunCMake/Syntax/CMP0053-WARN-stderr.txt
  55. 5 0
      Tests/RunCMake/Syntax/CMP0053-WARN.cmake
  56. 1 1
      Tests/RunCMake/Syntax/CMakeLists.txt
  57. 1 0
      Tests/RunCMake/Syntax/Escape2-result.txt
  58. 13 0
      Tests/RunCMake/Syntax/Escape2-stderr.txt
  59. 7 0
      Tests/RunCMake/Syntax/Escape2.cmake
  60. 1 0
      Tests/RunCMake/Syntax/EscapeChar-char-result.txt
  61. 12 0
      Tests/RunCMake/Syntax/EscapeChar-char-stderr.txt.in
  62. 3 0
      Tests/RunCMake/Syntax/EscapeChar-char.cmake.in
  63. 12 0
      Tests/RunCMake/Syntax/EscapeCharsAllowed-stderr.txt
  64. 26 0
      Tests/RunCMake/Syntax/EscapeCharsAllowed.cmake
  65. 42 0
      Tests/RunCMake/Syntax/EscapeCharsDisallowed.cmake
  66. 1 0
      Tests/RunCMake/Syntax/NameWithCarriageReturn-result.txt
  67. 12 0
      Tests/RunCMake/Syntax/NameWithCarriageReturn-stderr.txt
  68. 1 0
      Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake
  69. 1 0
      Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-result.txt
  70. 12 0
      Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-stderr.txt
  71. 1 0
      Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake
  72. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedSpaces-result.txt
  73. 12 0
      Tests/RunCMake/Syntax/NameWithEscapedSpaces-stderr.txt
  74. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake
  75. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-result.txt
  76. 12 0
      Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-stderr.txt
  77. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake
  78. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedTabs-result.txt
  79. 12 0
      Tests/RunCMake/Syntax/NameWithEscapedTabs-stderr.txt
  80. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake
  81. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-result.txt
  82. 12 0
      Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-stderr.txt
  83. 1 0
      Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake
  84. 1 0
      Tests/RunCMake/Syntax/NameWithNewline-result.txt
  85. 12 0
      Tests/RunCMake/Syntax/NameWithNewline-stderr.txt
  86. 1 0
      Tests/RunCMake/Syntax/NameWithNewline.cmake
  87. 1 0
      Tests/RunCMake/Syntax/NameWithNewlineQuoted-result.txt
  88. 12 0
      Tests/RunCMake/Syntax/NameWithNewlineQuoted-stderr.txt
  89. 1 0
      Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake
  90. 1 0
      Tests/RunCMake/Syntax/NameWithSpaces-result.txt
  91. 12 0
      Tests/RunCMake/Syntax/NameWithSpaces-stderr.txt
  92. 1 0
      Tests/RunCMake/Syntax/NameWithSpaces.cmake
  93. 1 0
      Tests/RunCMake/Syntax/NameWithSpacesQuoted-result.txt
  94. 12 0
      Tests/RunCMake/Syntax/NameWithSpacesQuoted-stderr.txt
  95. 1 0
      Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake
  96. 1 0
      Tests/RunCMake/Syntax/NameWithTabs-result.txt
  97. 12 0
      Tests/RunCMake/Syntax/NameWithTabs-stderr.txt
  98. 1 0
      Tests/RunCMake/Syntax/NameWithTabs.cmake
  99. 1 0
      Tests/RunCMake/Syntax/NameWithTabsQuoted-result.txt
  100. 12 0
      Tests/RunCMake/Syntax/NameWithTabsQuoted-stderr.txt

+ 17 - 6
Help/manual/cmake-language.7.rst

@@ -287,6 +287,8 @@ For example:
  Instead use a `Quoted Argument`_ or a `Bracket Argument`_ to
  represent the content.
 
+.. _`Escape Sequences`:
+
 Escape Sequences
 ----------------
 
@@ -294,16 +296,20 @@ An *escape sequence* is a ``\`` followed by one character:
 
 .. productionlist::
  escape_sequence: `escape_identity` | `escape_encoded` | `escape_semicolon`
- escape_identity: '\(' | '\)' | '\#' | '\"' | '\ ' |
-                : '\\' | '\$' | '\@' | '\^'
+ escape_identity: '\' <match '[^A-Za-z0-9;]'>
  escape_encoded: '\t' | '\r' | '\n'
  escape_semicolon: '\;'
 
-A ``\`` followed by one of ``()#" \#@^`` simply encodes the literal
+A ``\`` followed by a non-alphanumeric character simply encodes the literal
 character without interpreting it as syntax.  A ``\t``, ``\r``, or ``\n``
-encodes a tab, carriage return, or newline character, respectively.
-A ``\;`` encodes itself but may be used in an `Unquoted Argument`_
-to encode the ``;`` without dividing the argument value on it.
+encodes a tab, carriage return, or newline character, respectively. A ``\;``
+outside of any `Variable References`_  encodes itself but may be used in an
+`Unquoted Argument`_ to encode the ``;`` without dividing the argument
+value on it.  A ``\;`` inside `Variable References`_ encodes the literal
+``;`` character.  (See also policy :policy:`CMP0053` documentation for
+historical considerations.)
+
+.. _`Variable References`:
 
 Variable References
 -------------------
@@ -315,6 +321,11 @@ or by the empty string if the variable is not set.
 Variable references can nest and are evaluated from the
 inside out, e.g. ``${outer_${inner_variable}_variable}``.
 
+Literal variable references may consist of alphanumeric characters,
+the characters ``/_.+-``, and `Escape Sequences`_.  Nested references
+may be used to evaluate variables of any name.  (See also policy
+:policy:`CMP0053` documentation for historical considerations.)
+
 The `Variables`_ section documents the scope of variable names
 and how their values are set.
 

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -104,3 +104,4 @@ All Policies
    /policy/CMP0050
    /policy/CMP0051
    /policy/CMP0052
+   /policy/CMP0053

+ 3 - 0
Help/policy/CMP0010.rst

@@ -10,6 +10,9 @@ variable reference is an error.  The OLD behavior for this policy is
 to warn about the error, leave the string untouched, and continue.
 The NEW behavior for this policy is to report an error.
 
+If :policy:`CMP0053` is set to ``NEW``, this policy has no effect
+and is treated as always being ``NEW``.
+
 This policy was introduced in CMake version 2.6.3.  CMake version
 |release| warns when the policy is not set and uses OLD behavior.  Use
 the cmake_policy command to set it to OLD or NEW explicitly.

+ 44 - 0
Help/policy/CMP0053.rst

@@ -0,0 +1,44 @@
+CMP0053
+-------
+
+Simplify variable reference and escape sequence evaluation.
+
+CMake 3.1 introduced a much faster implementation of evaluation of the
+:ref:`Variable References` and :ref:`Escape Sequences` documented in the
+:manual:`cmake-language(7)` manual.  While the behavior is identical
+to the legacy implementation in most cases, some corner cases were
+cleaned up to simplify the behavior.  Specifically:
+
+* Expansion of ``@VAR@`` reference syntax defined by the
+  :command:`configure_file` and :command:`string(CONFIGURE)`
+  commands is no longer performed in other contexts.
+
+* Literal ``${VAR}`` reference syntax may contain only
+  alphanumeric characters (``A-Z``, ``a-z``, ``0-9``) and
+  the characters ``_``, ``.``, ``/``, ``-``, and ``+``.
+  Variables with other characters in their name may still
+  be referenced indirectly, e.g.
+
+  .. code-block:: cmake
+
+    set(varname "otherwise & disallowed $ characters")
+    message("${${varname}}")
+
+* The setting of policy :policy:`CMP0010` is not considered,
+  so improper variable reference syntax is always an error.
+
+* More characters are allowed to be escaped in variable names.
+  Previously, only ``()#" \#@^`` were valid characters to
+  escape. Now any non-alphanumeric, non-semicolon, non-NUL
+  character may be escaped following the ``escape_identity``
+  production in the :ref:`Escape Sequences` section of the
+  :manual:`cmake-language(7)` manual.
+
+The ``OLD`` behavior for this policy is to honor the legacy behavior for
+variable references and escape sequences.  The ``NEW`` behavior is to
+use the simpler variable expansion and escape sequence evaluation rules.
+
+This policy was introduced in CMake version 3.1.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior.  Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.

+ 6 - 0
Help/release/dev/CMP0053.rst

@@ -0,0 +1,6 @@
+CMP0053
+-------
+
+* The :manual:`cmake-language(7)` syntax for :ref:`Variable References` and
+  :ref:`Escape Sequences` was simplified in order to allow a much faster
+  implementation.  See policy :policy:`CMP0053`.

+ 2 - 1
Modules/InstallRequiredSystemLibraries.cmake

@@ -157,7 +157,8 @@ if(MSVC)
         "${msvc_install_dir}/../../VC/redist"
         "${base_dir}/VC/redist"
         "$ENV{ProgramFiles}/Microsoft Visual Studio ${v}.0/VC/redist"
-        "$ENV{ProgramFiles(x86)}/Microsoft Visual Studio ${v}.0/VC/redist"
+        set(programfilesx86 "ProgramFiles(x86)")
+        "$ENV{${programfilesx86}}/Microsoft Visual Studio ${v}.0/VC/redist"
       )
     mark_as_advanced(MSVC${v}_REDIST_DIR)
     set(MSVC${v}_CRT_DIR "${MSVC${v}_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC${v}0.CRT")

+ 3 - 2
Modules/Platform/WindowsPaths.cmake

@@ -56,9 +56,10 @@ else()
   if(DEFINED "ENV{ProgramFiles}")
     list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles}")
   endif()
-  if(DEFINED "ENV{ProgramFiles(x86)}")
+  set(programfilesx86 "ProgramFiles(x86)")
+  if(DEFINED "ENV{${programfilesx86}}")
     # 64-bit binary.  32-bit program files are in ProgramFiles(x86).
-    list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{ProgramFiles(x86)}")
+    list(APPEND CMAKE_SYSTEM_PREFIX_PATH "$ENV{${programfilesx86}}")
   elseif(DEFINED "ENV{SystemDrive}")
     # Guess the 32-bit program files location.
     if(EXISTS "$ENV{SystemDrive}/Program Files (x86)")

+ 445 - 16
Source/cmMakefile.cxx

@@ -161,6 +161,7 @@ void cmMakefile::Initialize()
   this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)");
   this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)");
   this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)");
+  this->cmNamedCurly.compile("^[A-Za-z0-9/_.+-]+{");
 
   // Enter a policy level for this directory.
   this->PushPolicy();
@@ -2540,23 +2541,129 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
                                                 bool removeEmpty,
                                                 bool replaceAt) const
 {
-  if ( source.empty() || source.find_first_of("$@\\") == source.npos)
+  bool compareResults = false;
+  cmake::MessageType mtype = cmake::LOG;
+  std::string errorstr;
+  std::string original;
+
+  // Sanity check the @ONLY mode.
+  if(atOnly && (!noEscapes || !removeEmpty))
     {
+    // This case should never be called.  At-only is for
+    // configure-file/string which always does no escapes.
+    this->IssueMessage(cmake::INTERNAL_ERROR,
+                       "ExpandVariablesInString @ONLY called "
+                       "on something with escapes.");
     return source.c_str();
     }
 
-  // Special-case the @ONLY mode.
-  if(atOnly)
+  // Variables used in the WARN case.
+  std::string newResult;
+  std::string newErrorstr;
+  cmake::MessageType newError = cmake::LOG;
+
+  switch(this->GetPolicyStatus(cmPolicies::CMP0053))
     {
-    if(!noEscapes || !removeEmpty || !replaceAt)
+    case cmPolicies::WARN:
       {
-      // This case should never be called.  At-only is for
-      // configure-file/string which always does no escapes.
-      this->IssueMessage(cmake::INTERNAL_ERROR,
-                         "ExpandVariablesInString @ONLY called "
-                         "on something with escapes.");
+      // Save the original string for the warning.
+      original = source;
+      newResult = source;
+      compareResults = true;
+      newError =
+        ExpandVariablesInStringNew(newErrorstr, newResult, escapeQuotes,
+                                   noEscapes, atOnly, filename, line,
+                                   removeEmpty, replaceAt);
       }
+    case cmPolicies::OLD:
+      mtype = ExpandVariablesInStringOld(errorstr, source, escapeQuotes,
+                                         noEscapes, atOnly, filename,
+                                         line, removeEmpty, true);
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+      // Messaging here would be *very* verbose.
+    case cmPolicies::NEW:
+      mtype = ExpandVariablesInStringNew(errorstr, source, escapeQuotes,
+                                         noEscapes, atOnly, filename,
+                                         line, removeEmpty, replaceAt);
+      break;
+    }
 
+  // If it's an error in either case, just report the error...
+  if(mtype != cmake::LOG)
+    {
+    if(mtype == cmake::FATAL_ERROR)
+      {
+      cmSystemTools::SetFatalErrorOccured();
+      }
+    this->IssueMessage(mtype, errorstr);
+    }
+  // ...otherwise, see if there's a difference that needs to be warned about.
+  else if(compareResults && (newResult != source || newError != mtype))
+    {
+    std::string msg =
+      this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0053);
+    msg += "\n";
+
+    std::string msg_input = original;
+    cmSystemTools::ReplaceString(msg_input, "\n", "\n  ");
+    msg += "For input:\n  '";
+    msg += msg_input;
+    msg += "'\n";
+
+    std::string msg_old = source;
+    cmSystemTools::ReplaceString(msg_old, "\n", "\n  ");
+    msg += "the old evaluation rules produce:\n  '";
+    msg += msg_old;
+    msg += "'\n";
+
+    if(newError == mtype)
+      {
+      std::string msg_new = newResult;
+      cmSystemTools::ReplaceString(msg_new, "\n", "\n  ");
+      msg += "but the new evaluation rules produce:\n  '";
+      msg += msg_new;
+      msg += "'\n";
+      }
+    else
+      {
+      std::string msg_err = newErrorstr;
+      cmSystemTools::ReplaceString(msg_err, "\n", "\n  ");
+      msg += "but the new evaluation rules produce an error:\n  ";
+      msg += msg_err;
+      msg += "\n";
+      }
+
+    msg +=
+      "Using the old result for compatibility since the policy is not set.";
+
+    this->IssueMessage(cmake::AUTHOR_WARNING, msg);
+    }
+
+  return source.c_str();
+}
+
+cmake::MessageType cmMakefile::ExpandVariablesInStringOld(
+                                                std::string& errorstr,
+                                                std::string& source,
+                                                bool escapeQuotes,
+                                                bool noEscapes,
+                                                bool atOnly,
+                                                const char* filename,
+                                                long line,
+                                                bool removeEmpty,
+                                                bool replaceAt) const
+{
+  // Fast path strings without any special characters.
+  if ( source.find_first_of("$@\\") == source.npos)
+    {
+    return cmake::LOG;
+    }
+
+  // Special-case the @ONLY mode.
+  if(atOnly)
+    {
     // Store an original copy of the input.
     std::string input = source;
 
@@ -2596,7 +2703,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
     // Append the rest of the unchanged part of the string.
     source.append(in);
 
-    return source.c_str();
+    return cmake::LOG;
     }
 
   // This method replaces ${VAR} and @VAR@ where VAR is looked up
@@ -2613,6 +2720,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
   parser.SetRemoveEmpty(removeEmpty);
   int res = parser.ParseString(source.c_str(), 0);
   const char* emsg = parser.GetError();
+  cmake::MessageType mtype = cmake::LOG;
   if ( res && !emsg[0] )
     {
     source = parser.GetResult();
@@ -2639,7 +2747,7 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
     // parser reported an error message without failing because the
     // helper implementation is unhappy, which has always reported an
     // error.
-    cmake::MessageType mtype = cmake::FATAL_ERROR;
+    mtype = cmake::FATAL_ERROR;
     if(!res)
       {
       // This is a real argument parsing error.  Use policy CMP0010 to
@@ -2661,13 +2769,334 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source,
                     ->GetRequiredPolicyError(cmPolicies::CMP0010));
         case cmPolicies::NEW:
           // NEW behavior is to report the error.
-          cmSystemTools::SetFatalErrorOccured();
           break;
         }
       }
-    this->IssueMessage(mtype, error.str());
+    errorstr = error.str();
     }
-  return source.c_str();
+  return mtype;
+}
+
+typedef enum
+  {
+  NORMAL,
+  ENVIRONMENT,
+  CACHE
+  } t_domain;
+struct t_lookup
+  {
+  t_lookup(): domain(NORMAL), loc(0) {}
+  t_domain domain;
+  size_t loc;
+  };
+
+cmake::MessageType cmMakefile::ExpandVariablesInStringNew(
+                                            std::string& errorstr,
+                                            std::string& source,
+                                            bool escapeQuotes,
+                                            bool noEscapes,
+                                            bool atOnly,
+                                            const char* filename,
+                                            long line,
+                                            bool removeEmpty,
+                                            bool replaceAt) const
+{
+  // This method replaces ${VAR} and @VAR@ where VAR is looked up
+  // with GetDefinition(), if not found in the map, nothing is expanded.
+  // It also supports the $ENV{VAR} syntax where VAR is looked up in
+  // the current environment variables.
+
+  const char* in = source.c_str();
+  const char* last = in;
+  std::string result;
+  result.reserve(source.size());
+  std::stack<t_lookup> openstack;
+  bool error = false;
+  bool done = false;
+  openstack.push(t_lookup());
+  cmake::MessageType mtype = cmake::LOG;
+
+  do
+    {
+    char inc = *in;
+    switch(inc)
+      {
+      case '}':
+        if(openstack.size() > 1)
+          {
+          t_lookup var = openstack.top();
+          openstack.pop();
+          result.append(last, in - last);
+          std::string const& lookup = result.substr(var.loc);
+          const char* value = NULL;
+          std::string varresult;
+          static const std::string lineVar = "CMAKE_CURRENT_LIST_LINE";
+          switch(var.domain)
+            {
+            case NORMAL:
+              if(filename && lookup == lineVar)
+                {
+                cmOStringStream ostr;
+                ostr << line;
+                varresult = ostr.str();
+                }
+              else
+                {
+                value = this->GetDefinition(lookup);
+                }
+              break;
+            case ENVIRONMENT:
+              value = cmSystemTools::GetEnv(lookup.c_str());
+              break;
+            case CACHE:
+              value = this->GetCacheManager()->GetCacheValue(lookup);
+              break;
+            }
+          // Get the string we're meant to append to.
+          if(value)
+            {
+            if(escapeQuotes)
+              {
+              varresult = cmSystemTools::EscapeQuotes(value);
+              }
+            else
+              {
+              varresult = value;
+              }
+            }
+          else if(!removeEmpty)
+            {
+            // check to see if we need to print a warning
+            // if strict mode is on and the variable has
+            // not been "cleared"/initialized with a set(foo ) call
+            if(this->GetCMakeInstance()->GetWarnUninitialized() &&
+               !this->VariableInitialized(lookup))
+              {
+              if (this->CheckSystemVars ||
+                  cmSystemTools::IsSubDirectory(filename,
+                                                this->GetHomeDirectory()) ||
+                  cmSystemTools::IsSubDirectory(filename,
+                                             this->GetHomeOutputDirectory()))
+                {
+                cmOStringStream msg;
+                cmListFileBacktrace bt;
+                cmListFileContext lfc;
+                lfc.FilePath = filename;
+                lfc.Line = line;
+                bt.push_back(lfc);
+                msg << "uninitialized variable \'" << lookup << "\'";
+                this->GetCMakeInstance()->IssueMessage(cmake::AUTHOR_WARNING,
+                                                       msg.str().c_str(), bt);
+                }
+              }
+            }
+          result.replace(var.loc, result.size() - var.loc, varresult);
+          // Start looking from here on out.
+          last = in + 1;
+          }
+        break;
+      case '$':
+        if(!atOnly)
+          {
+          t_lookup lookup;
+          const char* next = in + 1;
+          const char* start = NULL;
+          char nextc = *next;
+          if(nextc == '{')
+            {
+            // Looking for a variable.
+            start = in + 2;
+            lookup.domain = NORMAL;
+            }
+          else if(nextc == '<')
+            {
+            }
+          else if(!nextc)
+            {
+            result.append(last, next - last);
+            last = next;
+            }
+          else if(cmHasLiteralPrefix(next, "ENV{"))
+            {
+            // Looking for an environment variable.
+            start = in + 5;
+            lookup.domain = ENVIRONMENT;
+            }
+          else if(cmHasLiteralPrefix(next, "CACHE{"))
+            {
+            // Looking for a cache variable.
+            start = in + 7;
+            lookup.domain = CACHE;
+            }
+          else
+            {
+            if(this->cmNamedCurly.find(next))
+              {
+              errorstr = "Syntax $"
+                  + std::string(next, this->cmNamedCurly.end())
+                  + "{} is not supported.  Only ${}, $ENV{}, "
+                    "and $CACHE{} are allowed.";
+              mtype = cmake::FATAL_ERROR;
+              error = true;
+              }
+            }
+          if(start)
+            {
+            result.append(last, in - last);
+            last = start;
+            in = start - 1;
+            lookup.loc = result.size();
+            openstack.push(lookup);
+            }
+          break;
+          }
+      case '\\':
+        if(!noEscapes)
+          {
+          const char* next = in + 1;
+          char nextc = *next;
+          if(nextc == 't')
+            {
+            result.append(last, in - last);
+            result.append("\t");
+            last = next + 1;
+            }
+          else if(nextc == 'n')
+            {
+            result.append(last, in - last);
+            result.append("\n");
+            last = next + 1;
+            }
+          else if(nextc == 'r')
+            {
+            result.append(last, in - last);
+            result.append("\r");
+            last = next + 1;
+            }
+          else if(nextc == ';' && openstack.size() == 1)
+            {
+            // Handled in ExpandListArgument; pass the backslash literally.
+            }
+          else if (isalnum(nextc) || nextc == '\0')
+            {
+            errorstr += "Invalid character escape '\\";
+            if (nextc)
+              {
+              errorstr += nextc;
+              errorstr += "'.";
+              }
+            else
+              {
+              errorstr += "' (at end of input).";
+              }
+            error = true;
+            }
+          else
+            {
+            // Take what we've found so far, skipping the escape character.
+            result.append(last, in - last);
+            // Start tracking from the next character.
+            last = in + 1;
+            }
+          // Skip the next character since it was escaped, but don't read past
+          // the end of the string.
+          if(*last)
+            {
+            ++in;
+            }
+          }
+        break;
+      case '\n':
+        // Onto the next line.
+        ++line;
+        break;
+      case '\0':
+        done = true;
+        break;
+      case '@':
+        if(replaceAt)
+          {
+          const char* nextAt = strchr(in + 1, '@');
+          if(nextAt && nextAt != in + 1 &&
+             nextAt == in + 1 + strspn(in + 1,
+                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                "abcdefghijklmnopqrstuvwxyz"
+                "0123456789/_.+-"))
+            {
+            std::string variable(in + 1, nextAt - in - 1);
+            std::string varresult = this->GetSafeDefinition(variable);
+            if(escapeQuotes)
+              {
+              varresult = cmSystemTools::EscapeQuotes(varresult);
+              }
+            // Skip over the variable.
+            result.append(last, in - last);
+            result.append(varresult);
+            in = nextAt;
+            last = in + 1;
+            break;
+            }
+          }
+        // Failed to find a valid @ expansion; treat it as literal.
+        /* FALLTHROUGH */
+      default:
+        {
+        if(openstack.size() > 1 &&
+           !(isalnum(inc) || inc == '_' ||
+             inc == '/' || inc == '.' ||
+             inc == '+' || inc == '-'))
+          {
+          errorstr += "Invalid character (\'";
+          errorstr += inc;
+          result.append(last, in - last);
+          errorstr += "\') in a variable name: "
+                      "'" + result.substr(openstack.top().loc) + "'";
+          mtype = cmake::FATAL_ERROR;
+          error = true;
+          }
+        break;
+        }
+      }
+    // Look at the next character.
+    } while(!error && !done && *++in);
+
+  // Check for open variable references yet.
+  if(!error && openstack.size() != 1)
+    {
+    // There's an open variable reference waiting.  Policy CMP0010 flags
+    // whether this is an error or not.  The new parser now enforces
+    // CMP0010 as well.
+    errorstr += "There is an unterminated variable reference.";
+    error = true;
+    }
+
+  if(error)
+    {
+    cmOStringStream emsg;
+    emsg << "Syntax error in cmake code ";
+    if(filename)
+      {
+      // This filename and line number may be more specific than the
+      // command context because one command invocation can have
+      // arguments on multiple lines.
+      emsg << "at\n"
+            << "  " << filename << ":" << line << "\n";
+      }
+    emsg << "when parsing string\n"
+         << "  " << source << "\n";
+    emsg << errorstr;
+    mtype = cmake::FATAL_ERROR;
+    errorstr = emsg.str();
+    }
+  else
+    {
+    // Append the rest of the unchanged part of the string.
+    result.append(last);
+
+    source = result;
+    }
+
+  return mtype;
 }
 
 void cmMakefile::RemoveVariablesInString(std::string& source,
@@ -2890,7 +3319,7 @@ bool cmMakefile::ExpandArguments(
     value = i->Value;
     this->ExpandVariablesInString(value, false, false, false,
                                   i->FilePath, i->Line,
-                                  false, true);
+                                  false, false);
 
     // If the argument is quoted, it should be one argument.
     // Otherwise, it may be a list of arguments.
@@ -3451,7 +3880,7 @@ void cmMakefile::ConfigureString(const std::string& input,
 
   // Perform variable replacements.
   this->ExpandVariablesInString(output, escapeQuotes, true,
-                                atOnly, 0, -1, true);
+                                atOnly, 0, -1, true, true);
 }
 
 int cmMakefile::ConfigureFile(const char* infile, const char* outfile,

+ 24 - 1
Source/cmMakefile.h

@@ -679,7 +679,7 @@ public:
                                       const char* filename = 0,
                                       long line = -1,
                                       bool removeEmpty = false,
-                                      bool replaceAt = true) const;
+                                      bool replaceAt = false) const;
 
   /**
    * Remove any remaining variables in the string. Anything with ${var} or
@@ -994,6 +994,7 @@ private:
   mutable cmsys::RegularExpression cmDefineRegex;
   mutable cmsys::RegularExpression cmDefine01Regex;
   mutable cmsys::RegularExpression cmAtVarRegex;
+  mutable cmsys::RegularExpression cmNamedCurly;
 
   cmPropertyMap Properties;
 
@@ -1050,6 +1051,28 @@ private:
   // Enforce rules about CMakeLists.txt files.
   void EnforceDirectoryLevelRules() const;
 
+  // CMP0053 == old
+  cmake::MessageType ExpandVariablesInStringOld(
+                                  std::string& errorstr,
+                                  std::string& source,
+                                  bool escapeQuotes,
+                                  bool noEscapes,
+                                  bool atOnly,
+                                  const char* filename,
+                                  long line,
+                                  bool removeEmpty,
+                                  bool replaceAt) const;
+  // CMP0053 == new
+  cmake::MessageType ExpandVariablesInStringNew(
+                                  std::string& errorstr,
+                                  std::string& source,
+                                  bool escapeQuotes,
+                                  bool noEscapes,
+                                  bool atOnly,
+                                  const char* filename,
+                                  long line,
+                                  bool removeEmpty,
+                                  bool replaceAt) const;
   bool GeneratingBuildSystem;
   /**
    * Old version of GetSourceFileWithOutput(const std::string&) kept for

+ 5 - 0
Source/cmPolicies.cxx

@@ -354,6 +354,11 @@ cmPolicies::cmPolicies()
     "Reject source and build dirs in installed "
     "INTERFACE_INCLUDE_DIRECTORIES.",
     3,1,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0053, "CMP0053",
+    "Simplify variable reference and escape sequence evaluation.",
+    3,1,0, cmPolicies::WARN);
 }
 
 cmPolicies::~cmPolicies()

+ 2 - 0
Source/cmPolicies.h

@@ -108,6 +108,8 @@ public:
     CMP0052, ///< Reject source and build dirs in installed
     /// INTERFACE_INCLUDE_DIRECTORIES
 
+    CMP0053, ///< Simplify variable reference and escape sequence evaluation
+
     /** \brief Always the last entry.
      *
      * Useful mostly to avoid adding a comma the last policy when adding a new

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-At-NEW-stderr.txt

@@ -0,0 +1 @@
+^-->\${right}<--$

+ 9 - 0
Tests/RunCMake/Syntax/CMP0053-At-NEW.cmake

@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0053 NEW)
+
+set(right "wrong")
+set(var "\${right}")
+# Not expanded here with the new policy.
+set(ref "@var@")
+
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-At-OLD-stderr.txt

@@ -0,0 +1 @@
+^-->wrong<--$

+ 9 - 0
Tests/RunCMake/Syntax/CMP0053-At-OLD.cmake

@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0053 OLD)
+
+set(right "wrong")
+set(var "\${right}")
+# Expanded here with the old policy.
+set(ref "@var@")
+
+string(CONFIGURE "${ref}" output)
+message("-->${output}<--")

+ 27 - 0
Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines-stderr.txt

@@ -0,0 +1,27 @@
+^CMake Warning \(dev\) at CMP0053-At-WARN-newlines.cmake:4 \(set\):
+  Policy CMP0053 is not set: Simplify variable reference and escape sequence
+  evaluation.  Run "cmake --help-policy CMP0053" for policy details.  Use the
+  cmake_policy command to set the policy and suppress this warning.
+
+  For input:
+
+    '
+    @var@
+    '
+
+  the old evaluation rules produce:
+
+    '
+    \${right}
+    '
+
+  but the new evaluation rules produce:
+
+    '
+    @var@
+    '
+
+  Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$

+ 6 - 0
Tests/RunCMake/Syntax/CMP0053-At-WARN-newlines.cmake

@@ -0,0 +1,6 @@
+set(right "wrong")
+set(var "\${right}")
+# Expanded here with the old policy.
+set(ref "
+@var@
+")

+ 21 - 0
Tests/RunCMake/Syntax/CMP0053-At-WARN-stderr.txt

@@ -0,0 +1,21 @@
+^CMake Warning \(dev\) at CMP0053-At-WARN.cmake:4 \(set\):
+  Policy CMP0053 is not set: Simplify variable reference and escape sequence
+  evaluation.  Run "cmake --help-policy CMP0053" for policy details.  Use the
+  cmake_policy command to set the policy and suppress this warning.
+
+  For input:
+
+    '@var@'
+
+  the old evaluation rules produce:
+
+    '\${right}'
+
+  but the new evaluation rules produce:
+
+    '@var@'
+
+  Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.$

+ 4 - 0
Tests/RunCMake/Syntax/CMP0053-At-WARN.cmake

@@ -0,0 +1,4 @@
+set(right "wrong")
+set(var "\${right}")
+# Expanded here with the old policy.
+set(ref "@var@")

+ 56 - 0
Tests/RunCMake/Syntax/CMP0053-NUL-stderr.txt

@@ -0,0 +1,56 @@
+^CMake Warning \(dev\) at CMP0053-NUL.cmake:1 \(set\):
+  Policy CMP0053 is not set: Simplify variable reference and escape sequence
+  evaluation.  Run "cmake --help-policy CMP0053" for policy details.  Use the
+  cmake_policy command to set the policy and suppress this warning.
+
+  For input:
+
+    '\\0'
+
+  the old evaluation rules produce:
+
+    ''
+
+  but the new evaluation rules produce an error:
+
+    Syntax error in cmake code at
+      .*/Tests/RunCMake/Syntax/CMP0053-NUL.cmake:1
+    when parsing string
+      \\0
+    Invalid character escape '\\0'.
+
+  Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at CMP0053-NUL.cmake:2 \(set\):
+  Policy CMP0053 is not set: Simplify variable reference and escape sequence
+  evaluation.  Run "cmake --help-policy CMP0053" for policy details.  Use the
+  cmake_policy command to set the policy and suppress this warning.
+
+  For input:
+
+    '\\0'
+
+  the old evaluation rules produce:
+
+    ''
+
+  but the new evaluation rules produce an error:
+
+    Syntax error in cmake code at
+      .*/Tests/RunCMake/Syntax/CMP0053-NUL.cmake:2
+    when parsing string
+      \\0
+    Invalid character escape '\\0'.
+
+  Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+--><--
+--><--
+--><--
+--><--$

+ 6 - 0
Tests/RunCMake/Syntax/CMP0053-NUL.cmake

@@ -0,0 +1,6 @@
+set(qnul "\0")
+set(nul \0)
+message(-->${nul}<--)
+message(-->${qnul}<--)
+message("-->${nul}<--")
+message("-->${qnul}<--")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithCarriageReturn.cmake:2 \(message\):
+  message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturn.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\rwith\rcarriagereturn})

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithCarriageReturnQuoted.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\rwith\rcarriagereturn}")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithEscapedSpaces.cmake:2 \(message\):
+  message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpaces.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\ with\ escaped\ space})

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedSpacesQuoted.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\ with\ escaped\ space}")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithEscapedTabs.cmake:2 \(message\):
+  message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabs.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\	with\	escaped\	tab})

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithEscapedTabsQuoted.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\	with\	escaped\	tab}")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithNewline-result.txt

@@ -0,0 +1 @@
+1

+ 4 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithNewline-stderr.txt

@@ -0,0 +1,4 @@
+^CMake Error at CMP0053-NameWithNewline.cmake:2 \(message\):
+  message called with incorrect number of arguments
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithNewline.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var\nwith\nnewline})

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithNewlineQuoted.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var\nwith\nnewline}")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithSpaces-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithSpaces.cmake:2 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake:2
+
+  when parsing string
+
+    \${var
+
+  There is an unterminated variable reference.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithSpaces.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var with space})

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithSpacesQuoted.cmake:2 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake:2
+
+  when parsing string
+
+    \${var with space}
+
+  Invalid character \(' '\) in a variable name: 'var'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithSpacesQuoted.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var with space}")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithTabs-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithTabs-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithTabs.cmake:2 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake:2
+
+  when parsing string
+
+    \${var
+
+  There is an unterminated variable reference.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithTabs.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message(${var	with	tab})

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at CMP0053-NameWithTabsQuoted.cmake:2 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake:2
+
+  when parsing string
+
+    \${var	with	tab}
+
+  Invalid character \('	'\) in a variable name: 'var'
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/Syntax/CMP0053-NameWithTabsQuoted.cmake

@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0053 NEW)
+message("${var	with	tab}")

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-ParenInENV-stderr.txt

@@ -0,0 +1 @@
+-->value<--

+ 3 - 0
Tests/RunCMake/Syntax/CMP0053-ParenInENV.cmake

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+set("ENV{e(x)}" value)
+message(-->$ENV{e\(x\)}<--)

+ 1 - 0
Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV-stderr.txt

@@ -0,0 +1 @@
+-->value<--

+ 3 - 0
Tests/RunCMake/Syntax/CMP0053-ParenInQuotedENV.cmake

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+set("ENV{e(x)}" value)
+message("-->$ENV{e\(x\)}<--")

+ 28 - 0
Tests/RunCMake/Syntax/CMP0053-WARN-stderr.txt

@@ -0,0 +1,28 @@
+^CMake Warning \(dev\) at CMP0053-WARN.cmake:2 \(message\):
+  Policy CMP0053 is not set: Simplify variable reference and escape sequence
+  evaluation.  Run "cmake --help-policy CMP0053" for policy details.  Use the
+  cmake_policy command to set the policy and suppress this warning.
+
+  For input:
+
+    '\\'
+
+  the old evaluation rules produce:
+
+    '\\'
+
+  but the new evaluation rules produce an error:
+
+    Syntax error in cmake code at
+      .*/Tests/RunCMake/Syntax/CMP0053-WARN.cmake:2
+    when parsing string
+      \\
+    Invalid character escape '\\' \(at end of input\).
+
+  Using the old result for compatibility since the policy is not set.
+Call Stack \(most recent call first\):
+  CMP0053-WARN.cmake:5 \(escape\)
+  CMakeLists.txt:3 \(include\)
+This warning is for project developers.  Use -Wno-dev to suppress it.
+
+\\$

+ 5 - 0
Tests/RunCMake/Syntax/CMP0053-WARN.cmake

@@ -0,0 +1,5 @@
+macro (escape str)
+  message("${str}")
+endmacro ()
+
+escape("\\")

+ 1 - 1
Tests/RunCMake/Syntax/CMakeLists.txt

@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.9)
+cmake_minimum_required(VERSION 2.8.12)
 project(${RunCMake_TEST} NONE)
 include(${RunCMake_TEST}.cmake)

+ 1 - 0
Tests/RunCMake/Syntax/Escape2-result.txt

@@ -0,0 +1 @@
+1

+ 13 - 0
Tests/RunCMake/Syntax/Escape2-stderr.txt

@@ -0,0 +1,13 @@
+CMake Error at Escape2.cmake:4 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/Escape2.cmake:4
+
+  when parsing string
+
+    \\
+
+  Invalid character escape '\\' \(at end of input\).
+Call Stack \(most recent call first\):
+  Escape2.cmake:7 \(escape\)
+  CMakeLists.txt:3 \(include\)

+ 7 - 0
Tests/RunCMake/Syntax/Escape2.cmake

@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0053 NEW)
+
+macro (escape str)
+  message("${str}")
+endmacro ()
+
+escape("\\")

+ 1 - 0
Tests/RunCMake/Syntax/EscapeChar-char-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/EscapeChar-char-stderr.txt.in

@@ -0,0 +1,12 @@
+CMake Error at EscapeChar-@char@-@[email protected]:3 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/EscapeChar-@char@-@[email protected]:3
+
+  when parsing string
+
+    -->\\@char@<--
+
+  Invalid character escape '\\@char@'.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)

+ 3 - 0
Tests/RunCMake/Syntax/EscapeChar-char.cmake.in

@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0053 NEW)
+
+message("-->\@char@<--")

+ 12 - 0
Tests/RunCMake/Syntax/EscapeCharsAllowed-stderr.txt

@@ -0,0 +1,12 @@
+^-->semicolon<--
+-->dollar<--
+-->brace<--
+-->bracket<--
+-->newline<--
+-->octothorpe<--
+-->splat<--
+-->caret<--
+-->paren<--
+-->dquote<--
+-->top-levelsemicolon<--
+-->top-level;escaped;semicolon<--$

+ 26 - 0
Tests/RunCMake/Syntax/EscapeCharsAllowed.cmake

@@ -0,0 +1,26 @@
+cmake_policy(SET CMP0053 NEW)
+
+set("semicolon;in;name" semicolon)
+set("dollar$in$name" dollar)
+set("brace{in}name" brace)
+set("bracket[in]name" bracket)
+set("newline\nin\nname" newline)
+set("octothorpe\#in\#name" octothorpe)
+set("splat\@in\@name" splat)
+set("caret\^in\^name" caret)
+set("paren\(in\)name" paren)
+set("dquote\"in\"name" dquote)
+
+message("-->${semicolon\;in\;name}<--")
+message("-->${dollar\$in\$name}<--")
+message("-->${brace\{in\}name}<--")
+message("-->${bracket\[in\]name}<--")
+message("-->${newline\nin\nname}<--")
+message("-->${octothorpe\#in\#name}<--")
+message("-->${splat\@in\@name}<--")
+message("-->${caret\^in\^name}<--")
+message("-->${paren\(in\)name}<--")
+message("-->${dquote\"in\"name}<--")
+
+message(-->top-level;semicolon<--)
+message(-->top-level\;escaped\;semicolon<--)

+ 42 - 0
Tests/RunCMake/Syntax/EscapeCharsDisallowed.cmake

@@ -0,0 +1,42 @@
+set(disallowed_chars
+  a b c d e f g h i j l m   o p q   s   u v w x y z
+  A B C D E F G H I J L M N O P Q R S T U V W X Y Z
+  0 1 2 3 4 5 6 6 7 8 9)
+set(testnum 0)
+
+configure_file(
+  "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+  "${RunCMake_BINARY_DIR}/CMakeLists.txt"
+  COPYONLY)
+
+foreach (char IN LISTS disallowed_chars)
+  configure_file(
+    "${RunCMake_SOURCE_DIR}/EscapeChar-char.cmake.in"
+    "${RunCMake_BINARY_DIR}/EscapeChar-${char}-${testnum}.cmake"
+    @ONLY)
+  configure_file(
+    "${RunCMake_SOURCE_DIR}/EscapeChar-char-stderr.txt.in"
+    "${RunCMake_BINARY_DIR}/EscapeChar-${char}-${testnum}-stderr.txt"
+    @ONLY)
+  configure_file(
+    "${RunCMake_SOURCE_DIR}/EscapeChar-char-result.txt"
+    "${RunCMake_BINARY_DIR}/EscapeChar-${char}-${testnum}-result.txt"
+    COPYONLY)
+
+  math(EXPR testnum "${testnum} + 1")
+endforeach ()
+
+function (run_tests)
+  set(GENERATED_RUNCMAKE_TESTS TRUE)
+  # Find the tests in the binary directory.
+  set(RunCMake_SOURCE_DIR "${RunCMake_BINARY_DIR}")
+
+  set(testnum 0)
+  foreach (char IN LISTS disallowed_chars)
+    run_cmake("EscapeChar-${char}-${testnum}")
+
+    math(EXPR testnum "${testnum} + 1")
+  endforeach ()
+endfunction ()
+
+run_tests()

+ 1 - 0
Tests/RunCMake/Syntax/NameWithCarriageReturn-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithCarriageReturn-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithCarriageReturn.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake:1
+
+  when parsing string
+
+    \${var\\rwith\\rcarriagereturn}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithCarriageReturn.cmake

@@ -0,0 +1 @@
+message(${var\rwith\rcarriagereturn})

+ 1 - 0
Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithCarriageReturnQuoted.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake:1
+
+  when parsing string
+
+    \${var\\rwith\\rcarriagereturn}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithCarriageReturnQuoted.cmake

@@ -0,0 +1 @@
+message("${var\rwith\rcarriagereturn}")

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedSpaces-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithEscapedSpaces-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedSpaces.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake:1
+
+  when parsing string
+
+    \${var\\ with\\ escaped\\ space}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedSpaces.cmake

@@ -0,0 +1 @@
+message(${var\ with\ escaped\ space})

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedSpacesQuoted.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake:1
+
+  when parsing string
+
+    \${var\\ with\\ escaped\\ space}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedSpacesQuoted.cmake

@@ -0,0 +1 @@
+message("${var\ with\ escaped\ space}")

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedTabs-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithEscapedTabs-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedTabs.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake:1
+
+  when parsing string
+
+    \${var\\	with\\	escaped\\	tab}
+
+  Invalid escape sequence \\.?
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedTabs.cmake

@@ -0,0 +1 @@
+message(${var\	with\	escaped\	tab})

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithEscapedTabsQuoted.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake:1
+
+  when parsing string
+
+    \${var\\	with\\	escaped\\	tab}
+
+  Invalid escape sequence \\.?
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithEscapedTabsQuoted.cmake

@@ -0,0 +1 @@
+message("${var\	with\	escaped\	tab}")

+ 1 - 0
Tests/RunCMake/Syntax/NameWithNewline-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithNewline-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithNewline.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithNewline.cmake:1
+
+  when parsing string
+
+    \${var\\nwith\\nnewline}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithNewline.cmake

@@ -0,0 +1 @@
+message(${var\nwith\nnewline})

+ 1 - 0
Tests/RunCMake/Syntax/NameWithNewlineQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithNewlineQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithNewlineQuoted.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake:1
+
+  when parsing string
+
+    \${var\\nwith\\nnewline}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(7\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithNewlineQuoted.cmake

@@ -0,0 +1 @@
+message("${var\nwith\nnewline}")

+ 1 - 0
Tests/RunCMake/Syntax/NameWithSpaces-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithSpaces-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithSpaces.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithSpaces.cmake:1
+
+  when parsing string
+
+    \${var
+
+  syntax error, unexpected \$end, expecting } \(5\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithSpaces.cmake

@@ -0,0 +1 @@
+message(${var with space})

+ 1 - 0
Tests/RunCMake/Syntax/NameWithSpacesQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithSpacesQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithSpacesQuoted.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake:1
+
+  when parsing string
+
+    \${var with space}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(17\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithSpacesQuoted.cmake

@@ -0,0 +1 @@
+message("${var with space}")

+ 1 - 0
Tests/RunCMake/Syntax/NameWithTabs-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithTabs-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithTabs.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithTabs.cmake:1
+
+  when parsing string
+
+    \${var
+
+  syntax error, unexpected \$end, expecting } \(5\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

+ 1 - 0
Tests/RunCMake/Syntax/NameWithTabs.cmake

@@ -0,0 +1 @@
+message(${var	with	tab})

+ 1 - 0
Tests/RunCMake/Syntax/NameWithTabsQuoted-result.txt

@@ -0,0 +1 @@
+1

+ 12 - 0
Tests/RunCMake/Syntax/NameWithTabsQuoted-stderr.txt

@@ -0,0 +1,12 @@
+^CMake Error at NameWithTabsQuoted.cmake:1 \(message\):
+  Syntax error in cmake code at
+
+    .*/Tests/RunCMake/Syntax/NameWithTabsQuoted.cmake:1
+
+  when parsing string
+
+    \${var	with	tab}
+
+  syntax error, unexpected cal_SYMBOL, expecting } \(15\)
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$

Some files were not shown because too many files changed in this diff