Add a string(FIND) sub-command (#11795)

This commit is contained in:
Tim Hütz 2011-02-15 11:20:47 +01:00 committed by Brad King
parent 4d1240eb0a
commit 1462561a8c
4 changed files with 151 additions and 2 deletions

View File

@ -72,6 +72,10 @@ bool cmStringCommand
{ {
return this->HandleRandomCommand(args); return this->HandleRandomCommand(args);
} }
else if(subCommand == "FIND")
{
return this->HandleFindCommand(args);
}
std::string e = "does not recognize sub-command "+subCommand; std::string e = "does not recognize sub-command "+subCommand;
this->SetError(e.c_str()); this->SetError(e.c_str());
@ -498,6 +502,68 @@ void cmStringCommand::StoreMatches(cmMakefile* mf,cmsys::RegularExpression& re)
} }
} }
//----------------------------------------------------------------------------
bool cmStringCommand::HandleFindCommand(std::vector<std::string> const&
args)
{
// check if all required parameters were passed
if(args.size() < 4 || args.size() > 5)
{
this->SetError("sub-command FIND requires 3 or 4 parameters.");
return false;
}
// check if the reverse flag was set or not
bool reverseMode = false;
if(args.size() == 5 && args[4] == "REVERSE")
{
reverseMode = true;
}
// if we have 5 arguments the last one must be REVERSE
if(args.size() == 5 && args[4] != "REVERSE")
{
this->SetError("sub-command FIND: unknown last parameter");
return false;
}
// local parameter names.
const std::string& sstring = args[1];
const std::string& schar = args[2];
const std::string& outvar = args[3];
// ensure that the user cannot accidentally specify REVERSE as a variable
if(outvar == "REVERSE")
{
this->SetError("sub-command FIND does not allow to select REVERSE as "
"the output variable. "
"Maybe you missed the actual output variable?");
return false;
}
// try to find the character and return its position
size_t pos;
if(!reverseMode)
{
pos = sstring.find(schar);
}
else
{
pos = sstring.rfind(schar);
}
if(std::string::npos != pos)
{
std::stringstream s;
s << pos;
this->Makefile->AddDefinition(outvar.c_str(), s.str().c_str());
return true;
}
// the character was not found, but this is not really an error
this->Makefile->AddDefinition(outvar.c_str(), "-1");
return true;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const& bool cmStringCommand::HandleCompareCommand(std::vector<std::string> const&
args) args)

View File

