base: Prevent undefined behavior in not interleaved `AddrRange`s.
[gem5.git] / src / base / cprintf_formats.hh
index 75157a540d0d384dcc6fe220fc9edf4206ac1b2c..b12b2d71a4f771323d1aa6c47f14752e0b3287ac 100644 (file)
@@ -24,8 +24,6 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Nathan Binkert
  */
 
 #ifndef __BASE_CPRINTF_FORMATS_HH__
@@ -50,6 +48,8 @@ struct Format
     enum { best, fixed, scientific } float_format;
     int precision;
     int width;
+    bool get_precision;
+    bool get_width;
 
     Format() { clear(); }
 
@@ -63,8 +63,11 @@ struct Format
         uppercase = false;
         base = dec;
         format = none;
+        float_format = best;
         precision = -1;
         width = 0;
+        get_precision = false;
+        get_width = false;
     }
 };
 
@@ -83,6 +86,8 @@ _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(std::ios::hex, std::ios::basefield);
@@ -132,6 +137,8 @@ _format_integer(std::ostream &out, const T &data, Format &fmt)
         out.setf(std::ios::uppercase);
 
     out << data;
+
+    out.flags(flags);
 }
 
 template <typename T>
@@ -140,6 +147,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) {
@@ -184,43 +196,34 @@ _format_float(std::ostream &out, const T &data, Format &fmt)
     }
 
     out << data;
+
+    out.flags(flags);
 }
 
 template <typename T>
 inline void
 _format_string(std::ostream &out, const T &data, Format &fmt)
 {
-    using namespace std;
-
-#if defined(__GNUC__) && (__GNUC__ < 3) || 1
     if (fmt.width > 0) {
         std::stringstream foo;
         foo << data;
         int flen = foo.str().size();
 
         if (fmt.width > flen) {
-            char *spaces = new char[fmt.width - flen + 1];
-            memset(spaces, ' ', fmt.width - flen);
+            char spaces[fmt.width - flen + 1];
+            std::memset(spaces, ' ', fmt.width - flen);
             spaces[fmt.width - flen] = 0;
 
             if (fmt.flush_left)
                 out << foo.str() << spaces;
             else
                 out << spaces << foo.str();
-
-            delete [] spaces;
-        } else
+        } else {
             out << data;
-    } else
+        }
+    } else {
         out << data;
-#else
-    if (fmt.width > 0)
-        out.width(fmt.width);
-    if (fmt.flush_left)
-        out.setf(std::ios::left);
-
-    out << data;
-#endif
+    }
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -296,32 +299,12 @@ format_integer(std::ostream &out, unsigned char data, Format &fmt)
 inline void
 format_integer(std::ostream &out, signed char data, Format &fmt)
 { _format_integer(out, (int)data, fmt); }
-#if 0
 inline void
-format_integer(std::ostream &out, short data, Format &fmt)
-{ _format_integer(out, data, fmt); }
+format_integer(std::ostream &out, const unsigned char *data, Format &fmt)
+{ _format_integer(out, (uintptr_t)data, fmt); }
 inline void
-format_integer(std::ostream &out, unsigned short data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-inline void
-format_integer(std::ostream &out, int data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-inline void
-format_integer(std::ostream &out, unsigned int data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-inline void
-format_integer(std::ostream &out, long data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-inline void
-format_integer(std::ostream &out, unsigned long data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-inline void
-format_integer(std::ostream &out, long long data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-inline void
-format_integer(std::ostream &out, unsigned long long data, Format &fmt)
-{ _format_integer(out, data, fmt); }
-#endif
+format_integer(std::ostream &out, const signed char *data, Format &fmt)
+{ _format_integer(out, (uintptr_t)data, fmt); }
 
 //
 // floating point formats
@@ -347,10 +330,6 @@ inline void
 format_string(std::ostream &out, const T &data, Format &fmt)
 { _format_string(out, data, fmt); }
 
-inline void
-format_string(std::ostream &out, const std::stringstream &data, Format &fmt)
-{ _format_string(out, data.str(), fmt); }
-
 } // namespace cp
 
 #endif // __CPRINTF_FORMATS_HH__