Selaa lähdekoodia

string: Tolerate SUBSTRING length exceeding end index

string SUBSTRING command now ignores length if it points
past end of string and uses end of string instead.
String SUBSTRING tests now cover more corner cases.
Domen Vrankar 11 vuotta sitten
vanhempi
sitoutus
474bbb9dbc

+ 6 - 1
Help/command/string.rst

@@ -73,8 +73,13 @@ TOUPPER/TOLOWER will convert string to upper/lower characters.
 
 LENGTH will return a given string's length.
 
-SUBSTRING will return a substring of a given string.  If length is -1
+SUBSTRING will return a substring of a given string. If length is -1
 the remainder of the string starting at begin will be returned.
+If string is shorter than length then end of string is used instead.
+
+.. note::
+  CMake 3.1 and below reported an error if length pointed past
+  the end of string.
 
 STRIP will return a substring of a given string with leading and
 trailing spaces removed.

+ 2 - 4
Source/cmStringCommand.cxx

@@ -711,12 +711,10 @@ bool cmStringCommand::HandleSubstringCommand(std::vector<std::string> const&
     this->SetError(ostr.str());
     return false;
     }
-  int leftOverLength = intStringLength - begin;
-  if ( end < -1 || end > leftOverLength )
+  if ( end < -1 )
     {
     cmOStringStream ostr;
-    ostr << "end index: " << end << " is out of range -1 - "
-         << leftOverLength;
+    ostr << "end index: " << end << " should be -1 or greater";
     this->SetError(ostr.str());
     return false;
     }

+ 2 - 2
Tests/CMakeTests/StringTest.cmake.in

@@ -63,7 +63,7 @@ check_cmake_test(String
 # Execute each test listed in StringTestScript.cmake:
 #
 set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake")
-set(number_of_tests_expected 69)
+set(number_of_tests_expected 70)
 
 include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
 execute_all_script_tests(${scriptname} number_of_tests_executed)
@@ -75,6 +75,6 @@ message(STATUS "scriptname='${scriptname}'")
 message(STATUS "number_of_tests_executed='${number_of_tests_executed}'")
 message(STATUS "number_of_tests_expected='${number_of_tests_expected}'")
 
-if(number_of_tests_executed LESS number_of_tests_expected)
+if(NOT number_of_tests_executed EQUAL number_of_tests_expected)
   message(FATAL_ERROR "error: some test cases were skipped")
 endif()

+ 7 - 4
Tests/CMakeTests/StringTestScript.cmake

@@ -122,14 +122,17 @@ elseif(testname STREQUAL substring_not_enough_args) # fail
 elseif(testname STREQUAL substring_begin_too_large) # fail
   string(SUBSTRING "abcdefg" 25 100 v)
 
-elseif(testname STREQUAL substring_end_too_large) # fail
+elseif(testname STREQUAL substring_end_larger_than_strlen) # pass
   string(SUBSTRING "abcdefg" 1 100 v)
 
 elseif(testname STREQUAL substring_begin_less_than_zero) # fail
-  string(SUBSTRING "abcdefg" -2 4 v)
+  string(SUBSTRING "abcdefg" -1 4 v)
 
-elseif(testname STREQUAL substring_end_less_than_begin) # fail
-  string(SUBSTRING "abcdefg" 6 3 v)
+elseif(testname STREQUAL substring_end_less_than_zero) # pass
+  string(SUBSTRING "abcdefg" 0 -1 v)
+
+elseif(testname STREQUAL substring_end_less_than_begin) # pass
+  string(SUBSTRING "abcdefg" 6 0 v)
 
 elseif(testname STREQUAL length_not_enough_args) # fail
   string(LENGTH)