snes9x/vulkan/slang_helpers.cpp
2023-03-07 13:58:22 -06:00

130 lines
2.8 KiB
C++

#include "slang_helpers.hpp"
#include <string>
#include <vector>
#include <filesystem>
#include <cmath>
#include <cctype>
using std::string;
using std::string_view;
using std::vector;
namespace fs = std::filesystem;
int mipmap_levels_for_size(int width, int height)
{
return (int)log2(width > height ? width : height);
}
void trim(string_view &view)
{
while (view.length() > 0 && isspace((unsigned char)view.at(0)))
view.remove_prefix(1);
while (view.length() > 0 && isspace((unsigned char)view.at(view.length() - 1)))
view.remove_suffix(1);
}
string trim(const string& str)
{
string_view sv(str);
trim(sv);
return string(sv);
}
int get_significant_digits(const string_view &view)
{
auto pos = view.rfind('.');
if (pos == string_view::npos)
return 0;
return view.length() - pos - 1;
}
vector<string> split_string_quotes(const string_view &view)
{
vector<string> tokens;
size_t pos = 0;
while (pos < view.length())
{
size_t indexa = view.find_first_not_of("\t\r\n ", pos);
size_t indexb = 0;
if (indexa == string::npos)
break;
if (view.at(indexa) == '\"')
{
indexa++;
indexb = view.find_first_of('\"', indexa);
if (indexb == string::npos)
break;
}
else
{
indexb = view.find_first_of("\t\r\n ", indexa);
if (indexb == string::npos)
indexb = view.length();
}
if (indexb > indexa)
tokens.push_back(string{view.substr(indexa, indexb - indexa)});
pos = indexb + 1;
}
return tokens;
}
vector<string> split_string(const string_view &str, unsigned char delim)
{
vector<string> tokens;
size_t pos = 0;
size_t index;
while (pos < str.length())
{
index = str.find(delim, pos);
if (index == string::npos)
{
if (pos < str.length())
{
tokens.push_back(string{str.substr(pos)});
}
break;
}
else if (index > pos)
{
tokens.push_back(string{str.substr(pos, index - pos)});
}
pos = index + 1;
}
return tokens;
}
bool ends_with(const string &str, const string &ext)
{
if (ext.length() > str.length())
return false;
auto icmp = [](const unsigned char a, const unsigned char b) -> bool {
return std::tolower(a) == std::tolower(b);
};
return std::equal(ext.crbegin(), ext.crend(), str.crbegin(), icmp);
}
void canonicalize(string &filename, const string &base)
{
fs::path path(filename);
if (path.is_relative())
{
fs::path base_path(base);
base_path.remove_filename();
path = fs::weakly_canonical(base_path / path);
filename = path.string();
}
}