diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 08494b9bf5..68e122e7d9 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -159,6 +159,7 @@ if(KWSYS_USE_SystemTools) set(KWSYS_USE_FStream 1) set(KWSYS_USE_Encoding 1) set(KWSYS_USE_Status 1) + set(KWSYS_USE_String 1) endif() if(KWSYS_USE_Glob) set(KWSYS_USE_Directory 1) @@ -166,6 +167,7 @@ if(KWSYS_USE_Glob) set(KWSYS_USE_RegularExpression 1) set(KWSYS_USE_FStream 1) set(KWSYS_USE_Encoding 1) + set(KWSYS_USE_String 1) endif() if(KWSYS_USE_Process) set(KWSYS_USE_System 1) @@ -179,6 +181,7 @@ if(KWSYS_USE_SystemInformation) endif() if(KWSYS_USE_System) set(KWSYS_USE_Encoding 1) + set(KWSYS_USE_String 1) endif() if(KWSYS_USE_Directory) set(KWSYS_USE_Encoding 1) @@ -913,6 +916,7 @@ if(KWSYS_STANDALONE OR CMake_SOURCE_DIR) # C tests set(KWSYS_C_TESTS testEncode.c + testString.c ) if(KWSYS_STANDALONE) set(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c) diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx index 7bf46817ea..885a1f7c7e 100644 --- a/Source/kwsys/EncodingCXX.cxx +++ b/Source/kwsys/EncodingCXX.cxx @@ -9,12 +9,14 @@ #include "kwsysPrivate.h" #include KWSYS_HEADER(Encoding.hxx) #include KWSYS_HEADER(Encoding.h) +#include KWSYS_HEADER(String.h) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. #if 0 # include "Encoding.h.in" # include "Encoding.hxx.in" +# include "String.h" #endif #include @@ -29,7 +31,6 @@ #if defined(_WIN32) # include -# include # include #endif @@ -248,7 +249,7 @@ std::wstring Encoding::ToWindowsExtendedPath(std::wstring const& wsource) * previous size workaround. */ wfull_len = static_cast(wcslen(&wfull[0])); - if (wfull_len >= 2 && isalpha(wfull[0]) && + if (wfull_len >= 2 && kwsysString_isalpha(wfull[0]) && wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */ return L"\\\\?\\" + std::wstring(&wfull[0]); } else if (wfull_len >= 2 && wfull[0] == L'\\' && @@ -259,7 +260,7 @@ std::wstring Encoding::ToWindowsExtendedPath(std::wstring const& wsource) wfull[6] == L'C' && wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */ return std::wstring(&wfull[0]); - } else if (wfull_len >= 6 && isalpha(wfull[4]) && + } else if (wfull_len >= 6 && kwsysString_isalpha(wfull[4]) && wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */ return std::wstring(&wfull[0]); } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */ @@ -267,7 +268,7 @@ std::wstring Encoding::ToWindowsExtendedPath(std::wstring const& wsource) } } else if (wfull_len >= 4 && wfull[2] == L'.' && wfull[3] == L'\\') { /* Starts with \\.\ a device name */ - if (wfull_len >= 6 && isalpha(wfull[4]) && + if (wfull_len >= 6 && kwsysString_isalpha(wfull[4]) && wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */ return L"\\\\?\\" + std::wstring(&wfull[4]); } else if (wfull_len >= diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx index 90970ea589..3ac75f6bfb 100644 --- a/Source/kwsys/Glob.cxx +++ b/Source/kwsys/Glob.cxx @@ -8,6 +8,7 @@ #include KWSYS_HEADER(RegularExpression.hxx) #include KWSYS_HEADER(SystemTools.hxx) #include KWSYS_HEADER(Directory.hxx) +#include KWSYS_HEADER(String.h) // Work-around CMake dependency scanning limitation. This must // duplicate the above list of headers. @@ -16,6 +17,7 @@ # include "Directory.hxx.in" # include "Glob.hxx.in" # include "RegularExpression.hxx.in" +# include "String.h.in" # include "SystemTools.hxx.in" #endif @@ -23,7 +25,6 @@ #include #include -#include #include #include namespace KWSYS_NAMESPACE { @@ -162,7 +163,7 @@ std::string Glob::PatternToRegex(std::string const& pattern, // On case-insensitive systems file names are converted to lower // case before matching. if (!preserve_case) { - ch = tolower(static_cast(ch)); + ch = kwsysString_tolower(ch); } } #endif diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index 01dc039822..8c22b4e43a 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -54,7 +54,6 @@ do. #endif #include /* assert */ -#include /* isspace */ #include /* DIR, dirent */ #include /* errno */ #include /* fcntl */ diff --git a/Source/kwsys/String.c b/Source/kwsys/String.c index 7fd159b461..0ccf38d0aa 100644 --- a/Source/kwsys/String.c +++ b/Source/kwsys/String.c @@ -17,84 +17,130 @@ condition blocks the compiler from seeing the symbols defined here. # include "String.h.in" # endif -/* Select an implementation for strcasecmp. */ -# if defined(_MSC_VER) -# define KWSYS_STRING_USE_STRICMP -# include -# elif defined(__GNUC__) -# define KWSYS_STRING_USE_STRCASECMP -# include -# else -/* Table to convert upper case letters to lower case and leave all - other characters alone. */ -static char kwsysString_strcasecmp_tolower[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010', - '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021', - '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032', - '\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043', - '\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054', - '\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065', - '\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076', - '\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160', - '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171', - '\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142', - '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153', - '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164', - '\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175', - '\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206', - '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230', - '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241', - '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252', - '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263', - '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274', - '\275', '\276', '\277', '\300', '\301', '\302', '\303', '\304', '\305', - '\306', '\307', '\310', '\311', '\312', '\313', '\314', '\315', '\316', - '\317', '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', - '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340', - '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351', - '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362', - '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373', - '\374', '\375', '\376', '\377' -}; -# endif +# include -/*--------------------------------------------------------------------------*/ -int kwsysString_strcasecmp(char const* lhs, char const* rhs) +int kwsysString_isalnum(char c) { -# if defined(KWSYS_STRING_USE_STRICMP) - return _stricmp(lhs, rhs); -# elif defined(KWSYS_STRING_USE_STRCASECMP) - return strcasecmp(lhs, rhs); -# else - char const* const lower = kwsysString_strcasecmp_tolower; - unsigned char const* us1 = (unsigned char const*)lhs; - unsigned char const* us2 = (unsigned char const*)rhs; + return (kwsysString_isalpha(c) | /* bitwise-or to avoid branching. */ + kwsysString_isdigit(c)); +} + +int kwsysString_isalpha(char c) +{ + return (kwsysString_islower(c) | /* bitwise-or to avoid branching. */ + kwsysString_isupper(c)); +} + +int kwsysString_isascii(char c) +{ + unsigned char const uc = (unsigned char)c; + return (uc & 0x80) ^ 0x80; +} + +int kwsysString_isblank(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && isblank(uc); +} + +int kwsysString_iscntrl(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && iscntrl(uc); +} + +int kwsysString_isdigit(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push '0-9' to 246-255 so integer division by 246 is 1 only for them. */ + return ((uc + 246 - '0') & 0xFF) / 246; +} + +int kwsysString_isgraph(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && isgraph(uc); +} + +int kwsysString_islower(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'a-z' to 230-255 so integer division by 230 is 1 only for them. */ + return ((uc + 230 - 'a') & 0xFF) / 230; +} + +int kwsysString_isprint(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 32-126 to 161-255 so integer division by 161 is 1 only for them. */ + return ((uc + 161 - ' ') & 0xFF) / 161; +} + +int kwsysString_ispunct(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && ispunct(uc); +} + +int kwsysString_isspace(char c) +{ + unsigned char const uc = (unsigned char)c; + return uc < 0x80 && isspace(uc); +} + +int kwsysString_isupper(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'A-Z' to 230-255 so integer division by 230 is 1 only for them. */ + return ((uc + 230 - 'A') & 0xFF) / 230; +} + +int kwsysString_isxdigit(char c) +{ + unsigned char const uc = (unsigned char)c; + return ( + /* Push '0-9' to 246-255 so integer division by 246 is 1 only for them. */ + (((uc + 246 - '0') & 0xFF) / 246) | /* bitwise-or to avoid branching. */ + /* Push 'A-F' to 250-255 so integer division by 250 is 1 only for them. */ + (((uc + 250 - 'A') & 0xFF) / 250) | /* bitwise-or to avoid branching. */ + /* Push 'a-f' to 250-255 so integer division by 250 is 1 only for them. */ + (((uc + 250 - 'a') & 0xFF) / 250)); +} + +unsigned char kwsysString_tolower(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'A-Z' to 230-255 so integer division by 230 is 1 only for them. */ + return (unsigned char)(uc ^ ((((uc + 230 - 'A') & 0xFF) / 230) << 5)); +} + +unsigned char kwsysString_toupper(char c) +{ + unsigned char const uc = (unsigned char)c; + /* Push 'a-z' to 230-255 so integer division by 230 is 1 only for them. */ + return (unsigned char)(uc ^ ((((uc + 230 - 'a') & 0xFF) / 230) << 5)); +} + +int kwsysString_strcasecmp(char const* lhs, char const* rhs) +{ int result; - while ((result = lower[*us1] - lower[*us2++], result == 0) && *us1++) { + while ((result = kwsysString_tolower(*lhs) - kwsysString_tolower(*rhs++)) == + 0 && + *lhs++) { } return result; -# endif } -/*--------------------------------------------------------------------------*/ int kwsysString_strncasecmp(char const* lhs, char const* rhs, size_t n) { -# if defined(KWSYS_STRING_USE_STRICMP) - return _strnicmp(lhs, rhs, n); -# elif defined(KWSYS_STRING_USE_STRCASECMP) - return strncasecmp(lhs, rhs, n); -# else - char const* const lower = kwsysString_strcasecmp_tolower; - unsigned char const* us1 = (unsigned char const*)lhs; - unsigned char const* us2 = (unsigned char const*)rhs; int result = 0; - while (n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++) { + while (n && + (result = kwsysString_tolower(*lhs) - kwsysString_tolower(*rhs++)) == + 0 && + *lhs++) { --n; } return result; -# endif } #endif /* KWSYS_STRING_C */ diff --git a/Source/kwsys/String.h.in b/Source/kwsys/String.h.in index 6931051e38..abc74a6ef4 100644 --- a/Source/kwsys/String.h.in +++ b/Source/kwsys/String.h.in @@ -16,6 +16,21 @@ # define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT #endif #if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# define kwsysString_isalnum kwsys_ns(String_isalnum) +# define kwsysString_isalpha kwsys_ns(String_isalpha) +# define kwsysString_isascii kwsys_ns(String_isascii) +# define kwsysString_isblank kwsys_ns(String_isblank) +# define kwsysString_iscntrl kwsys_ns(String_iscntrl) +# define kwsysString_isdigit kwsys_ns(String_isdigit) +# define kwsysString_isgraph kwsys_ns(String_isgraph) +# define kwsysString_islower kwsys_ns(String_islower) +# define kwsysString_isprint kwsys_ns(String_isprint) +# define kwsysString_ispunct kwsys_ns(String_ispunct) +# define kwsysString_isspace kwsys_ns(String_isspace) +# define kwsysString_isupper kwsys_ns(String_isupper) +# define kwsysString_isxdigit kwsys_ns(String_isxdigit) +# define kwsysString_tolower kwsys_ns(String_tolower) +# define kwsysString_toupper kwsys_ns(String_toupper) # define kwsysString_strcasecmp kwsys_ns(String_strcasecmp) # define kwsysString_strncasecmp kwsys_ns(String_strncasecmp) #endif @@ -24,6 +39,51 @@ extern "C" { #endif +/** Locale-independent ASCII isalnum. */ +kwsysEXPORT int kwsysString_isalnum(char c); + +/** Locale-independent ASCII isalpha. */ +kwsysEXPORT int kwsysString_isalpha(char c); + +/** Locale-independent ASCII isascii. */ +kwsysEXPORT int kwsysString_isascii(char c); + +/** Locale-independent ASCII isblank. */ +kwsysEXPORT int kwsysString_isblank(char c); + +/** Locale-independent ASCII iscntrl. */ +kwsysEXPORT int kwsysString_iscntrl(char c); + +/** Locale-independent ASCII isdigit. */ +kwsysEXPORT int kwsysString_isdigit(char c); + +/** Locale-independent ASCII isgraph. */ +kwsysEXPORT int kwsysString_isgraph(char c); + +/** Locale-independent ASCII islower. */ +kwsysEXPORT int kwsysString_islower(char c); + +/** Locale-independent ASCII isprint. */ +kwsysEXPORT int kwsysString_isprint(char c); + +/** Locale-independent ASCII ispunct. */ +kwsysEXPORT int kwsysString_ispunct(char c); + +/** Locale-independent ASCII isspace. */ +kwsysEXPORT int kwsysString_isspace(char c); + +/** Locale-independent ASCII isupper. */ +kwsysEXPORT int kwsysString_isupper(char c); + +/** Locale-independent ASCII isxdigit. */ +kwsysEXPORT int kwsysString_isxdigit(char c); + +/** Locale-independent ASCII tolower. */ +kwsysEXPORT unsigned char kwsysString_tolower(char c); + +/** Locale-independent ASCII toupper. */ +kwsysEXPORT unsigned char kwsysString_toupper(char c); + /** * Compare two strings ignoring the case of the characters. The * integer returned is negative, zero, or positive if the first string @@ -49,6 +109,21 @@ kwsysEXPORT int kwsysString_strncasecmp(char const* lhs, char const* rhs, # undef kwsys_ns # undef kwsysEXPORT # if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS +# undef kwsysString_isalnum +# undef kwsysString_isalpha +# undef kwsysString_isascii +# undef kwsysString_isblank +# undef kwsysString_iscntrl +# undef kwsysString_isdigit +# undef kwsysString_isgraph +# undef kwsysString_islower +# undef kwsysString_isprint +# undef kwsysString_ispunct +# undef kwsysString_isspace +# undef kwsysString_isupper +# undef kwsysString_isxdigit +# undef kwsysString_tolower +# undef kwsysString_toupper # undef kwsysString_strcasecmp # undef kwsysString_strncasecmp # endif diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c index 11257cdb34..cb7fc2d7a9 100644 --- a/Source/kwsys/System.c +++ b/Source/kwsys/System.c @@ -1,15 +1,16 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ #include "kwsysPrivate.h" +#include KWSYS_HEADER(String.h) #include KWSYS_HEADER(System.h) /* Work-around CMake dependency scanning limitation. This must duplicate the above list of headers. */ #if 0 +# include "String.h.in" # include "System.h.in" #endif -#include /* isspace */ #include /* ptrdiff_t */ #include /* malloc, free */ #include /* memcpy */ @@ -148,7 +149,7 @@ static char** kwsysSystem__ParseUnixCommand(char const* command, int flags) in_argument = 1; } } - } else if (isspace((unsigned char)*c)) { + } else if (kwsysString_isspace(*c)) { if (in_argument) { if (in_single || in_double) { /* This space belongs to a quoted argument. */ diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 5f67f16813..0a472d324a 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -28,6 +28,7 @@ // https://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx #include "kwsysPrivate.h" +#include KWSYS_HEADER(String.h) #include KWSYS_HEADER(SystemInformation.hxx) #include KWSYS_HEADER(Process.h) @@ -35,6 +36,7 @@ // duplicate the above list of headers. #if 0 # include "Process.h.in" +# include "String.h.in" # include "SystemInformation.hxx.in" #endif @@ -165,7 +167,6 @@ using ResourceLimitType = struct rlimit; # undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP #endif -#include // int isdigit(int c); #include #include #include @@ -4167,11 +4168,11 @@ bool SystemInformationImplementation::QueryLinuxMemory() char majorChar = unameInfo.release[0]; char minorChar = unameInfo.release[2]; - if (isdigit(majorChar)) { + if (kwsysString_isdigit(majorChar)) { linuxMajor = majorChar - '0'; } - if (isdigit(minorChar)) { + if (kwsysString_isdigit(minorChar)) { linuxMinor = minorChar - '0'; } } diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 2bedcbdeb7..7e23c16a95 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -25,9 +25,9 @@ #include KWSYS_HEADER(FStream.hxx) #include KWSYS_HEADER(Encoding.h) #include KWSYS_HEADER(Encoding.hxx) +#include KWSYS_HEADER(String.h) #include -#include #include #include #include @@ -44,9 +44,11 @@ // duplicate the above list of headers. #if 0 # include "Directory.hxx.in" +# include "Encoding.h.in" # include "Encoding.hxx.in" # include "FStream.hxx.in" # include "RegularExpression.hxx.in" +# include "String.h.in" # include "SystemTools.hxx.in" #endif @@ -58,7 +60,6 @@ # pragma set woff 1375 /* base class destructor not virtual */ #endif -#include #include #include #include @@ -321,8 +322,7 @@ inline char const* Getcwd(char* buf, unsigned int len) if (nlen < len) { // make sure the drive letter is capital if (nlen > 1 && buf[1] == ':') { - buf[0] = - static_cast(toupper(static_cast(buf[0]))); + buf[0] = kwsysString_toupper(buf[0]); } return buf; } @@ -554,8 +554,7 @@ std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn) casePath = path_components[idx++]; // make sure drive letter is always upper case if (casePath.size() > 1 && casePath[1] == ':') { - casePath[0] = static_cast( - toupper(static_cast(casePath[0]))); + casePath[0] = kwsysString_toupper(casePath[0]); } char const* sep = ""; @@ -1659,11 +1658,9 @@ std::string SystemTools::Capitalized(std::string const& s) return n; } n.resize(s.size()); - n[0] = static_cast( - toupper(static_cast(s[0]))); + n[0] = static_cast(kwsysString_toupper(s[0])); for (size_t i = 1; i < s.size(); i++) { - n[i] = static_cast( - tolower(static_cast(s[i]))); + n[i] = static_cast(kwsysString_tolower(s[i])); } return n; } @@ -1673,17 +1670,9 @@ std::string SystemTools::CapitalizedWords(std::string const& s) { std::string n(s); for (size_t i = 0; i < s.size(); i++) { -#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG) - // MS has an assert that will fail if s[i] < 0; setting - // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && - (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) -#else - if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif - { - n[i] = static_cast( - toupper(static_cast(s[i]))); + if (kwsysString_isalpha(s[i]) && + (i == 0 || kwsysString_isspace(s[i - 1]))) { + n[i] = static_cast(kwsysString_toupper(s[i])); } } return n; @@ -1694,17 +1683,9 @@ std::string SystemTools::UnCapitalizedWords(std::string const& s) { std::string n(s); for (size_t i = 0; i < s.size(); i++) { -#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG) - // MS has an assert that will fail if s[i] < 0; setting - // LC_CTYPE using setlocale() does *not* help. Painful. - if ((int)s[i] >= 0 && isalpha(s[i]) && - (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1])))) -#else - if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1]))) -#endif - { - n[i] = static_cast( - tolower(static_cast(s[i]))); + if (kwsysString_isalpha(s[i]) && + (i == 0 || kwsysString_isspace(s[i - 1]))) { + n[i] = static_cast(kwsysString_tolower(s[i])); } } return n; @@ -1718,7 +1699,8 @@ std::string SystemTools::AddSpaceBetweenCapitalizedWords(std::string const& s) n.reserve(s.size()); n += s[0]; for (size_t i = 1; i < s.size(); i++) { - if (isupper(s[i]) && !isspace(s[i - 1]) && !isupper(s[i - 1])) { + if (kwsysString_isupper(s[i]) && !kwsysString_isspace(s[i - 1]) && + !kwsysString_isupper(s[i - 1])) { n += ' '; } n += s[i]; @@ -1771,15 +1753,13 @@ char* SystemTools::AppendStrings(char const* str1, char const* str2, std::string SystemTools::LowerCase(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return std::tolower(c); }); + std::transform(s.begin(), s.end(), s.begin(), kwsysString_tolower); return s; } std::string SystemTools::UpperCase(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return std::toupper(c); }); + std::transform(s.begin(), s.end(), s.begin(), kwsysString_toupper); return s; } @@ -2004,7 +1984,7 @@ int SystemTools::EstimateFormatLength(char const* format, va_list ap) if (*cur++ == '%') { // Skip "%%" since it doesn't correspond to a va_arg. if (*cur != '%') { - while (!int(isalpha(*cur))) { + while (!kwsysString_isalpha(*cur)) { ++cur; } switch (*cur) { @@ -2742,8 +2722,8 @@ int SystemTools::Strucmp(char const* l, char const* r) int lc; int rc; do { - lc = tolower(static_cast(*l++)); - rc = tolower(static_cast(*r++)); + lc = kwsysString_tolower(*l++); + rc = kwsysString_tolower(*r++); } while (lc == rc && lc); return lc - rc; } diff --git a/Source/kwsys/testString.c b/Source/kwsys/testString.c new file mode 100644 index 0000000000..b6a1e84398 --- /dev/null +++ b/Source/kwsys/testString.c @@ -0,0 +1,134 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing#kwsys for details. */ +#include "kwsysPrivate.h" +#include KWSYS_HEADER(String.h) + +/* Work-around CMake dependency scanning limitation. This must + duplicate the above list of headers. */ +#if 0 +# include "String.h.in" +#endif + +#include +#include +#include + +#ifdef _WIN32 +static int isprint_posix(int c) +{ + return isprint(c) && c != '\t'; +} +# define isprint isprint_posix +#endif + +#define MAKE_testString_(isXXXXX) \ + static int testString_##isXXXXX(void) \ + { \ + int i = 0; \ + for (; i < 128; ++i) { \ + if (!!isXXXXX(i) != !!kwsysString_##isXXXXX((char)i)) { \ + printf(#isXXXXX "(%d) failed: %d\n", i, \ + kwsysString_##isXXXXX((char)i)); \ + return 1; \ + } \ + } \ + for (; i < 256; ++i) { \ + if (kwsysString_##isXXXXX((char)i)) { \ + printf(#isXXXXX "(%d) failed: %d\n", i, \ + kwsysString_##isXXXXX((char)i)); \ + return 1; \ + } \ + } \ + return 0; \ + } \ + static int testString_##isXXXXX(void) + +MAKE_testString_(isalnum); +MAKE_testString_(isalpha); +MAKE_testString_(isascii); +MAKE_testString_(isblank); +MAKE_testString_(iscntrl); +MAKE_testString_(isdigit); +MAKE_testString_(isgraph); +MAKE_testString_(islower); +MAKE_testString_(isprint); +MAKE_testString_(ispunct); +MAKE_testString_(isspace); +MAKE_testString_(isupper); +MAKE_testString_(isxdigit); + +static int testString_tolower(void) +{ + int i = 0; + int j; + for (; i < 'A'; ++i) { + if ((j = kwsysString_tolower((char)i)) != i) { + printf("tolower(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i <= 'Z'; ++i) { + if ((j = kwsysString_tolower((char)i)) != i + 32) { + printf("tolower(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i < 256; ++i) { + if ((j = kwsysString_tolower((char)i)) != i) { + printf("tolower(%d) failed: %d\n", i, j); + return 1; + } + } + return 0; +} + +static int testString_toupper(void) +{ + int i = 0; + int j; + for (; i < 'a'; ++i) { + if ((j = kwsysString_toupper((char)i)) != i) { + printf("toupper(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i <= 'z'; ++i) { + if ((j = kwsysString_toupper((char)i)) != i - 32) { + printf("toupper(%d) failed: %d\n", i, j); + return 1; + } + } + for (; i < 256; ++i) { + if ((j = kwsysString_toupper((char)i)) != i) { + printf("toupper(%d) failed: %d\n", i, j); + return 1; + } + } + return 0; +} + +int testString(int argc, char* argv[]) +{ + int result = 0; + (void)argc; + (void)argv; + setlocale(LC_CTYPE, ""); + + result |= testString_isalnum(); + result |= testString_isalpha(); + result |= testString_isascii(); + result |= testString_isblank(); + result |= testString_iscntrl(); + result |= testString_isdigit(); + result |= testString_isgraph(); + result |= testString_islower(); + result |= testString_isprint(); + result |= testString_ispunct(); + result |= testString_isspace(); + result |= testString_isupper(); + result |= testString_isxdigit(); + result |= testString_tolower(); + result |= testString_toupper(); + + return result; +}