mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-25 07:41:07 +00:00
Implement dynamic width in printf.
This commit is contained in:
parent
8666ea82f7
commit
1275923a68
39
format.cc
39
format.cc
@ -632,23 +632,18 @@ void fmt::BasicWriter<Char>::PrintfParser::ParseFlags(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this doesnt' depend on template argument
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
unsigned fmt::BasicWriter<Char>::PrintfParser::ParseArgIndex(
|
unsigned fmt::BasicWriter<Char>::PrintfParser::HandleArgIndex(
|
||||||
const Char *&s, const char *&error) {
|
unsigned arg_index, const char *&error) {
|
||||||
Char c = *s;
|
if (arg_index != UINT_MAX) {
|
||||||
unsigned value = 0;
|
|
||||||
if (c >= '0' && c <= '9') {
|
|
||||||
value = internal::ParseNonnegativeInt(s, error);
|
|
||||||
if (*s == '$') {
|
|
||||||
++s;
|
|
||||||
if (next_arg_index_ <= 0) {
|
if (next_arg_index_ <= 0) {
|
||||||
next_arg_index_ = -1;
|
next_arg_index_ = -1;
|
||||||
return value - 1;
|
return arg_index - 1;
|
||||||
}
|
}
|
||||||
if (!error)
|
if (!error)
|
||||||
error = "cannot switch from automatic to manual argument indexing";
|
error = "cannot switch from automatic to manual argument indexing";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (next_arg_index_ >= 0)
|
if (next_arg_index_ >= 0)
|
||||||
return next_arg_index_++;
|
return next_arg_index_++;
|
||||||
// Don't check if the error has already been set because the argument
|
// Don't check if the error has already been set because the argument
|
||||||
@ -656,7 +651,7 @@ unsigned fmt::BasicWriter<Char>::PrintfParser::ParseArgIndex(
|
|||||||
// indexing errors are reported first even though parsing width
|
// indexing errors are reported first even though parsing width
|
||||||
// above can cause another error.
|
// above can cause another error.
|
||||||
error = "cannot switch from manual to automatic argument indexing";
|
error = "cannot switch from manual to automatic argument indexing";
|
||||||
return value;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
@ -694,15 +689,27 @@ void fmt::BasicWriter<Char>::PrintfParser::Format(
|
|||||||
const char *error = 0;
|
const char *error = 0;
|
||||||
|
|
||||||
c = *s;
|
c = *s;
|
||||||
unsigned arg_index = ParseArgIndex(s, error);
|
unsigned arg_index = UINT_MAX;
|
||||||
if (c >= '0' && c <= '9' && s[-1] != '$') { // TODO
|
if (c >= '0' && c <= '9') {
|
||||||
|
unsigned value = internal::ParseNonnegativeInt(s, error);
|
||||||
|
if (*s != '$') {
|
||||||
if (c == '0')
|
if (c == '0')
|
||||||
spec.fill_ = '0';
|
spec.fill_ = '0';
|
||||||
if (arg_index != 0)
|
if (value != 0)
|
||||||
spec.width_ = arg_index + 1;
|
spec.width_ = value;
|
||||||
arg_index = 0;
|
} else {
|
||||||
|
++s;
|
||||||
|
arg_index = value;
|
||||||
}
|
}
|
||||||
|
} else if (c == '*') {
|
||||||
|
++s;
|
||||||
|
const ArgInfo &arg = args_[HandleArgIndex(UINT_MAX, error)];
|
||||||
|
// TODO: check if arg is integer
|
||||||
|
spec.width_ = GetIntValue(arg);
|
||||||
|
}
|
||||||
|
arg_index = HandleArgIndex(arg_index, error);
|
||||||
|
|
||||||
|
// TODO: move to HandleArgIndex
|
||||||
const ArgInfo *arg = 0;
|
const ArgInfo *arg = 0;
|
||||||
if (arg_index < num_args) {
|
if (arg_index < num_args) {
|
||||||
arg = &args_[arg_index];
|
arg = &args_[arg_index];
|
||||||
|
2
format.h
2
format.h
@ -1043,7 +1043,7 @@ class BasicWriter {
|
|||||||
const ArgInfo *args_;
|
const ArgInfo *args_;
|
||||||
int next_arg_index_;
|
int next_arg_index_;
|
||||||
|
|
||||||
unsigned ParseArgIndex(const Char *&s, const char *&error);
|
unsigned HandleArgIndex(unsigned arg_index, const char *&error);
|
||||||
void ParseFlags(FormatSpec &spec, const Char *&s, const ArgInfo &arg);
|
void ParseFlags(FormatSpec &spec, const Char *&s, const ArgInfo &arg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -135,6 +135,7 @@ TEST(PrintfTest, DefaultAlignRight) {
|
|||||||
|
|
||||||
TEST(PrintfTest, Width) {
|
TEST(PrintfTest, Width) {
|
||||||
EXPECT_PRINTF(" abc", "%5s", "abc");
|
EXPECT_PRINTF(" abc", "%5s", "abc");
|
||||||
|
EXPECT_EQ(" 42", str(fmt::sprintf("%*d", 5, 42)));
|
||||||
|
|
||||||
// Width cannot be specified twice.
|
// Width cannot be specified twice.
|
||||||
EXPECT_THROW_MSG(fmt::sprintf("%5-5d", 42), FormatError,
|
EXPECT_THROW_MSG(fmt::sprintf("%5-5d", 42), FormatError,
|
||||||
|
Loading…
Reference in New Issue
Block a user