2017-01-28 04:49:09 +08:00
|
|
|
#include "pch.h"
|
2016-09-19 11:50:08 +08:00
|
|
|
#include "vcpkg_Strings.h"
|
2017-04-13 13:39:14 +08:00
|
|
|
#include "vcpkg_Util.h"
|
2016-09-19 11:50:08 +08:00
|
|
|
|
2017-01-06 04:47:08 +08:00
|
|
|
namespace vcpkg::Strings::details
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2016-12-17 08:02:19 +08:00
|
|
|
// To disambiguate between two overloads
|
2016-12-16 09:09:14 +08:00
|
|
|
static const auto isspace = [](const char c)
|
|
|
|
{
|
|
|
|
return std::isspace(c);
|
|
|
|
};
|
|
|
|
|
2017-02-16 12:44:19 +08:00
|
|
|
// Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower()
|
2017-02-16 12:41:03 +08:00
|
|
|
static char tolower_char(const char c)
|
|
|
|
{
|
|
|
|
return static_cast<char>(std::tolower(c));
|
|
|
|
}
|
|
|
|
|
2017-03-04 22:10:59 +08:00
|
|
|
static _locale_t& c_locale()
|
|
|
|
{
|
|
|
|
static _locale_t c_locale_impl = _create_locale(LC_ALL, "C");
|
|
|
|
return c_locale_impl;
|
|
|
|
}
|
|
|
|
|
2016-09-19 11:50:08 +08:00
|
|
|
std::string format_internal(const char* fmtstr, ...)
|
|
|
|
{
|
|
|
|
va_list lst;
|
|
|
|
va_start(lst, fmtstr);
|
|
|
|
|
2017-03-04 22:10:59 +08:00
|
|
|
const int sz = _vscprintf_l(fmtstr, c_locale(), lst);
|
2016-09-19 11:50:08 +08:00
|
|
|
std::string output(sz, '\0');
|
2017-03-04 22:10:59 +08:00
|
|
|
_vsnprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst);
|
2016-09-19 11:50:08 +08:00
|
|
|
va_end(lst);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2016-09-30 10:25:07 +08:00
|
|
|
std::wstring wformat_internal(const wchar_t* fmtstr, ...)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
va_list lst;
|
|
|
|
va_start(lst, fmtstr);
|
|
|
|
|
2017-03-04 22:10:59 +08:00
|
|
|
const int sz = _vscwprintf_l(fmtstr, c_locale(), lst);
|
2016-09-19 11:50:08 +08:00
|
|
|
std::wstring output(sz, '\0');
|
2017-03-04 22:10:59 +08:00
|
|
|
_vsnwprintf_s_l(&output[0], output.size() + 1, output.size() + 1, fmtstr, c_locale(), lst);
|
2016-09-19 11:50:08 +08:00
|
|
|
va_end(lst);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
2017-01-06 04:47:08 +08:00
|
|
|
}
|
2016-09-19 11:50:08 +08:00
|
|
|
|
2017-01-06 04:47:08 +08:00
|
|
|
namespace vcpkg::Strings
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2017-04-04 05:21:51 +08:00
|
|
|
std::wstring utf8_to_utf16(const CStringView s)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
|
|
|
|
return conversion.from_bytes(s);
|
|
|
|
}
|
|
|
|
|
2017-04-04 05:21:51 +08:00
|
|
|
std::string utf16_to_utf8(const CWStringView w)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
|
|
|
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
|
|
|
|
return conversion.to_bytes(w);
|
|
|
|
}
|
|
|
|
|
2016-10-05 06:23:44 +08:00
|
|
|
std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2017-02-17 05:02:30 +08:00
|
|
|
const std::string pattern_as_lower_case(ascii_to_lowercase(pattern));
|
2016-10-05 05:44:19 +08:00
|
|
|
return search(s.begin(), s.end(), pattern_as_lower_case.begin(), pattern_as_lower_case.end(), [](const char a, const char b)
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2017-02-16 12:41:03 +08:00
|
|
|
return details::tolower_char(a) == b;
|
2016-09-19 11:50:08 +08:00
|
|
|
});
|
|
|
|
}
|
2016-10-05 05:44:19 +08:00
|
|
|
|
|
|
|
std::string ascii_to_lowercase(const std::string& input)
|
|
|
|
{
|
2017-02-16 12:41:03 +08:00
|
|
|
std::string output(input);
|
|
|
|
std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char);
|
2016-10-05 05:44:19 +08:00
|
|
|
return output;
|
|
|
|
}
|
2016-11-03 10:34:30 +08:00
|
|
|
|
2016-12-16 09:09:14 +08:00
|
|
|
void trim(std::string* s)
|
|
|
|
{
|
|
|
|
s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end());
|
2016-12-21 06:45:35 +08:00
|
|
|
s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace));
|
2016-12-16 09:09:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string trimmed(const std::string& s)
|
|
|
|
{
|
|
|
|
auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base();
|
2016-12-21 06:45:35 +08:00
|
|
|
auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace);
|
|
|
|
return std::string(whitespace_front, whitespace_back);
|
2016-12-16 09:09:14 +08:00
|
|
|
}
|
2016-12-17 08:02:19 +08:00
|
|
|
|
|
|
|
void trim_all_and_remove_whitespace_strings(std::vector<std::string>* strings)
|
|
|
|
{
|
2016-12-17 09:48:37 +08:00
|
|
|
for (std::string& s : *strings)
|
|
|
|
{
|
|
|
|
trim(&s);
|
|
|
|
}
|
|
|
|
|
2017-04-13 13:39:14 +08:00
|
|
|
Util::keep_if(*strings, [](const std::string& s)-> bool
|
|
|
|
{
|
|
|
|
return s != "";
|
|
|
|
});
|
2016-12-17 08:02:19 +08:00
|
|
|
}
|
2017-01-24 07:13:12 +08:00
|
|
|
|
|
|
|
std::vector<std::string> split(const std::string& s, const std::string& delimiter)
|
|
|
|
{
|
|
|
|
std::vector<std::string> output;
|
|
|
|
|
|
|
|
size_t i = 0;
|
2017-01-28 12:09:40 +08:00
|
|
|
for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos))
|
2017-01-24 07:13:12 +08:00
|
|
|
{
|
|
|
|
output.push_back(s.substr(i, pos - i));
|
|
|
|
i = ++pos;
|
2017-01-24 08:50:29 +08:00
|
|
|
}
|
2017-01-24 07:13:12 +08:00
|
|
|
|
2017-01-24 08:50:29 +08:00
|
|
|
// 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()));
|
2017-01-24 07:13:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
2017-01-06 04:47:08 +08:00
|
|
|
}
|