base: Fix a few incorrectly handled print format cases
authorChander Sudanthi <chander.sudanthi@arm.com>
Fri, 2 Nov 2012 16:32:00 +0000 (11:32 -0500)
committerChander Sudanthi <chander.sudanthi@arm.com>
Fri, 2 Nov 2012 16:32:00 +0000 (11:32 -0500)
This patch ensures cases like %0.6u, %06f, and %.6u are processed correctly.
The case like %06f is ambiguous and was made to match printf.  Also, this patch
removes the goto statement in cprintf.cc in favor of a function call.

src/base/cprintf.cc
src/base/cprintf.hh

index 4f825c0976b384238a7d7ad24eddc9d10b3dc566..2dd2ab4866f3171f0c5979f0dca7d3ad8d6ca270 100644 (file)
@@ -69,9 +69,10 @@ Print::process()
     while (*ptr) {
         switch (*ptr) {
           case '%':
-            if (ptr[1] != '%')
-                goto processing;
-
+            if (ptr[1] != '%') {
+                process_flag();
+                return;
+            }
             stream.put('%');
             ptr += 2;
             break;
@@ -93,10 +94,11 @@ Print::process()
             break;
         }
     }
+}
 
-    return;
-
-  processing:
+void
+Print::process_flag()
+{
     bool done = false;
     bool end_number = false;
     bool have_precision = false;
@@ -248,7 +250,20 @@ Print::process()
             end_number = false;
             number = 0;
         }
-    }
+
+        if (done) {
+            if ((fmt.format == Format::integer) && have_precision) {
+                // specified a . but not a float, set width
+                fmt.width = fmt.precision;
+                // precision requries digits for width, must fill with 0
+                fmt.fill_zero = true;
+            } else if ((fmt.format == Format::floating) && !have_precision &&
+                        fmt.fill_zero) {
+                // ambiguous case, matching printf
+                fmt.precision = fmt.width;
+            }
+        }
+    } // end while
 
     ++ptr;
 }
index 6124d8c7330f856e7512fa2a18339fdd93eb5ab3..e702fa3a6ef06cc65301e0f51917e3f1895922c6 100644 (file)
@@ -59,6 +59,7 @@ struct Print
 
     Format fmt;
     void process();
+    void process_flag();
 
   public:
     Print(std::ostream &stream, const std::string &format);