diff --git a/SystemTools.cxx b/SystemTools.cxx index b7e0960034..f18f67ebc4 100644 --- a/SystemTools.cxx +++ b/SystemTools.cxx @@ -2728,6 +2728,22 @@ int SystemTools::Strucmp(char const* l, char const* r) return lc - rc; } +int SystemTools::Strnucmp(char const* l, char const* r, size_t n) +{ + int lc; + int rc; + size_t count = 0; + do { + lc = kwsysString_tolower(*l++); + rc = kwsysString_tolower(*r++); + count++; + if (count >= n) { + return lc - rc; + } + } while (lc == rc && lc); + return lc - rc; +} + // return file's modified time long int SystemTools::ModifiedTime(std::string const& filename) { diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in index 12b37406a2..330846f320 100644 --- a/SystemTools.hxx.in +++ b/SystemTools.hxx.in @@ -198,10 +198,17 @@ public: char separator = '/', bool isPath = false); /** - * Perform a case-independent string comparison + * Perform a case-independent string comparison. + * Similar to POSIX's strcasecmp. */ static int Strucmp(char const* s1, char const* s2); + /** + * Perform a case-independent string comparison, but compares at most n + * characters. Similar to POSIX's strncasecmp. + */ + static int Strnucmp(char const* s1, char const* s2, size_t n); + /** * Split a string on its newlines into multiple lines * Return false only if the last line stored had no newline diff --git a/testSystemTools.cxx b/testSystemTools.cxx index e48525de43..6e0958202d 100644 --- a/testSystemTools.cxx +++ b/testSystemTools.cxx @@ -1317,6 +1317,43 @@ static bool CheckSplitString() return ret; } +static bool CheckStringComparisons() +{ + if (!(kwsys::SystemTools::Strucmp("", "") == 0)) + return false; + if (!(kwsys::SystemTools::Strucmp("bob", "bob") == 0)) + return false; + if (!(kwsys::SystemTools::Strucmp("bob", "BOB") == 0)) + return false; + if (!(kwsys::SystemTools::Strucmp("bob1", "BoB2") < 0)) + return false; + if (!(kwsys::SystemTools::Strucmp("bOb4", "Bob3") > 0)) + return false; + if (!(kwsys::SystemTools::Strucmp("aaa", "aaaaaaaaa") < 0)) + return false; + if (!(kwsys::SystemTools::Strucmp("aaaaaaaaa", "aaa") > 1)) + return false; + + if (!(kwsys::SystemTools::Strnucmp("", "", 0) == 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("", "", 3000) == 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("bob", "Bobby", 3) == 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("Bob", "boBBy", 3) == 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("bob", "Bobby", 3000) < 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("bobbY", "BOB", 3000) > 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("bobb", "Bobby", 5) < 0)) + return false; + if (!(kwsys::SystemTools::Strnucmp("bobbY", "BOBb", 5) > 0)) + return false; + + return true; +} + int testSystemTools(int, char*[]) { bool res = true; @@ -1370,5 +1407,7 @@ int testSystemTools(int, char*[]) res &= CheckSplitString(); + res &= CheckStringComparisons(); + return res ? 0 : 1; }