summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/base/cprintf.cc17
-rw-r--r--src/base/cprintf.hh35
-rw-r--r--src/base/cprintf_formats.hh4
-rw-r--r--src/unittest/cprintftest.cc9
4 files changed, 57 insertions, 8 deletions
diff --git a/src/base/cprintf.cc b/src/base/cprintf.cc
index d4ba9ca21..5c11e501c 100644
--- a/src/base/cprintf.cc
+++ b/src/base/cprintf.cc
@@ -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:
diff --git a/src/base/cprintf.hh b/src/base/cprintf.hh
index cff73a228..2920e210d 100644
--- a/src/base/cprintf.hh
+++ b/src/base/cprintf.hh
@@ -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:
diff --git a/src/base/cprintf_formats.hh b/src/base/cprintf_formats.hh
index 75157a540..6bf6b2b66 100644
--- a/src/base/cprintf_formats.hh
+++ b/src/base/cprintf_formats.hh
@@ -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;
}
};
diff --git a/src/unittest/cprintftest.cc b/src/unittest/cprintftest.cc
index 1438f194b..6722ce6a3 100644
--- a/src/unittest/cprintftest.cc
+++ b/src/unittest/cprintftest.cc
@@ -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;
}