Skip to content

Commit 5a36c57

Browse files
committed
Formatting system improved
`unveil<>` renamed to `fmt_unveil<>`, now packs args to u64 imitating va_args `bijective...` removed, `cfg::enum_entry` now uses formatting system `fmt_class_string<>` added, providing type-specific "%s" handler function Added `fmt::append`, removed `fmt::narrow` (too obscure) Utilities/cfmt.h: C-style format template function (WIP) Minor formatting fixes and cleanup
1 parent 662fce3 commit 5a36c57

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1300
-464
lines changed

Utilities/BEType.h

+5-7
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,6 @@ union alignas(16) v128
298298
_u64[0] = 0;
299299
_u64[1] = 0;
300300
}
301-
302-
std::string to_hex() const;
303-
304-
std::string to_xyzw() const;
305301
};
306302

307303
inline v128 operator |(const v128& left, const v128& right)
@@ -950,11 +946,13 @@ template<typename T> using atomic_le_t = atomic_t<le_t<T>>;
950946

951947
// Formatting for BE/LE data
952948
template<typename T, bool Se, std::size_t Align>
953-
struct unveil<se_t<T, Se, Align>, void>
949+
struct fmt_unveil<se_t<T, Se, Align>, void>
954950
{
955-
static inline auto get(const se_t<T, Se, Align>& arg)
951+
using type = typename fmt_unveil<T>::type;
952+
953+
static inline u64 get(const se_t<T, Se, Align>& arg)
956954
{
957-
return unveil<T>::get(arg);
955+
return fmt_unveil<T>::get(arg);
958956
}
959957
};
960958

Utilities/BitField.h

+33
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,36 @@ struct ff_t : bf_base<T, N>
242242
return V;
243243
}
244244
};
245+
246+
template<typename T, uint I, uint N>
247+
struct fmt_unveil<bf_t<T, I, N>, void>
248+
{
249+
using type = typename fmt_unveil<simple_t<T>>::type;
250+
251+
static inline u64 get(const bf_t<T, I, N>& bf)
252+
{
253+
return fmt_unveil<type>::get(bf);
254+
}
255+
};
256+
257+
template<typename F, typename... Fields>
258+
struct fmt_unveil<cf_t<F, Fields...>, void>
259+
{
260+
using type = typename fmt_unveil<simple_t<typename F::type>>::type;
261+
262+
static inline u64 get(const cf_t<F, Fields...>& cf)
263+
{
264+
return fmt_unveil<type>::get(cf);
265+
}
266+
};
267+
268+
template<typename T, T V, uint N>
269+
struct fmt_unveil<ff_t<T, V, N>, void>
270+
{
271+
using type = typename fmt_unveil<simple_t<T>>::type;
272+
273+
static inline u64 get(const ff_t<T, V, N>& ff)
274+
{
275+
return fmt_unveil<type>::get(ff);
276+
}
277+
};

Utilities/BitSet.h

+11
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,14 @@ struct atomic_test_and_complement<bitset_t<T>, T, std::enable_if_t<std::is_enum<
256256

257257
static constexpr auto atomic_op = &_op;
258258
};
259+
260+
template<typename T, std::size_t BitSize>
261+
struct fmt_unveil<bitset_t<T, BitSize>, void>
262+
{
263+
using type = typename bitset_t<T, BitSize>::raw_type;
264+
265+
static inline u64 get(const bitset_t<T, BitSize>& value)
266+
{
267+
return fmt_unveil<type>::get(static_cast<type>(value._value()));
268+
}
269+
};

Utilities/Config.cpp

+56
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,62 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
8585
return true;
8686
}
8787

88+
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
89+
{
90+
for (u64 i = 0;; i++)
91+
{
92+
std::string var;
93+
func(var, i);
94+
95+
if (var == value)
96+
{
97+
if (out) *out = i;
98+
return true;
99+
}
100+
101+
std::string hex;
102+
fmt_class_string<u64>::format(hex, i);
103+
if (var == hex)
104+
{
105+
break;
106+
}
107+
}
108+
109+
try
110+
{
111+
const auto val = std::stoull(value, nullptr, 0);
112+
113+
if (out) *out = val;
114+
return true;
115+
}
116+
catch (...)
117+
{
118+
return false;
119+
}
120+
}
121+
122+
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
123+
{
124+
std::vector<std::string> result;
125+
126+
for (u64 i = 0;; i++)
127+
{
128+
std::string var;
129+
func(var, i);
130+
131+
std::string hex;
132+
fmt_class_string<u64>::format(hex, i);
133+
if (var == hex)
134+
{
135+
break;
136+
}
137+
138+
result.emplace_back(std::move(var));
139+
}
140+
141+
return result;
142+
}
143+
88144
void cfg::encode(YAML::Emitter& out, const cfg::entry_base& rhs)
89145
{
90146
switch (rhs.get_type())

Utilities/Config.h

+21-21
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "Utilities/types.h"
44
#include "Utilities/Atomic.h"
5+
#include "Utilities/StrFmt.h"
56

67
#include <initializer_list>
78
#include <exception>
@@ -18,6 +19,12 @@ namespace cfg
1819
// Convert string to signed integer
1920
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
2021

22+
// Internal hack
23+
bool try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string&);
24+
25+
// Internal hack
26+
std::vector<std::string> try_to_enum_list(decltype(&fmt_class_string<int>::format) func);
27+
2128
// Config tree entry type.
2229
enum class type : uint
2330
{
@@ -296,41 +303,34 @@ namespace cfg
296303

297304
std::string to_string() const override
298305
{
299-
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
300-
{
301-
if (bijective<T, const char*>::map[i].v1 == m_value)
302-
{
303-
return bijective<T, const char*>::map[i].v2;
304-
}
305-
}
306-
307-
return{}; // TODO: ???
306+
std::string result;
307+
fmt_class_string<T>::format(result, fmt_unveil<T>::get(m_value));
308+
return result; // TODO: ???
308309
}
309310

310311
bool from_string(const std::string& value) override
311312
{
312-
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
313+
u64 result;
314+
315+
if (try_to_enum_value(&result, &fmt_class_string<T>::format, value))
313316
{
314-
if (bijective<T, const char*>::map[i].v2 == value)
317+
const auto val = static_cast<std::underlying_type_t<T>>(result);
318+
319+
if (static_cast<u64>(val) != result)
315320
{
316-
m_value = bijective<T, const char*>::map[i].v1;
317-
return true;
321+
return false;
318322
}
323+
324+
m_value = static_cast<T>(val);
325+
return true;
319326
}
320327

321328
return false;
322329
}
323330

324331
std::vector<std::string> to_list() const override
325332
{
326-
std::vector<std::string> result;
327-
328-
for (std::size_t i = 0; i < sizeof(bijective<T, const char*>::map) / sizeof(bijective_pair<T, const char*>); i++)
329-
{
330-
result.emplace_back(bijective<T, const char*>::map[i].v2);
331-
}
332-
333-
return result;
333+
return try_to_enum_list(&fmt_class_string<T>::format);
334334
}
335335
};
336336

