base: Handle zero fill in cprintf when printing floats.
[gem5.git] / src / base / cprintf_formats.hh
index 58ee7f7950f4c037d66dee093bd0d2bb7cfaadf7..253fe59cfca6198d35c16a88ad532ce11af309cc 100644 (file)
  * Authors: Nathan Binkert
  */
 
-#ifndef __CPRINTF_FORMATS_HH__
-#define __CPRINTF_FORMATS_HH__
+#ifndef __BASE_CPRINTF_FORMATS_HH__
+#define __BASE_CPRINTF_FORMATS_HH__
 
-#include <sstream>
+#include <cstring>
 #include <ostream>
+#include <sstream>
 
 namespace cp {
 
@@ -49,6 +50,8 @@ struct Format
     enum { best, fixed, scientific } float_format;
     int precision;
     int width;
+    bool get_precision;
+    bool get_width;
 
     Format() { clear(); }
 
@@ -62,8 +65,11 @@ struct Format
         uppercase = false;
         base = dec;
         format = none;
+        float_format = best;
         precision = -1;
         width = 0;
+        get_precision = false;
+        get_width = false;
     }
 };
 
@@ -82,23 +88,25 @@ _format_integer(std::ostream &out, const T &data, Format &fmt)
 {
     using namespace std;
 
+    ios::fmtflags flags(out.flags());
+
     switch (fmt.base) {
       case Format::hex:
-        out.setf(ios::hex, ios::basefield);
+        out.setf(std::ios::hex, std::ios::basefield);
         break;
 
       case Format::oct:
-        out.setf(ios::oct, ios::basefield);
+        out.setf(std::ios::oct, std::ios::basefield);
         break;
 
       case Format::dec:
-        out.setf(ios::dec, ios::basefield);
+        out.setf(std::ios::dec, std::ios::basefield);
         break;
     }
 
     if (fmt.alternate_form) {
         if (!fmt.fill_zero)
-            out.setf(ios::showbase);
+            out.setf(std::ios::showbase);
         else {
             switch (fmt.base) {
               case Format::hex:
@@ -122,15 +130,17 @@ _format_integer(std::ostream &out, const T &data, Format &fmt)
         out.width(fmt.width);
 
     if (fmt.flush_left && !fmt.fill_zero)
-        out.setf(ios::left);
+        out.setf(std::ios::left);
 
     if (fmt.print_sign)
-        out.setf(ios::showpos);
+        out.setf(std::ios::showpos);
 
     if (fmt.uppercase)
-        out.setf(ios::uppercase);
+        out.setf(std::ios::uppercase);
 
     out << data;
+
+    out.flags(flags);
 }
 
 template <typename T>
@@ -139,6 +149,11 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
 {
     using namespace std;
 
+    ios::fmtflags flags(out.flags());
+
+    if (fmt.fill_zero)
+        out.fill('0');
+
     switch (fmt.float_format) {
       case Format::scientific:
         if (fmt.precision != -1) {
@@ -148,7 +163,7 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
             if (fmt.precision == 0)
                 fmt.precision = 1;
             else
-                out.setf(ios::scientific);
+                out.setf(std::ios::scientific);
 
             out.precision(fmt.precision);
         } else
@@ -156,7 +171,7 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
                 out.width(fmt.width);
 
         if (fmt.uppercase)
-            out.setf(ios::uppercase);
+            out.setf(std::ios::uppercase);
         break;
 
       case Format::fixed:
@@ -164,7 +179,7 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
             if (fmt.width > 0)
                 out.width(fmt.width);
 
-            out.setf(ios::fixed);
+            out.setf(std::ios::fixed);
             out.precision(fmt.precision);
         } else
             if (fmt.width > 0)
@@ -183,6 +198,8 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
     }
 
     out << data;
+
+    out.flags(flags);
 }
 
 template <typename T>
@@ -216,7 +233,7 @@ _format_string(std::ostream &out, const T &data, Format &fmt)
     if (fmt.width > 0)
         out.width(fmt.width);
     if (fmt.flush_left)
-        out.setf(ios::left);
+        out.setf(std::ios::left);
 
     out << data;
 #endif
@@ -288,13 +305,13 @@ format_integer(std::ostream &out, const T &data, Format &fmt)
 { _format_integer(out, data, fmt); }
 inline void
 format_integer(std::ostream &out, char data, Format &fmt)
-{ _format_integer(out, data, fmt); }
+{ _format_integer(out, (int)data, fmt); }
 inline void
 format_integer(std::ostream &out, unsigned char data, Format &fmt)
-{ _format_integer(out, data, fmt); }
+{ _format_integer(out, (int)data, fmt); }
 inline void
 format_integer(std::ostream &out, signed char data, Format &fmt)
-{ _format_integer(out, data, fmt); }
+{ _format_integer(out, (int)data, fmt); }
 #if 0
 inline void
 format_integer(std::ostream &out, short data, Format &fmt)