@ -90,6 +90,7 @@ public:
" string(STRIP <string> <output variable>)\n" " string(STRIP <string> <output variable>)\n"
" string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n" " string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]\n"
" [RANDOM_SEED <seed>] <output variable>)\n" " [RANDOM_SEED <seed>] <output variable>)\n"
" string(FIND <string> <substring> <output variable> [REVERSE])\n"
"REGEX MATCH will match the regular expression once and store the " "REGEX MATCH will match the regular expression once and store the "
"match in the output variable.\n" "match in the output variable.\n"
"REGEX MATCHALL will match the regular expression as many times as " "REGEX MATCHALL will match the regular expression as many times as "
@ -117,6 +118,10 @@ public:
"characters and default alphabet is all numbers and upper and " "characters and default alphabet is all numbers and upper and "
"lower case letters. If an integer RANDOM_SEED is given, its " "lower case letters. If an integer RANDOM_SEED is given, its "
"value will be used to seed the random number generator.\n" "value will be used to seed the random number generator.\n"
"FIND will return the position where the given substring was found "
"in the supplied string. If the REVERSE flag was used, the command "
"will search for the position of the last occurrence of the "
"specified substring.\n"
"The following characters have special meaning in regular expressions:\n" "The following characters have special meaning in regular expressions:\n"
" ^ Matches at beginning of a line\n" " ^ Matches at beginning of a line\n"
" $ Matches at end of a line\n" " $ Matches at end of a line\n"
@ -152,6 +157,7 @@ protected:
bool HandleSubstringCommand(std::vector<std::string> const& args); bool HandleSubstringCommand(std::vector<std::string> const& args);
bool HandleStripCommand(std::vector<std::string> const& args); bool HandleStripCommand(std::vector<std::string> const& args);
bool HandleRandomCommand(std::vector<std::string> const& args); bool HandleRandomCommand(std::vector<std::string> const& args);
bool HandleFindCommand(std::vector<std::string> const& args);
class RegexReplacement class RegexReplacement
{ {

View File

@ -1,7 +1,7 @@
# Execute each test listed in StringTestScript.cmake: # Execute each test listed in StringTestScript.cmake:
# #
set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake") set(scriptname "@CMAKE_CURRENT_SOURCE_DIR@/StringTestScript.cmake")
set(number_of_tests_expected 52) set(number_of_tests_expected 69)
include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake") include("@CMAKE_CURRENT_SOURCE_DIR@/ExecuteScriptTests.cmake")
execute_all_script_tests(${scriptname} number_of_tests_executed) execute_all_script_tests(${scriptname} number_of_tests_executed)

View File

@ -194,6 +194,83 @@ elseif(testname STREQUAL random_with_various_alphabets) # pass
string(RANDOM LENGTH 78 ALPHABET "~`!@#$%^&*()_-+={}[]\\|:\\;'\",.<>/?" v) string(RANDOM LENGTH 78 ALPHABET "~`!@#$%^&*()_-+={}[]\\|:\\;'\",.<>/?" v)
message(STATUS "v='${v}'") message(STATUS "v='${v}'")
elseif(testname STREQUAL string_find_with_no_parameter) # fail
string(FIND)
elseif(testname STREQUAL string_find_with_one_parameter) # fail
string(FIND "CMake is great.")
elseif(testname STREQUAL string_find_with_two_parameters) # fail
string(FIND "CMake is great." "a")
elseif(testname STREQUAL string_find_with_three_parameters) # pass
string(FIND "CMake is great." "a" v)
message(STATUS "v='${v}'")
elseif(testname STREQUAL string_find_with_four_parameters) # fail
string(FIND "CMake is great." "a" v v2)
elseif(testname STREQUAL string_find_reverse_with_no_parameter) # fail
string(FIND REVERSE)
elseif(testname STREQUAL string_find_reverse_with_one_parameter) # fail
string(FIND "CMake is great." REVERSE)
elseif(testname STREQUAL string_find_reverse_with_two_parameters) # fail
string(FIND "CMake is great." "a" REVERSE)
elseif(testname STREQUAL string_find_reverse_with_three_parameters) # pass
string(FIND "CMake is great." "a" v REVERSE)
message(STATUS "v='${v}'")
elseif(testname STREQUAL string_find_reverse_with_four_parameters_part1) # fail
string(FIND "CMake is great." "a" v v2 REVERSE)
elseif(testname STREQUAL string_find_reverse_with_four_parameters_part2) # fail
string(FIND "CMake is great." "a" v REVERSE v2)
elseif(testname STREQUAL string_find_with_no_possible_result) # pass
string(FIND "CMake is a great application." "z" v)
message(STATUS "v='${v}'")
if(NOT(-1 EQUAL ${v}))
message(SEND_ERROR "FIND sub-command should return -1 but returned ${v}.")
endif(NOT(-1 EQUAL ${v}))
elseif(testname STREQUAL string_find_reverse_with_no_possible_result) # pass
string(FIND "CMake is a great application." "z" v REVERSE)
message(STATUS "v='${v}'")
if(NOT(-1 EQUAL ${v}))
message(SEND_ERROR "FIND REVERSE sub-command should return -1 but returned ${v}.")
endif(NOT(-1 EQUAL ${v}))
elseif(testname STREQUAL string_find_with_required_result) # pass
string(FIND "CMake is a great application." "g" v)
message(STATUS "v='${v}'")
if(NOT(11 EQUAL ${v}))
message(SEND_ERROR "FIND sub-command should return 11 but returned ${v}.")
endif(NOT(11 EQUAL ${v}))
elseif(testname STREQUAL string_find_reverse_with_required_result) # pass
string(FIND "CMake is a great application." "e" v REVERSE)
message(STATUS "v='${v}'")
if(NOT(13 EQUAL ${v}))
message(SEND_ERROR "FIND REVERSE sub-command should return 13 but returned ${v}.")
endif(NOT(13 EQUAL ${v}))
elseif(testname STREQUAL string_find_word_reverse_with_required_result) # pass
string(FIND "The command should find REVERSE in this string. Or maybe this REVERSE?!" "REVERSE" v)
message(STATUS "v='${v}'")
if(NOT(24 EQUAL ${v}))
message(SEND_ERROR "FIND sub-command should return 24 but returned ${v}.")
endif(NOT(24 EQUAL ${v}))
elseif(testname STREQUAL string_find_reverse_word_reverse_with_required_result) # pass
string(FIND "The command should find REVERSE in this string. Or maybe this REVERSE?!" "REVERSE" v REVERSE)
message(STATUS "v='${v}'")
if(NOT(62 EQUAL ${v}))
message(SEND_ERROR "FIND sub-command should return 62 but returned ${v}.")
endif(NOT(62 EQUAL ${v}))
else() # fail else() # fail
message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'") message(FATAL_ERROR "testname='${testname}' - error: no such test in '${CMAKE_CURRENT_LIST_FILE}'")