From 76f0bcdfb6e04f1f6089ea693d69b642bbf26e82 Mon Sep 17 00:00:00 2001
From: Marc Chevrier <marc.chevrier@gmail.com>
Date: Wed, 13 Jan 2021 15:27:49 +0100
Subject: cmake_path: various updates

To follow discussions in #21385 and !5682:
* Fix bug in cmCMakePath::IsSuffix() method
* cmake_path(HASH) always normalized paths (NORMALIZE option removed)
---
 Help/command/cmake_path.rst               |  7 +++----
 Source/cmCMakePath.cxx                    |  3 ++-
 Source/cmCMakePathCommand.cxx             | 18 ++++--------------
 Tests/RunCMake/cmake_path/HASH.cmake      |  5 -----
 Tests/RunCMake/cmake_path/IS_PREFIX.cmake |  5 +++++
 5 files changed, 14 insertions(+), 24 deletions(-)

diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst
index 2d37ae0..3c9653e 100644
--- a/Help/command/cmake_path.rst
+++ b/Help/command/cmake_path.rst
@@ -156,7 +156,7 @@ Synopsis
     cmake_path(`IS_PREFIX`_ <path-var> <input> [NORMALIZE] <out-var>)
 
   `Hashing`_
-    cmake_path(`HASH`_ <path-var> [NORMALIZE] <out-var>)
+    cmake_path(`HASH`_ <path-var> <out-var>)
 
 Decomposition
 ^^^^^^^^^^^^^
@@ -807,11 +807,10 @@ Hashing
 
 .. code-block:: cmake
 
-    cmake_path(HASH <path-var> [NORMALIZE] <out-var>)
+    cmake_path(HASH <path-var> <out-var>)
 
 Compute hash value of ``<path-var>`` such that if for two paths (``p1`` and
 ``p2``) are equal (:ref:`COMPARE ... EQUAL <COMPARE>`) then hash value of p1 is
 equal to hash value of p2.
 
-When ``NORMALIZE`` option is specified, the paths are :ref:`normalized
-<NORMAL_PATH>` before the check.
+Path is always :ref:`normalized <NORMAL_PATH>` before the hash is computed.
diff --git a/Source/cmCMakePath.cxx b/Source/cmCMakePath.cxx
index b8215df..73321c6 100644
--- a/Source/cmCMakePath.cxx
+++ b/Source/cmCMakePath.cxx
@@ -88,7 +88,8 @@ bool cmCMakePath::IsPrefix(const cmCMakePath& path) const
     ++prefix_it;
     ++path_it;
   }
-  return prefix_it == prefix_end;
+  return (prefix_it == prefix_end) ||
+    (prefix_it->empty() && path_it != path_end);
 }
 
 std::string cmCMakePath::FormatPath(std::string path, format fmt)
diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx
index e9bf84a..5662a2f 100644
--- a/Source/cmCMakePathCommand.cxx
+++ b/Source/cmCMakePathCommand.cxx
@@ -929,17 +929,8 @@ bool HandleIsPrefixCommand(std::vector<std::string> const& args,
 bool HandleHashCommand(std::vector<std::string> const& args,
                        cmExecutionStatus& status)
 {
-  if (args.size() < 3 || args.size() > 4) {
-    status.SetError("HASH must be called with two or three arguments.");
-    return false;
-  }
-
-  static NormalizeParser const parser;
-
-  const auto arguments = parser.Parse(args);
-
-  if (parser.GetInputs().size() != 1) {
-    status.SetError("HASH called with unexpected arguments.");
+  if (args.size() != 3) {
+    status.SetError("HASH must be called with two arguments.");
     return false;
   }
 
@@ -948,15 +939,14 @@ bool HandleHashCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  const auto& output = parser.GetInputs().front();
+  const auto& output = args[2];
 
   if (output.empty()) {
     status.SetError("Invalid name for output variable.");
     return false;
   }
 
-  auto hash = hash_value(arguments.Normalize ? cmCMakePath(inputPath).Normal()
-                                             : cmCMakePath(inputPath));
+  auto hash = hash_value(cmCMakePath(inputPath).Normal());
 
   std::ostringstream out;
   out << std::setbase(16) << hash;
diff --git a/Tests/RunCMake/cmake_path/HASH.cmake b/Tests/RunCMake/cmake_path/HASH.cmake
index dfcf2b2..eb04f7f 100644
--- a/Tests/RunCMake/cmake_path/HASH.cmake
+++ b/Tests/RunCMake/cmake_path/HASH.cmake
@@ -14,11 +14,6 @@ set (path1 "a///b/c/../d")
 cmake_path(HASH path1 hash1)
 set (path2 "a/b////d")
 cmake_path(HASH path2 hash2)
-if (hash1 STREQUAL hash2)
-  list (APPEND errors "'hash values equal for '${path1}' and '${path2}'")
-endif()
-cmake_path(HASH path1 hash1 NORMALIZE)
-cmake_path(HASH path2 NORMALIZE hash2)
 if (NOT hash1 STREQUAL hash2)
   list (APPEND errors "'hash values not equal for '${path1}' and '${path2}'")
 endif()
diff --git a/Tests/RunCMake/cmake_path/IS_PREFIX.cmake b/Tests/RunCMake/cmake_path/IS_PREFIX.cmake
index 53da93b..9160dab 100644
--- a/Tests/RunCMake/cmake_path/IS_PREFIX.cmake
+++ b/Tests/RunCMake/cmake_path/IS_PREFIX.cmake
@@ -18,5 +18,10 @@ if (NOT output)
   list (APPEND errors "'${path} is not prefix of 'a/b/d/e'")
 endif()
 
+set(path "/a/b/..")
+cmake_path(IS_PREFIX path "/a/c/../b" NORMALIZE output)
+if (NOT output)
+  list (APPEND errors "'${path} is not prefix of '/a/c/../b'")
+endif()
 
 check_errors (IS_PREFIX ${errors})
-- 
cgit v0.12