Utilities/File.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -1333,3 +1333,37 @@ u64 fs::get_dir_size(const std::string& path)
13331333

13341334
return result;
13351335
}
1336+
1337+
template<>
1338+
void fmt_class_string<fs::seek_mode>::format(std::string& out, u64 arg)
1339+
{
1340+
format_enum(out, arg, [](auto arg)
1341+
{
1342+
switch (arg)
1343+
{
1344+
STR_CASE(fs::seek_mode::seek_set);
1345+
STR_CASE(fs::seek_mode::seek_cur);
1346+
STR_CASE(fs::seek_mode::seek_end);
1347+
}
1348+
1349+
return unknown;
1350+
});
1351+
}
1352+
1353+
template<>
1354+
void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
1355+
{
1356+
format_enum(out, arg, [](auto arg)
1357+
{
1358+
switch (arg)
1359+
{
1360+
case fs::error::ok: return "OK";
1361+
1362+
case fs::error::inval: return "Invalid arguments";
1363+
case fs::error::noent: return "Not found";
1364+
case fs::error::exist: return "Already exists";
1365+
}
1366+
1367+
return unknown;
1368+
});
1369+
}

Utilities/File.h

-18
Original file line numberDiff line numberDiff line change
@@ -463,21 +463,3 @@ namespace fs
463463
// Error code returned
464464
extern thread_local error g_tls_error;
465465
}
466-
467-
template<>
468-
struct unveil<fs::error>
469-
{
470-
static inline const char* get(fs::error error)
471-
{
472-
switch (error)
473-
{
474-
case fs::error::ok: return "OK";
475-
476-
case fs::error::inval: return "Invalid arguments";
477-
case fs::error::noent: return "Not found";
478-
case fs::error::exist: return "Already exists";
479-
480-
default: throw error;
481-
}
482-
}
483-
};

Utilities/Log.cpp

+23-10
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,31 @@
33
#include "StrFmt.h"
44

55
#include "rpcs3_version.h"
6-
#include <cstdarg>
76
#include <string>
87

98
// Thread-specific log prefix provider
109
thread_local std::string(*g_tls_log_prefix)() = nullptr;
1110

12-
#ifndef _MSC_VER
13-
constexpr DECLARE(bijective<logs::level, const char*>::map);
14-
#endif
11+
template<>
12+
void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
13+
{
14+
format_enum(out, arg, [](auto lev)
15+
{
16+
switch (lev)
17+
{
18+
case logs::level::always: return "Nothing";
19+
case logs::level::fatal: return "Fatal";
20+
case logs::level::error: return "Error";
21+
case logs::level::todo: return "TODO";
22+
case logs::level::success: return "Success";
23+
case logs::level::warning: return "Warning";
24+
case logs::level::notice: return "Notice";
25+
case logs::level::trace: return "Trace";
26+
}
27+
28+
return unknown;
29+
});
30+
}
1531

1632
namespace logs
1733
{
@@ -72,13 +88,10 @@ void logs::listener::add(logs::listener* _new)
7288
}
7389
}
7490

75-
void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt...)
91+
void logs::channel::broadcast(const logs::channel& ch, logs::level sev, const char* fmt, const fmt::supplementary_info* sup, const u64* args)
7692
{
77-
va_list args;
78-
va_start(args, fmt);
79-
std::string&& text = fmt::unsafe_vformat(fmt, args);
80-
std::string&& prefix = g_tls_log_prefix ? g_tls_log_prefix() : "";
81-
va_end(args);
93+
std::string text; fmt::raw_append(text, fmt, sup, args);
94+
std::string prefix(g_tls_log_prefix ? g_tls_log_prefix() : "");
8295

8396
// Prepare message information
8497
message msg;

0 commit comments

Comments
 (0)