1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
#include "pch.h"
#include "vcpkg_Checks.h"
#include "vcpkg_Strings.h"
#include "vcpkg_Util.h"
namespace vcpkg::Strings::details
{
// To disambiguate between two overloads
static const auto isspace = [](const char c) { return std::isspace(c); };
// Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower()
static char tolower_char(const char c) { return static_cast<char>(std::tolower(c)); }
#if defined(_WIN32)
static _locale_t& c_locale()
{
static _locale_t c_locale_impl = _create_locale(LC_ALL, "C");
return c_locale_impl;
}
#endif
std::string format_internal(const char* fmtstr, ...)
{
va_list args;
va_start(args, fmtstr);
#if defined(_WIN32)
const int sz = _vscprintf_l(fmtstr, c_locale(), args);
#else
const int sz = vsnprintf(nullptr, 0, fmtstr, args);
#endif
Checks::check_exit(VCPKG_LINE_INFO, sz > 0);
std::string output(sz, '\0');
#if defined(_WIN32)
_vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args);
#else
vsnprintf(&output.at(0), output.size() + 1, fmtstr, args);
#endif
va_end(args);
return output;
}
std::wstring wformat_internal(const wchar_t* fmtstr, ...)
{
va_list args;
va_start(args, fmtstr);
#if defined(_WIN32)
const int sz = _vscwprintf_l(fmtstr, c_locale(), args);
#else
const int sz = vswprintf(nullptr, 0, fmtstr, args);
#endif
Checks::check_exit(VCPKG_LINE_INFO, sz > 0);
std::wstring output(sz, L'\0');
#if defined(_WIN32)
_vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args);
#else
vswprintf(&output.at(0), output.size() + 1, fmtstr, args);
#endif
va_end(args);
return output;
}
}
namespace vcpkg::Strings
{
std::wstring to_utf16(const CStringView s)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
return conversion.from_bytes(s);
}
std::string to_utf8(const CWStringView w)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
return conversion.to_bytes(w);
}
std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern)
{
const std::string pattern_as_lower_case(ascii_to_lowercase(pattern));
return search(s.begin(),
s.end(),
pattern_as_lower_case.begin(),
pattern_as_lower_case.end(),
[](const char a, const char b) { return details::tolower_char(a) == b; });
}
bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern)
{
return case_insensitive_ascii_find(s, pattern) != s.end();
}
int case_insensitive_ascii_compare(const CStringView left, const CStringView right)
{
return _stricmp(left, right);
}
std::string ascii_to_lowercase(const std::string& input)
{
std::string output(input);
std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char);
return output;
}
void trim(std::string* s)
{
s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end());
s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace));
}
std::string trimmed(const std::string& s)
{
auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base();
auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace);
return std::string(whitespace_front, whitespace_back);
}
void trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings)
{
for (std::string& s : *strings)
{
trim(&s);
}
Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); });
}
std::vector<std::string> split(const std::string& s, const std::string& delimiter)
{
std::vector<std::string> output;
if(delimiter.empty()){
output.push_back(s);
return output;
}
size_t i = 0;
for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos))
{
output.push_back(s.substr(i, pos - i));
i = ++pos;
}
// Add the rest of the string after the last delimiter, unless there is nothing after it
if (i != s.length())
{
output.push_back(s.substr(i, s.length()));
}
return output;
}
}
|