diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 277a3470cd..b9a2084095 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -449,7 +449,7 @@ struct fmt::cfmt_src { // Hack: use known function pointers to determine type #define TYPE(type) \ - if (sup[extra].fmt_string == &fmt_class_string::format) return sizeof(type); + if (sup[extra].fmt_string == &fmt_class_string::format) return sizeof(type); TYPE(int); TYPE(llong); @@ -457,10 +457,11 @@ struct fmt::cfmt_src TYPE(short); if (std::is_signed::value) TYPE(char); TYPE(long); - TYPE(u128); TYPE(s128); #undef TYPE + if (sup[extra].fmt_string == &fmt_class_string::format) + return -1; return 0; } diff --git a/Utilities/cfmt.h b/Utilities/cfmt.h index 4d4067d9e6..3b2c94dcbc 100644 --- a/Utilities/cfmt.h +++ b/Utilities/cfmt.h @@ -367,9 +367,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) break; } - if (!ctx.type) + const usz src_type = src.type(ctx.args); + + if (!ctx.type || src_type > 8) { - ctx.type = static_cast(src.type(ctx.args)); + ctx.type = static_cast(src_type); if (!ctx.type) { @@ -379,7 +381,13 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) // Sign-extended argument expected const u64 val = src.template get(ctx.args); - const bool negative = ctx.type && static_cast(val) < 0; + bool negative = ctx.type && ctx.type <= 8 && static_cast(val) < 0; + + if (ctx.type == 16) + { + u128 val2 = *reinterpret_cast(val); + negative = !!(val2 & (u128{1} << 127)); + } const usz start = out.size(); @@ -398,15 +406,14 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) out.push_back(' '); } - if (ctx.type == 16) + if (ctx.type >= 16) { - // TODO: support negative values (s128) - u128 val2 = *reinterpret_cast(val); - write_decimal(val2, ctx.prec); + u128 val2 = *reinterpret_cast(val); + write_decimal(negative ? u128{} - val2 : val2, ctx.prec); } else { - write_decimal(negative ? 0 - val : val, ctx.prec); + write_decimal(negative ? u64{} - val : val, ctx.prec); } } @@ -438,9 +445,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) break; } - if (!ctx.type) + const usz src_type = src.type(ctx.args); + + if (!ctx.type || src_type > 8) { - ctx.type = static_cast(src.type(ctx.args)); + ctx.type = static_cast(src_type); if (!ctx.type) { @@ -471,9 +480,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) if ((ctx.alter && val) || !ctx.dot || ctx.prec) { - if (ctx.type == 16) + if (ctx.type >= 16) { - u128 val2 = *reinterpret_cast(val); + u128 val2 = *reinterpret_cast(val); write_octal(val2, ctx.prec); } else @@ -504,9 +513,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) break; } - if (!ctx.type) + const usz src_type = src.type(ctx.args); + + if (!ctx.type || src_type > 8) { - ctx.type = static_cast(src.type(ctx.args)); + ctx.type = static_cast(src_type); if (!ctx.type) { @@ -537,9 +548,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) if ((ctx.alter && val) || !ctx.dot || ctx.prec) { - if (ctx.type == 16) + if (ctx.type >= 16) { - u128 val2 = *reinterpret_cast(val); + u128 val2 = *reinterpret_cast(val); write_hex(val2, ch == 'X', ctx.prec); } else @@ -576,9 +587,11 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) break; } - if (!ctx.type) + const usz src_type = src.type(ctx.args); + + if (!ctx.type || src_type > 8) { - ctx.type = static_cast(src.type(ctx.args)); + ctx.type = static_cast(src_type); if (!ctx.type) { @@ -599,9 +612,9 @@ usz cfmt_append(Dst& out, const Char* fmt, Src&& src) if (!ctx.dot || ctx.prec) { - if (ctx.type == 16) + if (ctx.type >= 16) { - u128 val2 = *reinterpret_cast(val); + u128 val2 = *reinterpret_cast(val); write_decimal(val2, ctx.prec); } else