Merge topic 'update-kwsys'

4eae1c0816 Merge branch 'upstream-KWSys' into update-kwsys
f3cd44263e KWSys 2018-06-14 (2b0ca1d8)

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2148
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 589e572..ad2c428 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -28,7 +28,7 @@
 
   `Ordering`_
     list(`REVERSE`_ <list>)
-    list(`SORT`_ <list>)
+    list(`SORT`_ <list> [...])
 
 Introduction
 ^^^^^^^^^^^^
@@ -253,7 +253,23 @@
 
 ::
 
-  list(SORT <list>)
-
+  list(SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>])
 
 Sorts the list in-place alphabetically.
+Use the option ``<compare>`` to select the compare type for sorting.
+The ``<compare>`` option may be one of:
+
+* ``STRING``: Sorts a list of strings alphabetically.
+* ``FILE_BASENAME``: Sort a list of pathnames of files by their basenames.
+
+Use the option ``<case>`` to select a case sensitive or case insensitive sort mode.
+The ``<case>`` option may be one of:
+
+* ``SENSITIVE``: Sorts the list alphabetically.
+* ``INSENSITIVE``: Sorts the list alphabetically in descending order.
+
+Use the option ``<order>`` to select a case sensitive or case insensitive sort mode.
+The ``<order>`` option may be one of:
+
+* ``ASCENDING``: Sorts the list in ascending order.
+* ``DESCENDING``: Sorts the list in descending order.
diff --git a/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst b/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst
new file mode 100644
index 0000000..2a2721f
--- /dev/null
+++ b/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst
@@ -0,0 +1,5 @@
+UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES
+--------------------------------------
+
+* Module ``UseSWIG`` gains capability to manage target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` for ``SWIG`` compilation.
diff --git a/Help/release/dev/list_sort.rst b/Help/release/dev/list_sort.rst
new file mode 100644
index 0000000..8971b78
--- /dev/null
+++ b/Help/release/dev/list_sort.rst
@@ -0,0 +1,5 @@
+list_sort
+---------
+
+* The :command:`list(SORT)` command gained options to control the
+  comparison operation used to order the entries.
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 7127b8f..851101b 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -96,6 +96,13 @@
   :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
   :prop_sf:`COMPILE_OPTIONS`.
 
+``USE_TARGET_INCLUDE_DIRECTORIES``
+  If set to ``TRUE``, contents of target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` will be forwarded to ``SWIG`` compiler.
+  If set to ``FALSE`` target property :prop_tgt:`INCLUDE_DIRECTORIES` will be
+  ignored. If not set, target property ``SWIG_USE_TARGT_INCLUDE_DIRECTORIES``
+  will be considered.
+
 ``GENERATED_INCLUDE_DIRECTORIES``, ``GENERATED_COMPILE_DEFINITIONS`` and ``GENERATED_COMPILE_OPTIONS``
   Add custom flags to the C/C++ generated source. They will fill, respectively,
   properties :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
@@ -127,6 +134,13 @@
     set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2)
     set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb)
 
