#include "StrFmt.h" #include "BEType.h" #include "StrUtil.h" #include "Macro.h" #include "cfmt.h" #include void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%p", reinterpret_cast(static_cast(arg))); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%p", reinterpret_cast(static_cast(arg))); } void fmt_class_string::format(std::string& out, u64 arg) { out += reinterpret_cast(static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { out += get_object(arg).c_str(); // TODO? } template<> void fmt_class_string>::format(std::string& out, u64 arg) { const std::vector& obj = get_object(arg); out.append(obj.cbegin(), obj.cend()); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#hhx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#hhx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#hhx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#hx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#hx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#x", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#x", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#lx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#lx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#llx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%#llx", static_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%gf", static_cast(reinterpret_cast(arg))); } template<> void fmt_class_string::format(std::string& out, u64 arg) { fmt::append(out, "%g", reinterpret_cast(arg)); } template<> void fmt_class_string::format(std::string& out, u64 arg) { out += arg ? "true" : "false"; } template<> void fmt_class_string::format(std::string& out, u64 arg) { const v128& vec = get_object(arg); fmt::append(out, "0x%016llx%016llx", vec._u64[1], vec._u64[0]); } namespace fmt { struct cfmt_src; } // Temporary implementation struct fmt::cfmt_src { const fmt_type_info* sup; const u64* args; bool test(std::size_t index) const { if (!sup[index].fmt_string) { return false; } return true; } template T get(std::size_t index) const { return reinterpret_cast(args[index]); } void skip(std::size_t extra) { ++sup += extra; ++args += extra; } std::size_t fmt_string(std::string& out, std::size_t extra) const { const std::size_t start = out.size(); sup[extra].fmt_string(out, args[extra]); return out.size() - start; } // Returns type size (0 if unknown, pointer, unsigned, assumed max) std::size_t type(std::size_t extra) const { // Hack: use known function pointers to determine type #define TYPE(type)\ if (sup[extra].fmt_string == &fmt_class_string::format) return sizeof(type); TYPE(int); TYPE(llong); TYPE(schar); TYPE(short); if (std::is_signed::value) TYPE(char); TYPE(long); #undef TYPE return 0; } }; void fmt::raw_append(std::string& out, const char* fmt, const fmt_type_info* sup, const u64* args) noexcept { cfmt_append(out, fmt, cfmt_src{sup, args}); } char* fmt::alloc_format(const char* fmt, const fmt_type_info* sup, const u64* args) noexcept { std::string str; raw_append(str, fmt, sup, args); return static_cast(std::memcpy(std::malloc(str.size() + 1), str.data(), str.size() + 1)); } std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to) { auto pos = src.find(from); if (pos == std::string::npos) { return src; } return (pos ? src.substr(0, pos) + to : to) + std::string(src.c_str() + pos + from.length()); } std::string fmt::replace_all(const std::string &src, const std::string& from, const std::string& to) { std::string target = src; for (auto pos = target.find(from); pos != std::string::npos; pos = target.find(from, pos + 1)) { target = (pos ? target.substr(0, pos) + to : to) + std::string(target.c_str() + pos + from.length()); pos += to.length(); } return target; } std::vector fmt::split(const std::string& source, std::initializer_list separators, bool is_skip_empty) { std::vector result; size_t cursor_begin = 0; for (size_t cursor_end = 0; cursor_end < source.length(); ++cursor_end) { for (auto &separator : separators) { if (strncmp(source.c_str() + cursor_end, separator.c_str(), separator.length()) == 0) { std::string candidate = source.substr(cursor_begin, cursor_end - cursor_begin); if (!is_skip_empty || !candidate.empty()) result.push_back(candidate); cursor_begin = cursor_end + separator.length(); cursor_end = cursor_begin - 1; break; } } } if (cursor_begin != source.length()) { result.push_back(source.substr(cursor_begin)); } return std::move(result); } std::string fmt::trim(const std::string& source, const std::string& values) { std::size_t begin = source.find_first_not_of(values); if (begin == source.npos) return{}; return source.substr(begin, source.find_last_not_of(values) + 1); } std::string fmt::to_upper(const std::string& string) { std::string result; result.resize(string.size()); std::transform(string.begin(), string.end(), result.begin(), ::toupper); return result; } bool fmt::match(const std::string &source, const std::string &mask) { std::size_t source_position = 0, mask_position = 0; for (; source_position < source.size() && mask_position < mask.size(); ++mask_position, ++source_position) { switch (mask[mask_position]) { case '?': break; case '*': for (std::size_t test_source_position = source_position; test_source_position < source.size(); ++test_source_position) { if (match(source.substr(test_source_position), mask.substr(mask_position + 1))) { return true; } } return false; default: if (source[source_position] != mask[mask_position]) { return false; } break; } } if (source_position != source.size()) return false; if (mask_position != mask.size()) return false; return true; }