diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index b47c3e2f6..41d55bb5d 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -29,16 +29,13 @@ */ #include -// Types for 8-bit signed and unsigned integers -using Int8 = int8_t; -using uInt8 = uint8_t; -// Types for 16-bit signed and unsigned integers +// Types for 8/16/32/64-bit signed and unsigned integers +using Int8 = int8_t; +using uInt8 = uint8_t; using Int16 = int16_t; using uInt16 = uint16_t; -// Types for 32-bit signed and unsigned integers using Int32 = int32_t; using uInt32 = uint32_t; -// Types for 64-bit signed and unsigned integers using Int64 = int64_t; using uInt64 = uint64_t; @@ -69,104 +66,106 @@ static const string EmptyString(""); namespace BSPF { -// Defines to help with path handling -#if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX) - static const string PATH_SEPARATOR = "/"; -#elif defined(BSPF_WINDOWS) - static const string PATH_SEPARATOR = "\\"; - #pragma warning(2:4264) // no override available for virtual member function from base 'class'; function is hidden - #pragma warning(2:4265) // class has virtual functions, but destructor is not virtual - #pragma warning(2:4266) // no override available for virtual member function from base 'type'; function is hidden -#else - #error Update src/common/bspf.hxx for path separator -#endif + // Defines to help with path handling + #if defined(BSPF_UNIX) || defined(BSPF_MAC_OSX) + static const string PATH_SEPARATOR = "/"; + #elif defined(BSPF_WINDOWS) + static const string PATH_SEPARATOR = "\\"; + #pragma warning(2:4264) // no override available for virtual member function from base 'class'; function is hidden + #pragma warning(2:4265) // class has virtual functions, but destructor is not virtual + #pragma warning(2:4266) // no override available for virtual member function from base 'type'; function is hidden + #else + #error Update src/common/bspf.hxx for path separator + #endif -// CPU architecture type -// This isn't complete yet, but takes care of all the major platforms -#if defined(__i386__) || defined(_M_IX86) - static const string ARCH = "i386"; -#elif defined(__x86_64__) || defined(_WIN64) - static const string ARCH = "x86_64"; -#elif defined(__powerpc__) || defined(__ppc__) - static const string ARCH = "ppc"; -#else - static const string ARCH = "NOARCH"; -#endif + // CPU architecture type + // This isn't complete yet, but takes care of all the major platforms + #if defined(__i386__) || defined(_M_IX86) + static const string ARCH = "i386"; + #elif defined(__x86_64__) || defined(_WIN64) + static const string ARCH = "x86_64"; + #elif defined(__powerpc__) || defined(__ppc__) + static const string ARCH = "ppc"; + #else + static const string ARCH = "NOARCH"; + #endif -////////////////////////////////////////////////////////////////////// -// Some convenience functions -template inline T clamp(T a, T l, T u) { return (au) ? u : a; } - -// Compare two strings, ignoring case -inline int compareIgnoreCase(const string& s1, const string& s2) -{ -#if defined BSPF_WINDOWS && !defined __GNUG__ - return _stricmp(s1.c_str(), s2.c_str()); -#else - return strcasecmp(s1.c_str(), s2.c_str()); -#endif -} -inline int compareIgnoreCase(const char* s1, const char* s2) -{ -#if defined BSPF_WINDOWS && !defined __GNUG__ - return _stricmp(s1, s2); -#else - return strcasecmp(s1, s2); -#endif -} - -// Test whether the first string starts with the second one (case insensitive) -inline bool startsWithIgnoreCase(const string& s1, const string& s2) -{ -#if defined BSPF_WINDOWS && !defined __GNUG__ - return _strnicmp(s1.c_str(), s2.c_str(), s2.length()) == 0; -#else - return strncasecmp(s1.c_str(), s2.c_str(), s2.length()) == 0; -#endif -} -inline bool startsWithIgnoreCase(const char* s1, const char* s2) -{ -#if defined BSPF_WINDOWS && !defined __GNUG__ - return _strnicmp(s1, s2, strlen(s2)) == 0; -#else - return strncasecmp(s1, s2, strlen(s2)) == 0; -#endif -} - -// Test whether two strings are equal (case insensitive) -inline bool equalsIgnoreCase(const string& s1, const string& s2) -{ - return compareIgnoreCase(s1, s2) == 0; -} - -// Find location (if any) of the second string within the first, -// starting from 'startpos' in the first string -inline size_t findIgnoreCase(const string& s1, const string& s2, int startpos = 0) -{ - auto pos = std::search(s1.begin()+startpos, s1.end(), - s2.begin(), s2.end(), [](char ch1, char ch2) { - return toupper(uInt8(ch1)) == toupper(uInt8(ch2)); - }); - return pos == s1.end() ? string::npos : size_t(pos - (s1.begin()+startpos)); -} - -// Test whether the first string ends with the second one (case insensitive) -inline bool endsWithIgnoreCase(const string& s1, const string& s2) -{ - if(s1.length() >= s2.length()) + // Combines 'max' and 'min', and clamps value to the upper/lower value + // if it is outside the specified range + template inline T clamp(T a, T l, T u) { - const char* end = s1.c_str() + s1.length() - s2.length(); - return compareIgnoreCase(end, s2.c_str()) == 0; + return (au) ? u : a; } - return false; -} -// Test whether the first string contains the second one (case insensitive) -inline bool containsIgnoreCase(const string& s1, const string& s2) -{ - return findIgnoreCase(s1, s2) != string::npos; -} + // Compare two strings, ignoring case + inline int compareIgnoreCase(const string& s1, const string& s2) + { + #if defined BSPF_WINDOWS && !defined __GNUG__ + return _stricmp(s1.c_str(), s2.c_str()); + #else + return strcasecmp(s1.c_str(), s2.c_str()); + #endif + } + inline int compareIgnoreCase(const char* s1, const char* s2) + { + #if defined BSPF_WINDOWS && !defined __GNUG__ + return _stricmp(s1, s2); + #else + return strcasecmp(s1, s2); + #endif + } + // Test whether the first string starts with the second one (case insensitive) + inline bool startsWithIgnoreCase(const string& s1, const string& s2) + { + #if defined BSPF_WINDOWS && !defined __GNUG__ + return _strnicmp(s1.c_str(), s2.c_str(), s2.length()) == 0; + #else + return strncasecmp(s1.c_str(), s2.c_str(), s2.length()) == 0; + #endif + } + inline bool startsWithIgnoreCase(const char* s1, const char* s2) + { + #if defined BSPF_WINDOWS && !defined __GNUG__ + return _strnicmp(s1, s2, strlen(s2)) == 0; + #else + return strncasecmp(s1, s2, strlen(s2)) == 0; + #endif + } + + // Test whether two strings are equal (case insensitive) + inline bool equalsIgnoreCase(const string& s1, const string& s2) + { + return compareIgnoreCase(s1, s2) == 0; + } + + // Find location (if any) of the second string within the first, + // starting from 'startpos' in the first string + inline size_t findIgnoreCase(const string& s1, const string& s2, int startpos = 0) + { + auto pos = std::search(s1.begin()+startpos, s1.end(), + s2.begin(), s2.end(), [](char ch1, char ch2) { + return toupper(uInt8(ch1)) == toupper(uInt8(ch2)); + }); + return pos == s1.end() ? string::npos : size_t(pos - (s1.begin()+startpos)); + } + + // Test whether the first string ends with the second one (case insensitive) + inline bool endsWithIgnoreCase(const string& s1, const string& s2) + { + if(s1.length() >= s2.length()) + { + const char* end = s1.c_str() + s1.length() - s2.length(); + return compareIgnoreCase(end, s2.c_str()) == 0; + } + return false; + } + + // Test whether the first string contains the second one (case insensitive) + inline bool containsIgnoreCase(const string& s1, const string& s2) + { + return findIgnoreCase(s1, s2) != string::npos; + } } // namespace BSPF #endif