+``SWIG_USE_TARGET_INCLUDE_DIRECTORIES``
+  If set to ``TRUE``, contents of target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` will be forwarded to ``SWIG`` compiler.
+  If set to ``FALSE`` or not defined, target property
+  :prop_tgt:`INCLUDE_DIRECTORIES` will be ignored. This behavior can be
+  overridden by specifying source property ``USE_TARGET_INCLUDE_DIRECTORIES``.
+
 ``SWIG_GENERATED_INCLUDE_DIRECTORIES``, ``SWIG_GENERATED_COMPILE_DEFINITIONS`` and ``SWIG_GENERATED_COMPILE_OPTIONS``
   These properties will populate, respectively, properties
   :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and
@@ -310,6 +324,14 @@
   endif()
   set (property "$<TARGET_PROPERTY:${name},SWIG_INCLUDE_DIRECTORIES>")
   list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:$<TARGET_GENEX_EVAL:${name},${property}>,$<SEMICOLON>-I>>")
+  set (property "$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>")
+  get_source_file_property(use_target_include_dirs "${infile}" USE_TARGET_INCLUDE_DIRECTORIES)
+  if (use_target_include_dirs)
+    list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
+  elseif(use_target_include_dirs STREQUAL "NOTFOUND")
+    # not defined at source level, rely on target level
+    list (APPEND swig_source_file_flags "$<$<AND:$<BOOL:$<TARGET_PROPERTY:${name},SWIG_USE_TARGET_INCLUDE_DIRECTORIES>>,$<BOOL:${property}>>:-I$<JOIN:${property},$<SEMICOLON>-I>>")
+  endif()
 
   set (property "$<TARGET_PROPERTY:${name},SWIG_COMPILE_DEFINITIONS>")
   list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:$<TARGET_GENEX_EVAL:${name},${property}>,$<SEMICOLON>-D>>")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 2486bdf..0413faa 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 12)
-set(CMake_VERSION_PATCH 20180614)
+set(CMake_VERSION_PATCH 20180618)
 #set(CMake_VERSION_RC 1)
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 1ac2cc2..ba0c843 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -963,14 +963,193 @@
   return true;
 }
 
+class cmStringSorter
+{
+public:
+  enum class Order
+  {
+    UNINITIALIZED,
+    ASCENDING,
+    DESCENDING,
+  };
+
+  enum class Compare
+  {
+    UNINITIALIZED,
+    STRING,
+    FILE_BASENAME,
+  };
+  enum class CaseSensitivity
+  {
+    UNINITIALIZED,
+    SENSITIVE,
+    INSENSITIVE,
+  };
+
+protected:
+  typedef std::string (*StringFilter)(const std::string& in);
+  StringFilter GetCompareFilter(Compare compare)
+  {
+    return (compare == Compare::FILE_BASENAME) ? cmSystemTools::GetFilenameName
+                                               : nullptr;
+  }
+
+  StringFilter GetCaseFilter(CaseSensitivity sensitivity)
+  {
+    return (sensitivity == CaseSensitivity::INSENSITIVE)
+      ? cmSystemTools::LowerCase
+      : nullptr;
+  }
+
+public:
+  cmStringSorter(Compare compare, CaseSensitivity caseSensitivity,
+                 Order desc = Order::ASCENDING)
+    : filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) }
+    , descending(desc == Order::DESCENDING)
+  {
+  }
+
+  std::string ApplyFilter(const std::string& argument)
+  {
+    std::string result = argument;
+    for (auto filter : filters) {
+      if (filter != nullptr) {
+        result = filter(result);
+      }
+    }
+    return result;
+  }
+
+  bool operator()(const std::string& a, const std::string& b)
+  {
+    std::string af = ApplyFilter(a);
+    std::string bf = ApplyFilter(b);
+    bool result;
+    if (descending) {
+      result = bf < af;
+    } else {
+      result = af < bf;
+    }
+    return result;
+  }
+
+protected:
+  StringFilter filters[2] = { nullptr, nullptr };
+  bool descending;
+};
+
 bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
 {
   assert(args.size() >= 2);
-  if (args.size() > 2) {
-    this->SetError("sub-command SORT only takes one argument.");
+  if (args.size() > 8) {
+    this->SetError("sub-command SORT only takes up to six arguments.");
     return false;
   }
 
+  auto sortCompare = cmStringSorter::Compare::UNINITIALIZED;
+  auto sortCaseSensitivity = cmStringSorter::CaseSensitivity::UNINITIALIZED;
+  auto sortOrder = cmStringSorter::Order::UNINITIALIZED;
+
+  size_t argumentIndex = 2;
+  const std::string messageHint = "sub-command SORT ";
+
+  while (argumentIndex < args.size()) {
+    const std::string option = args[argumentIndex++];
+    if (option == "COMPARE") {
+      if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) {
+        std::string error = messageHint + "option \"" + option +
+          "\" has been specified multiple times.";
+        this->SetError(error);
+        return false;
+      }
+      if (argumentIndex < args.size()) {
+        const std::string argument = args[argumentIndex++];
+        if (argument == "STRING") {
+          sortCompare = cmStringSorter::Compare::STRING;
+        } else if (argument == "FILE_BASENAME") {
+          sortCompare = cmStringSorter::Compare::FILE_BASENAME;
+        } else {
+          std::string error = messageHint + "value \"" + argument +
+            "\" for option \"" + option + "\" is invalid.";
+          this->SetError(error);
+          return false;
+        }
+      } else {
+        std::string error =
+          messageHint + "missing argument for option \"" + option + "\".";
+        this->SetError(error);
+        return false;
+      }
+    } else if (option == "CASE") {
+      if (sortCaseSensitivity !=
+          cmStringSorter::CaseSensitivity::UNINITIALIZED) {
+        std::string error = messageHint + "option \"" + option +
+          "\" has been specified multiple times.";
+        this->SetError(error);
+        return false;
+      }
+      if (argumentIndex < args.size()) {
+        const std::string argument = args[argumentIndex++];
+        if (argument == "SENSITIVE") {
+          sortCaseSensitivity = cmStringSorter::CaseSensitivity::SENSITIVE;
+        } else if (argument == "INSENSITIVE") {
+          sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE;
+        } else {
+          std::string error = messageHint + "value \"" + argument +
+            "\" for option \"" + option + "\" is invalid.";
+          this->SetError(error);
+          return false;
+        }
+      } else {
+        std::string error =
+          messageHint + "missing argument for option \"" + option + "\".";
+        this->SetError(error);
+        return false;
+      }
+    } else if (option == "ORDER") {
+
+      if (sortOrder != cmStringSorter::Order::UNINITIALIZED) {
+        std::string error = messageHint + "option \"" + option +
+          "\" has been specified multiple times.";
+        this->SetError(error);
+        return false;
+      }
+      if (argumentIndex < args.size()) {
+        const std::string argument = args[argumentIndex++];
+        if (argument == "ASCENDING") {
+          sortOrder = cmStringSorter::Order::ASCENDING;
+        } else if (argument == "DESCENDING") {
+          sortOrder = cmStringSorter::Order::DESCENDING;
+        } else {
+          std::string error = messageHint + "value \"" + argument +
+            "\" for option \"" + option + "\" is invalid.";
+          this->SetError(error);
+          return false;
+        }
+      } else {
+        std::string error =
+          messageHint + "missing argument for option \"" + option + "\".";
+        this->SetError(error);
+        return false;
+      }
+    } else {
+      std::string error =
+        messageHint + "option \"" + option + "\" is unknown.";
+      this->SetError(error);
+      return false;
+    }
+  }
+  // set Default Values if Option is not given
+  if (sortCompare == cmStringSorter::Compare::UNINITIALIZED) {
+    sortCompare = cmStringSorter::Compare::STRING;
+  }
+  if (sortCaseSensitivity == cmStringSorter::CaseSensitivity::UNINITIALIZED) {
+    sortCaseSensitivity = cmStringSorter::CaseSensitivity::SENSITIVE;
+  }
+  if (sortOrder == cmStringSorter::Order::UNINITIALIZED) {
+    sortOrder = cmStringSorter::Order::ASCENDING;
+  }
+
   const std::string& listName = args[1];
   // expand the variable
   std::vector<std::string> varArgsExpanded;
@@ -979,7 +1158,14 @@
     return false;
   }
 
-  std::sort(varArgsExpanded.begin(), varArgsExpanded.end());
+  if ((sortCompare == cmStringSorter::Compare::STRING) &&
+      (sortCaseSensitivity == cmStringSorter::CaseSensitivity::SENSITIVE) &&
+      (sortOrder == cmStringSorter::Order::ASCENDING)) {
+    std::sort(varArgsExpanded.begin(), varArgsExpanded.end());
+  } else {
+    cmStringSorter sorter(sortCompare, sortCaseSensitivity, sortOrder);
+    std::sort(varArgsExpanded.begin(), varArgsExpanded.end(), sorter);
+  }
 
   std::string value = cmJoin(varArgsExpanded, ";");
   this->Makefile->AddDefinition(listName, value.c_str());
diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake
index bdc23a4..a8a0b57 100644
--- a/Tests/RunCMake/list/RunCMakeTest.cmake
+++ b/Tests/RunCMake/list/RunCMakeTest.cmake
@@ -20,7 +20,6 @@
 run_cmake(LENGTH-TooManyArguments)
 run_cmake(REMOVE_DUPLICATES-TooManyArguments)
 run_cmake(REVERSE-TooManyArguments)
-run_cmake(SORT-TooManyArguments)
 run_cmake(SUBLIST-TooManyArguments)
 
 run_cmake(FILTER-NotList)
@@ -84,3 +83,16 @@
 run_cmake(TRANSFORM-APPEND)
 run_cmake(TRANSFORM-PREPEND)
 run_cmake(TRANSFORM-REPLACE)
+
+# argument tests
+run_cmake(SORT-WrongOption)
+run_cmake(SORT-BadCaseOption)
+run_cmake(SORT-BadCompareOption)
+run_cmake(SORT-BadOrderOption)
+run_cmake(SORT-DuplicateOrderOption)
+run_cmake(SORT-DuplicateCompareOption)
+run_cmake(SORT-DuplicateCaseOption)
+run_cmake(SORT-NoCaseOption)
+
+# Successful tests
+run_cmake(SORT)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-BadCaseOption-result.txt
similarity index 100%
rename from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
rename to Tests/RunCMake/list/SORT-BadCaseOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-BadCaseOption-stderr.txt b/Tests/RunCMake/list/SORT-BadCaseOption-stderr.txt
new file mode 100644
index 0000000..87dd502
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-BadCaseOption-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-BadCaseOption.cmake:1 \(list\):
+  list sub-command SORT value "BAD_CASE_OPTION" for option "CASE" is invalid.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-BadCaseOption.cmake b/Tests/RunCMake/list/SORT-BadCaseOption.cmake
new file mode 100644
index 0000000..ac5c102
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-BadCaseOption.cmake
@@ -0,0 +1 @@
+list(SORT mylist CASE BAD_CASE_OPTION)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-BadCompareOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-BadCompareOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-BadCompareOption-stderr.txt b/Tests/RunCMake/list/SORT-BadCompareOption-stderr.txt
new file mode 100644
index 0000000..51b4de2
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-BadCompareOption-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at SORT-BadCompareOption.cmake:1 \(list\):
+  list sub-command SORT value "BAD_COMPARE_OPTION" for option "COMPARE" is
+  invalid.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-BadCompareOption.cmake b/Tests/RunCMake/list/SORT-BadCompareOption.cmake
new file mode 100644
index 0000000..d5c632e
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-BadCompareOption.cmake
@@ -0,0 +1 @@
+list(SORT mylist COMPARE BAD_COMPARE_OPTION)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-BadOrderOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-BadOrderOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-BadOrderOption-stderr.txt b/Tests/RunCMake/list/SORT-BadOrderOption-stderr.txt
new file mode 100644
index 0000000..7984e5c
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-BadOrderOption-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at SORT-BadOrderOption.cmake:1 \(list\):
+  list sub-command SORT value "BAD_ODER_OPTION" for option "ORDER" is
+  invalid.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-BadOrderOption.cmake b/Tests/RunCMake/list/SORT-BadOrderOption.cmake
new file mode 100644
index 0000000..e232197
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-BadOrderOption.cmake
@@ -0,0 +1 @@
+list(SORT mylist ORDER BAD_ODER_OPTION)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-DuplicateCaseOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-DuplicateCaseOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-DuplicateCaseOption-stderr.txt b/Tests/RunCMake/list/SORT-DuplicateCaseOption-stderr.txt
new file mode 100644
index 0000000..b893f50
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-DuplicateCaseOption-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-DuplicateCaseOption.cmake:2 \(list\):
+  list sub-command SORT option "CASE" has been specified multiple times.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-DuplicateCaseOption.cmake b/Tests/RunCMake/list/SORT-DuplicateCaseOption.cmake
new file mode 100644
index 0000000..ba52b24
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-DuplicateCaseOption.cmake
@@ -0,0 +1,2 @@
+set (mylist a b c)
+list(SORT mylist CASE INSENSITIVE CASE INSENSITIVE )
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-DuplicateCompareOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-DuplicateCompareOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-DuplicateCompareOption-stderr.txt b/Tests/RunCMake/list/SORT-DuplicateCompareOption-stderr.txt
new file mode 100644
index 0000000..83624be
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-DuplicateCompareOption-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-DuplicateCompareOption.cmake:2 \(list\):
+  list sub-command SORT option "COMPARE" has been specified multiple times.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-DuplicateCompareOption.cmake b/Tests/RunCMake/list/SORT-DuplicateCompareOption.cmake
new file mode 100644
index 0000000..fd2e31d
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-DuplicateCompareOption.cmake
@@ -0,0 +1,2 @@
+set (mylist a b c)
+list(SORT mylist COMPARE STRING COMPARE STRING)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-DuplicateOrderOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-DuplicateOrderOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-DuplicateOrderOption-stderr.txt b/Tests/RunCMake/list/SORT-DuplicateOrderOption-stderr.txt
new file mode 100644
index 0000000..9e95178
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-DuplicateOrderOption-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-DuplicateOrderOption.cmake:2 \(list\):
+  list sub-command SORT option "ORDER" has been specified multiple times.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-DuplicateOrderOption.cmake b/Tests/RunCMake/list/SORT-DuplicateOrderOption.cmake
new file mode 100644
index 0000000..26d9c7d
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-DuplicateOrderOption.cmake
@@ -0,0 +1,2 @@
+set (mylist a b c)
+list(SORT mylist ORDER ASCENDING ORDER ASCENDING)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-NoCaseOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-NoCaseOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-NoCaseOption-stderr.txt b/Tests/RunCMake/list/SORT-NoCaseOption-stderr.txt
new file mode 100644
index 0000000..5c63e77
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-NoCaseOption-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-NoCaseOption.cmake:1 \(list\):
+  list sub-command SORT missing argument for option "CASE".
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-NoCaseOption.cmake b/Tests/RunCMake/list/SORT-NoCaseOption.cmake
new file mode 100644
index 0000000..57cc429
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-NoCaseOption.cmake
@@ -0,0 +1 @@
+list(SORT mylist CASE)
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt b/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt
deleted file mode 100644
index d3fad60..0000000
--- a/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-^CMake Error at SORT-TooManyArguments.cmake:1 \(list\):
-  list sub-command SORT only takes one argument.
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/list/SORT-WrongOption-result.txt
similarity index 100%
copy from Tests/RunCMake/list/SORT-TooManyArguments-result.txt
copy to Tests/RunCMake/list/SORT-WrongOption-result.txt
diff --git a/Tests/RunCMake/list/SORT-WrongOption-stderr.txt b/Tests/RunCMake/list/SORT-WrongOption-stderr.txt
new file mode 100644
index 0000000..597cb29
--- /dev/null
+++ b/Tests/RunCMake/list/SORT-WrongOption-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SORT-WrongOption.cmake:1 \(list\):
+  list sub-command SORT option "one_too_many" is unknown.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/list/SORT-TooManyArguments.cmake b/Tests/RunCMake/list/SORT-WrongOption.cmake
similarity index 100%
rename from Tests/RunCMake/list/SORT-TooManyArguments.cmake
rename to Tests/RunCMake/list/SORT-WrongOption.cmake
diff --git a/Tests/RunCMake/list/SORT.cmake b/Tests/RunCMake/list/SORT.cmake
new file mode 100644
index 0000000..4a9e064
--- /dev/null
+++ b/Tests/RunCMake/list/SORT.cmake
@@ -0,0 +1,114 @@
+set(source_unsorted
+        c/B.h
+        a/c.h
+        B/a.h
+        )
+
+## Test with default options
+set(expected
+        B/a.h
+        a/c.h
+        c/B.h
+        )
+set(list ${source_unsorted})
+list(SORT list)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE STRING)")
+endif ()
+
+
+## Test CASE INSENSITIVE ORDER ASCENDING COMPARE STRING
+set(expected
+        a/c.h
+        B/a.h
+        c/B.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE STRING)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE STRING)")
+endif ()
+
+## Test CASE INSENSITIVE ORDER DESCENDING COMPARE STRING
+set(expected
+        c/B.h
+        B/a.h
+        a/c.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE STRING)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE STRING)")
+endif ()
+
+## Test CASE SENSITIVE ORDER ASCENDING COMPARE STRING
+set(expected
+        B/a.h
+        a/c.h
+        c/B.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE STRING)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE STRING)")
+endif ()
+
+## Test CASE SENSITIVE ORDER DESCENDING COMPARE STRING
+set(expected
+        c/B.h
+        a/c.h
+        B/a.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE STRING)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE STRING)")
+endif ()
+
+## Test CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME
+set(expected
+        B/a.h
+        c/B.h
+        a/c.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)")
+endif ()
+
+## Test CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME
+set(expected
+        a/c.h
+        c/B.h
+        B/a.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)")
+endif ()
+
+## Test CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME
+set(expected
+        c/B.h
+        B/a.h
+        a/c.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)")
+endif ()
+
+## Test CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME
+set(expected
+        a/c.h
+        B/a.h
+        c/B.h
+        )
+set(list ${source_unsorted})
+list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)
+if (NOT expected STREQUAL list)
+    message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)")
+endif ()
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index cc29b77..4c3d901 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -88,3 +88,14 @@
   --build-options ${build_options}
   --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
   )
+
+
+add_test(NAME UseSWIG.UseTargetINCLUDE_DIRECTORIES COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES"
+  "${CMake_BINARY_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES"
+  ${build_generator_args}
+  --build-project TestModuleVersion2
+  --build-options ${build_options}
+  )
diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
new file mode 100644
index 0000000..3e266c3
--- /dev/null
+++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestUseTargetINCLUDE_DIRECTORIES CXX)
+
+include(CTest)
+
+find_package(SWIG REQUIRED)
+include(${SWIG_USE_FILE})
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
+
+unset(CMAKE_SWIG_FLAGS)
+
+set_property(SOURCE "example.i" PROPERTY CPLUSPLUS ON)
+set_property(SOURCE "example.i" PROPERTY COMPILE_OPTIONS -includeall)
+
+swig_add_library(example1
+                 LANGUAGE python
+                 OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/example1"
+                 SOURCES example.i ../example.cxx)
+set_target_properties (example1 PROPERTIES
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.."
+  SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE
+  OUTPUT_NAME example1
+  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
+  ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1"
+  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1")
+target_link_libraries(example1 PRIVATE Python3::Python)
+
+
+# Check that source property override target property
+set_property(SOURCE "example.i" PROPERTY USE_TARGET_INCLUDE_DIRECTORIES TRUE)
+
+swig_add_library(example2
+                 LANGUAGE python
+                 OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/example2"
+                 SOURCES example.i ../example.cxx)
+set_target_properties (example2 PROPERTIES
+  INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.."
+  SWIG_USE_TARGET_INCLUDE_DIRECTORIES FALSE
+  OUTPUT_NAME example2
+  LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2"
+  ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2"
+  RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2")
+target_link_libraries(example2 PRIVATE Python3::Python)
diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i
new file mode 100644
index 0000000..fbdf724
--- /dev/null
+++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i
@@ -0,0 +1,9 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"