15 #ifndef INCG_IRIS_IUTEST_STRING_HPP_E22B02D7_E9E7_412C_B609_DC3D9C66895D_
16 #define INCG_IRIS_IUTEST_STRING_HPP_E22B02D7_E9E7_412C_B609_DC3D9C66895D_
20 #if defined(__MWERKS__)
28 #if defined(IUTEST_OS_CYGWIN) || defined(IUTEST_OS_ARM)
35 IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
41 ::std::string StringFormat(
const char* format, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 2);
42 ::std::
string StringFormat(const
char* format, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(1, 0);
47 inline int iu_mbicmp(
char l,
char r)
49 const int ul =
static_cast<int>(
static_cast<unsigned char>(toupper(l)));
50 const int ur =
static_cast<int>(
static_cast<unsigned char>(toupper(r)));
54 inline int iu_stricmp(
const char* str1,
const char* str2)
60 const int ret = iu_mbicmp(*l, *r);
68 return iu_mbicmp(*l, *r);
71 inline int iu_wcicmp(
wchar_t l,
wchar_t r)
73 const ::std::wint_t ul = towupper(l);
74 const ::std::wint_t ur = towupper(r);
78 inline int iu_wcsicmp(
const wchar_t * str1,
const wchar_t * str2)
80 const wchar_t* l = str1;
81 const wchar_t* r = str2;
84 const int ret = iu_wcicmp(*l, *r);
92 return iu_wcicmp(*l, *r);
101 inline int iu_stricmp(
const char* str1,
const char* str2)
103 #if defined(__BORLANDC__)
104 return stricmp(str1, str2);
105 #elif defined(_MSC_VER)
106 return _stricmp(str1, str2);
107 #elif defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MINGW) && !defined(__STRICT_ANSI__)
108 return _stricmp(str1, str2);
109 #elif !defined(__MWERKS__) && !defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_CYGWIN)
111 return strcasecmp(str1, str2);
113 return wrapper::iu_stricmp(str1, str2);
121 inline int iu_wcsicmp(
const wchar_t * str1,
const wchar_t * str2)
123 #if defined(_MSC_VER)
124 return _wcsicmp(str1, str2);
125 #elif defined(IUTEST_OS_LINUX) && !defined(IUTEST_OS_LINUX_ANDROID)
126 return wcscasecmp(str1, str2);
128 return wrapper::iu_wcsicmp(str1, str2);
135 int iu_vsnprintf(
char* dst,
size_t size,
const char* format, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(3, 0);
137 inline int iu_vsnprintf(
char* dst,
size_t size,
const char* format, va_list va)
139 char buffer[4096] = {0};
140 char* write_buffer = dst != NULL && size >= 4096 ? dst : buffer;
141 const int ret = vsprintf(write_buffer, format, va);
144 const size_t length =
static_cast<size_t>(ret);
145 const size_t write = (size <= length) ? size - 1 : length;
146 if( write_buffer == buffer ) {
147 strncpy(dst, buffer, write);
156 int iu_vsnprintf(
char* dst,
size_t size,
const char* format, va_list va) IUTEST_ATTRIBUTE_FORMAT_PRINTF(3, 0);
157 int iu_snprintf(
char* dst,
size_t size,
const char* format, ...) IUTEST_ATTRIBUTE_FORMAT_PRINTF(3, 4);
163 inline
int iu_vsnprintf(
char* dst,
size_t size, const
char* format, va_list va)
165 if( dst == NULL && size > 0 )
169 #if defined(_MSC_VER)
170 if( dst == NULL || size <= 0 )
172 return _vscprintf(format, va);
174 # if IUTEST_HAS_WANT_SECURE_LIB
175 return _vsnprintf_s(dst, size, _TRUNCATE, format, va);
177 return _vsnprintf(dst, size, format, va);
179 #elif defined(__CYGWIN__) \
180 && (defined(__STRICT_ANSI__) && (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) && (__cplusplus >= 201103L))
181 return wrapper::iu_vsnprintf(dst, size, format, va);
182 #elif (defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)) && defined(__STRICT_ANSI__)
183 return wrapper::iu_vsnprintf(dst, size, format, va);
185 return vsnprintf(dst, size, format, va);
193 inline int iu_snprintf(
char* dst,
size_t size,
const char* format, ...)
196 va_start(va, format);
197 const int ret = iu_vsnprintf(dst, size, format, va);
202 IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
204 inline
bool IsEmpty(const
char* p) {
return p == NULL || *p ==
'\0'; }
206 inline const char* NullableString(
const char* str) {
return str == NULL ?
"" : str; }
209 return p == NULL ? NULL : (IsSpace(*p) ? SkipSpace(++p) : p);
213 return (p == NULL || *p ==
'\0') ? NULL : ((*p ==
',') ? p : FindComma(++p));
215 inline bool IsStringEqual(
const char* str1,
const char* str2) {
return strcmp(str1, str2) == 0; }
216 inline bool IsStringEqual(const ::std::string& str1,
const char* str2) {
return str1.compare(str2) == 0; }
217 inline bool IsStringEqual(const ::std::string& str1, const ::std::string& str2) {
return str1.compare(str2) == 0; }
218 inline bool IsStringCaseEqual(
const char* str1,
const char* str2) {
return iu_stricmp(str1, str2) == 0; }
219 inline bool IsStringCaseEqual(const ::std::string& str1,
const char* str2) {
return iu_stricmp(str1.c_str(), str2) == 0; }
220 inline bool IsStringCaseEqual(const ::std::string& str1, const ::std::string& str2) {
return iu_stricmp(str1.c_str(), str2.c_str()) == 0; }
221 inline bool IsStringForwardMatching(
const char* str1,
const char* str2) {
return strstr(str1, str2) == str1; }
222 inline bool IsStringForwardMatching(const ::std::string& str1,
const char* str2) {
return str1.find(str2) == 0; }
223 inline bool IsStringForwardMatching(const ::std::string& str1,
const std::string& str2) {
return str1.find(str2) == 0; }
224 inline bool IsStringContains(
const char* str1,
const char* str2) {
return strstr(str1, str2) != NULL; }
225 inline bool IsStringContains(const ::std::string& str1,
const char* str2) {
return str1.find(str2) != ::std::string::npos; }
226 inline bool IsStringContains(const ::std::string& str1, const ::std::string& str2) {
return str1.find(str2) != ::std::string::npos; }
228 inline void StringReplace(::std::string& str,
const char* from,
size_t n,
const char* to)
230 ::std::string::size_type pos = 0;
231 while(
static_cast<void>(pos = str.find(from, pos)), pos != ::std::string::npos )
233 str.replace(pos, n, to);
237 inline void StringReplace(::std::string& str,
char a,
const char* to)
240 return StringReplace(str, s, 1, to);
242 inline ::std::string StripLeadingSpace(const ::std::string& str)
244 ::std::string::const_iterator it = str.begin();
245 while( it != str.end() && IsSpace(*it) )
249 return ::std::string(it, str.end());
251 inline ::std::string StripTrailingSpace(const ::std::string& str)
253 ::std::string::const_iterator it = str.end()-1;
254 while(it != str.begin() && IsSpace(*it))
258 return ::std::string(str.begin(), it+1);
260 inline ::std::string StripSpace(const ::std::string& str)
262 ::std::string::const_iterator start = str.begin();
263 while( start != str.end() && IsSpace(*start) )
267 ::std::string::const_iterator end = str.end()-1;
268 while( end != str.begin() && IsSpace(*end) )
272 return ::std::string(start, end+1);
275 inline bool StringIsBlank(const ::std::string& str)
277 ::std::string::const_iterator it = str.begin();
278 while( it != str.end() )
281 if( !IsSpace(ch) && ch !=
'\r' && ch !=
'\n' )
290 inline void StringReplaceToLF(::std::string& str)
292 StringReplace(str,
"\r\n", 2,
"\n");
293 StringReplace(str,
"\r" , 1,
"\n");
295 inline ::std::string StringRemoveComment(const ::std::string& str)
298 ::std::string::size_type prev = 0;
299 ::std::string::size_type pos = str.find(
'\n', 0);
300 while( pos != ::std::string::npos )
303 if( str[prev] !=
'#' ) {
304 r += str.substr(prev, pos-prev);
307 pos = str.find(
'\n', pos);
309 if( str[prev] !=
'#' ) {
310 r += str.substr(prev);
315 inline void StringSplit(const ::std::string& str,
char delimiter, ::std::vector< ::std::string >& dst)
317 ::std::string::size_type prev = 0;
318 ::std::string::size_type pos = 0;
319 ::std::vector< ::std::string > parsed;
320 while(
static_cast<void>(pos = str.find(delimiter, prev)), pos != ::std::string::npos)
322 parsed.push_back(str.substr(prev, pos - prev));
326 parsed.push_back(str.substr(prev));
331 inline ::std::string ToOctString(T value)
333 const size_t kB =
sizeof(T) * 8;
334 const size_t kN = (kB + 2) / 3;
335 const size_t kD = kB - (kN - 1) * 3;
336 const size_t kMask = (1u << kD) - 1u;
337 const T head = (value >> ((kN - 1) * 3)) & kMask;
338 char buf[kN + 1] = {
static_cast<char>(
'0' + (head & 0x7)), 0 };
339 for(
size_t i = 1; i < kN; ++i)
341 const T n = (value >> ((kN - i - 1) * 3));
342 buf[i] =
static_cast<char>(
'0' + (n & 0x7));
350 return static_cast<char>((n&0xF) >= 0xA ?
'A'+((n&0xF)-0xA) :
'0'+(n&0xF));
354 inline ::std::string ToHexString(T value)
356 const size_t kN =
sizeof(T)*2;
357 char buf[kN + 1] = {0};
358 for(
size_t i=0; i < kN; ++i )
360 buf[i] = ToHex(
static_cast<unsigned int>((value>>((kN-i-1)*4))));
367 inline ::std::string ToHexString(
const T* str,
int length)
370 for(
int i=0; (length < 0 || i < length) && *str != 0; ++str, ++i)
372 r += ToHexString(*str);
377 inline ::std::string FormatIntWidth2(
int value)
380 buf[0] =
static_cast<char>((value/10)%10 +
'0');
381 buf[1] =
static_cast<char>((value )%10 +
'0');
385 #if IUTEST_HAS_STD_TO_CHARS
388 ::std::string iu_to_string(
const T& value)
390 const size_t kN = 128;
391 char buf[kN] = { 0 };
392 const ::std::to_chars_result r = ::std::to_chars(buf, buf + kN, value);
399 #define IIUT_DECL_TOSTRING(fmt_, type_) \
400 inline ::std::string iu_to_string(type_ value) {\
401 char buf[128] = { 0 }; \
402 iu_snprintf(buf, sizeof(buf), fmt_, value); \
406 IIUT_DECL_TOSTRING(
"%d",
int)
407 IIUT_DECL_TOSTRING(
"%u",
unsigned int)
408 IIUT_DECL_TOSTRING(
"%ld",
long)
409 IIUT_DECL_TOSTRING(
"%lu",
unsigned long)
410 IIUT_DECL_TOSTRING(
"%lld",
long long)
411 IIUT_DECL_TOSTRING(
"%llu",
unsigned long long)
413 #undef IIUT_DECL_TOSTRING
417 inline ::std::string FormatSizeByte(
UInt64 value)
419 const char* suffixes[] = {
426 const size_t suffixes_length = IUTEST_PP_COUNTOF(suffixes);
428 double view_value =
static_cast<double>(value);
429 while(view_value >= 1024 && index + 1 < suffixes_length)
435 const UInt32 n =
static_cast<UInt32>(::std::floor(view_value));
436 const UInt32 f =
static_cast<UInt32>(view_value * 10.0 - n * 10.0);
437 const char* suffix = suffixes[index];
438 if(view_value - n <= 0.0)
440 return iu_to_string(n) + suffix;
444 return iu_to_string(n) +
"." + iu_to_string(f) + suffix;
448 inline ::std::string ShowStringQuoted(
const char* str)
450 ::std::string s =
"\""; s += str; s +=
"\"";
453 inline ::std::string ShowStringQuoted(const ::std::string& str)
455 ::std::string s =
"\""; s += str; s +=
"\"";
459 inline ::std::string StringFormat(
const char* format, ...)
462 va_start(va, format);
463 ::std::string str = StringFormat(format, va);
467 inline ::std::string StringFormat(
const char* format, va_list va)
469 size_t n = strlen(format) * 2 + 1;
473 const size_t ret = iu_vsnprintf(NULL, 0, format, va2);
482 char* dst =
new char[n];
485 const int written = iu_vsnprintf(dst, n, format, va2);
489 #if defined(EOVERFLOW)
490 if( errno == EOVERFLOW )
502 else if(
static_cast<size_t>(written) < n )
504 ::std::string s = ::std::string(dst,
static_cast<size_t>(written));
514 IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
519 #endif // INCG_IRIS_IUTEST_STRING_HPP_E22B02D7_E9E7_412C_B609_DC3D9C66895D_