cprintf: support a configurable width and precision ("*" in printf)

This commit is contained in:
Nathan Binkert 2008-12-03 04:57:54 -08:00
parent 47e2b08893
commit 74f10be526
4 changed files with 57 additions and 8 deletions

View file

@ -40,7 +40,7 @@ using namespace std;
namespace cp {
Print::Print(std::ostream &stream, const std::string &format)
: stream(stream), format(format.c_str()), ptr(format.c_str())
: stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
{
saved_flags = stream.flags();
saved_fill = stream.fill();
@ -48,7 +48,7 @@ Print::Print(std::ostream &stream, const std::string &format)
}
Print::Print(std::ostream &stream, const char *format)
: stream(stream), format(format), ptr(format)
: stream(stream), format(format), ptr(format), cont(false)
{
saved_flags = stream.flags();
saved_fill = stream.fill();
@ -60,8 +60,10 @@ Print::~Print()
}
void
Print::process(Format &fmt)
Print::process()
{
fmt.clear();
size_t len;
while (*ptr) {
@ -221,8 +223,15 @@ Print::process(Format &fmt)
number = number * 10 + (*ptr - '0');
break;
case '*':
if (have_precision)
fmt.get_precision = true;
else
fmt.get_width = true;
break;
case '%':
assert("we shouldn't get here");
assert(false && "we shouldn't get here");
break;
default:

View file

@ -51,24 +51,53 @@ struct Print
std::ostream &stream;
const char *format;
const char *ptr;
bool cont;
std::ios::fmtflags saved_flags;
char saved_fill;
int saved_precision;
void process(Format &fmt);
Format fmt;
void process();
public:
Print(std::ostream &stream, const std::string &format);
Print(std::ostream &stream, const char *format);
~Print();
int
get_number(int data)
{
return data;
}
template <typename T>
int
get_number(const T& data)
{
return 0;
}
template <typename T>
void
add_arg(const T &data)
{
Format fmt;
process(fmt);
if (!cont)
process();
if (fmt.get_width) {
fmt.get_width = false;
cont = true;
fmt.width = get_number(data);
return;
}
if (fmt.get_precision) {
fmt.get_precision = false;
cont = true;
fmt.precision = get_number(data);
return;
}
switch (fmt.format) {
case Format::character:

View file

@ -50,6 +50,8 @@ struct Format
enum { best, fixed, scientific } float_format;
int precision;
int width;
bool get_precision;
bool get_width;
Format() { clear(); }
@ -65,6 +67,8 @@ struct Format
format = none;
precision = -1;
width = 0;
get_precision = false;
get_width = false;
}
};

View file

@ -167,6 +167,13 @@ main()
cprintf("%c %c\n", 'c', 65);
cout << '9';
cout << '9' << endl;
cout << endl;
cprintf("%08.4f\n", 99.99);
cprintf("%0*.*f\n", 8, 4, 99.99);
cprintf("%07.*f\n", 4, 1.234);
cprintf("%#0*x\n", 9, 123412);
return 0;
}