Fix cprintf bug, plus minor cleanup & better error messages.
authorSteve Reinhardt <stever@eecs.umich.edu>
Sun, 11 Jan 2004 23:09:27 +0000 (15:09 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Sun, 11 Jan 2004 23:09:27 +0000 (15:09 -0800)
base/cprintf.cc:
    Fix bug where a call with a format string with no specifiers
    but one or more arguments would crash.  Old code tried to print
    extra args using last available format, but in this case there
    was no format, hence the problem.  Now we just print "<extra arg>"
    for each extra arg.

    Also reorganized code a bit to make scope of fmt variable
    match the scope in which you can be confident it's meaningful.
base/cprintf.hh:
    Print specific error message instead of calling format_invalid().
base/cprintf_formats.hh:
    Clear Format object in constructor.
    Use specific error messages instead of format_invalid() function.

--HG--
extra : convert_revision : 87d5e902174e3eb2583131d056742af166540db0

base/cprintf.cc
base/cprintf.hh
base/cprintf_formats.hh

index af3b26a57785af291b320ff15c51e18e595b4b5e..5796a712bb41dbbcea46ec8e16904bb0b4920277 100644 (file)
@@ -45,8 +45,6 @@ ArgList::dump(const string &format)
     stream->fill(' ');
     stream->flags((ios::fmtflags)0);
 
-    Format fmt;
-
     while (*p) {
         switch (*p) {
           case '%': {
@@ -56,12 +54,7 @@ ArgList::dump(const string &format)
                   continue;
               }
 
-              if (objects.empty())
-                  format_invalid(*stream);
-
-              Base *data = objects.front();
-
-              fmt.clear();
+              Format fmt;
               bool done = false;
               bool end_number = false;
               bool have_precision = false;
@@ -205,18 +198,26 @@ ArgList::dump(const string &format)
                   }
               }
 
-              ios::fmtflags saved_flags = stream->flags();
-              char old_fill = stream->fill();
-              int old_precision = stream->precision();
+              if (!objects.empty())
+              {
+                  Base *data = objects.front();
+                  objects.pop_front();
+
+                  ios::fmtflags saved_flags = stream->flags();
+                  char old_fill = stream->fill();
+                  int old_precision = stream->precision();
 
-              data->process(*stream, fmt);
+                  data->process(*stream, fmt);
 
-              stream->flags(saved_flags);
-              stream->fill(old_fill);
-              stream->precision(old_precision);
+                  stream->flags(saved_flags);
+                  stream->fill(old_fill);
+                  stream->precision(old_precision);
+
+                  delete data;
+              } else {
+                  *stream << "<missing arg for format>";
+              }
 
-              delete data;
-              objects.pop_front();
               ++p;
           }
             break;
@@ -241,10 +242,10 @@ ArgList::dump(const string &format)
     }
 
     while (!objects.empty()) {
+        *stream << "<extra arg>";
         Base *data = objects.front();
-        data->process(*stream, fmt);
-        delete data;
         objects.pop_front();
+        delete data;
     }
 }
 
index 8360d227c57d34629d78781b464d7c3b012fe9f0..ac34cd25212d3b1c631f497d7ed264943e102eb5 100644 (file)
@@ -75,7 +75,7 @@ class ArgList
                 break;
 
               default:
-                format_invalid(out);
+                out << "<bad format>";
                 break;
             }
         }
index 1e5de4fdf8ba15504c66e59a80a31a8a9c84fe43..b921c05062ba5b1236ac24dee4b45e980ac15dc4 100644 (file)
@@ -43,8 +43,10 @@ struct Format
     int precision;
     int width;
 
-    Format() { }
-    void clear() {
+    Format() { clear(); }
+
+    void clear()
+    {
         alternate_form = false;
         flush_left = false;
         print_sign = false;
@@ -58,15 +60,6 @@ struct Format
     }
 };
 
-inline void
-format_invalid(std::ostream &out)
-{
-    using namespace std;
-
-    out << "format invalid!!!" << endl;
-}
-
-
 template <typename T>
 inline void
 _format_char(std::ostream &out, const T& data, Format &fmt)
@@ -233,7 +226,7 @@ _format_string(std::ostream &out, const T& data, Format &fmt)
 template <typename T>
 inline void
 format_char(std::ostream &out, const T& data, Format &fmt)
-{ format_invalid(out); }
+{ out << "<bad arg type for char format>"; }
 
 inline void
 format_char(std::ostream &out, char data, Format &fmt)
@@ -329,7 +322,7 @@ format_integer(std::ostream &out, unsigned long long data, Format &fmt)
 template <typename T>
 inline void
 format_float(std::ostream &out, const T& data, Format &fmt)
-{ format_invalid(out); }
+{ out << "<bad arg type for float format>"; }
 
 inline void
 format_float(std::ostream &out, float data, Format &fmt)