mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-05 00:40:12 +00:00
Improve handling of char in printf.
This commit is contained in:
parent
f2be7851cc
commit
c4a4a05d12
30
format.cc
30
format.cc
@ -270,6 +270,21 @@ class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Converts an integer argument to char.
|
||||||
|
class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> {
|
||||||
|
private:
|
||||||
|
fmt::internal::Arg &arg_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CharConverter(fmt::internal::Arg &arg) : arg_(arg) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void visit_any_int(T value) {
|
||||||
|
arg_.type = Arg::CHAR;
|
||||||
|
arg_.int_value = static_cast<char>(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// This function template is used to prevent compile errors when handling
|
// This function template is used to prevent compile errors when handling
|
||||||
// incompatible string arguments, e.g. handling a wide string in a narrow
|
// incompatible string arguments, e.g. handling a wide string in a narrow
|
||||||
// string formatter.
|
// string formatter.
|
||||||
@ -954,7 +969,8 @@ void fmt::internal::PrintfFormatter<Char>::format(
|
|||||||
ArgConverter<ptrdiff_t>(arg, *s).visit(arg);
|
ArgConverter<ptrdiff_t>(arg, *s).visit(arg);
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
// TODO: handle length
|
// printf produces garbage when 'L' is omitted for long double, no
|
||||||
|
// need to do the same.
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
--s;
|
--s;
|
||||||
@ -966,9 +982,17 @@ void fmt::internal::PrintfFormatter<Char>::format(
|
|||||||
if (error_)
|
if (error_)
|
||||||
throw FormatError(error_);
|
throw FormatError(error_);
|
||||||
spec.type_ = static_cast<char>(*s++);
|
spec.type_ = static_cast<char>(*s++);
|
||||||
if (arg.type <= Arg::LAST_INTEGER_TYPE &&
|
if (arg.type <= Arg::LAST_INTEGER_TYPE) {
|
||||||
(spec.type_ == 'i' || spec.type_ == 'u')) {
|
// Normalize type.
|
||||||
|
switch (spec.type_) {
|
||||||
|
case 'i': case 'u':
|
||||||
spec.type_ = 'd';
|
spec.type_ = 'd';
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
// TODO: handle wchar_t
|
||||||
|
CharConverter(arg).visit(arg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
start = s;
|
start = s;
|
||||||
|
@ -368,7 +368,14 @@ TEST(PrintfTest, Length) {
|
|||||||
long double max = std::numeric_limits<long double>::max();
|
long double max = std::numeric_limits<long double>::max();
|
||||||
EXPECT_PRINTF(fmt::format("{}", max), "%g", max);
|
EXPECT_PRINTF(fmt::format("{}", max), "%g", max);
|
||||||
EXPECT_PRINTF(fmt::format("{}", max), "%Lg", max);
|
EXPECT_PRINTF(fmt::format("{}", max), "%Lg", max);
|
||||||
// TODO: test char, string
|
}
|
||||||
|
|
||||||
|
TEST(PrintfTest, Char) {
|
||||||
|
EXPECT_PRINTF("x", "%c", 'x');
|
||||||
|
int max = std::numeric_limits<int>::max();
|
||||||
|
EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max);
|
||||||
|
// TODO: test wchar_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test type specifier
|
// TODO: test type specifier
|
||||||
|
// TODO: test char, string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user