about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-04-17 16:18:25 -0400
committerBrian Anderson <andersrb@gmail.com>2011-04-17 16:18:25 -0400
commit4c0aea69dab28a3e94d2c623ec741284f48e1205 (patch)
tree47cc3127e5369dae6f26c14a26a369a9e8a4d4fd /src
parentc7edcb3a72f3991962acce0874c2ee24a4f38cf5 (diff)
Support #fmt precision for unsigned types
Diffstat (limited to 'src')
-rw-r--r--src/lib/ExtFmt.rs60
-rw-r--r--src/test/run-pass/syntax-extension-fmt.rs32
2 files changed, 65 insertions, 27 deletions
diff --git a/src/lib/ExtFmt.rs b/src/lib/ExtFmt.rs
index af18a0d6d76..f8c542c65bd 100644
--- a/src/lib/ExtFmt.rs
+++ b/src/lib/ExtFmt.rs
@@ -336,19 +336,55 @@ mod RT {
     }
 
     fn conv_uint(&conv cv, uint u) -> str {
+
+        // Convert a uint to string with a minimum number of digits.  If
+        // precision is 0 and num is 0 then the result is the empty
+        // string. Could move this to _str, but it doesn't seem all that
+        // useful.
+        fn uint_to_str_prec(uint num, uint radix, uint prec) -> str {
+            auto s;
+
+            if (prec == 0u && num == 0u) {
+                s = "";
+            } else {
+                s = _uint.to_str(num, radix);
+                auto len = _str.char_len(s);
+                if (len < prec) {
+                    auto diff = prec - len;
+                    auto pad = str_init_elt('0', diff);
+                    s = pad + s;
+                }
+            }
+
+            ret s;
+        }
+
+        fn get_precision(&conv cv) -> uint {
+            alt (cv.precision) {
+                case (count_is(?c)) {
+                    ret c as uint;
+                }
+                case (count_implied) {
+                    ret 1u;
+                }
+            }
+        }
+
+        auto prec = get_precision(cv);
+
         auto res;
         alt (cv.ty) {
             case (ty_default) {
-                res = _uint.to_str(u, 10u);
+                res = uint_to_str_prec(u, 10u, prec);
             }
             case (ty_hex_lower) {
-                res = _uint.to_str(u, 16u);
+                res = uint_to_str_prec(u, 16u, prec);
             }
             case (ty_hex_upper) {
-                res = _str.to_upper(_uint.to_str(u, 16u));
+                res = _str.to_upper(uint_to_str_prec(u, 16u, prec));
             }
             case (ty_bits) {
-                res = _uint.to_str(u, 2u);
+                res = uint_to_str_prec(u, 2u, prec);
             }
         }
         ret pad(cv, res);
@@ -382,6 +418,14 @@ mod RT {
         ret pad(cv, unpadded);
     }
 
+    // FIXME: This might be useful in _str, but needs to be utf8 safe first
+    fn str_init_elt(char c, uint n_elts) -> str {
+        auto svec = _vec.init_elt[u8](c as u8, n_elts);
+        // FIXME: Using unsafe_from_bytes because rustboot
+        // can't figure out the is_utf8 predicate on from_bytes?
+        ret _str.unsafe_from_bytes(svec);
+    }
+
     fn pad(&conv cv, str s) -> str {
         alt (cv.width) {
             case (count_implied) {
@@ -393,13 +437,7 @@ mod RT {
                 auto strlen = _str.char_len(s);
                 if (strlen < uwidth) {
                     auto diff = uwidth - strlen;
-                    // FIXME: Probably should be a _str fn for
-                    // initializing from n chars
-                    auto padvec = _vec.init_elt[u8](' ' as u8, diff);
-                    // FIXME: Using unsafe_from_bytes because rustboot
-                    // can't figure out the is_utf8 predicate on from_bytes?
-                    auto padstr = _str.unsafe_from_bytes(padvec);
-
+                    auto padstr = str_init_elt(' ', diff);
                     if (have_flag(cv.flags, flag_left_justify)) {
                         ret s + padstr;
                     } else {
diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs
index abe3a30acf2..5c71a27b75b 100644
--- a/src/test/run-pass/syntax-extension-fmt.rs
+++ b/src/test/run-pass/syntax-extension-fmt.rs
@@ -56,38 +56,38 @@ fn main() {
 
   // Precision
 //   test(#fmt("%.d", 0), "");
-//   test(#fmt("%.u", 0u), "");
-//   test(#fmt("%.x", 0u), "");
+   test(#fmt("%.u", 0u), "");
+   test(#fmt("%.x", 0u), "");
 //   test(#fmt("%.d", 10), "10");
 //   test(#fmt("%.d", -10), "-10");
-//   test(#fmt("%.u", 10u), "10");
+   test(#fmt("%.u", 10u), "10");
    test(#fmt("%.s", "test"), "");
-//   test(#fmt("%.x", 127u), "7f");
+   test(#fmt("%.x", 127u), "7f");
 
 //   test(#fmt("%.0d", 0), "");
-//   test(#fmt("%.0u", 0u), "");
-//   test(#fmt("%.0x", 0u), "");
+   test(#fmt("%.0u", 0u), "");
+   test(#fmt("%.0x", 0u), "");
 //   test(#fmt("%.0d", 10), "10");
 //   test(#fmt("%.0d", -10), "-10");
-//   test(#fmt("%.0u", 10u), "10");
+   test(#fmt("%.0u", 10u), "10");
    test(#fmt("%.0s", "test"), "");
-//   test(#fmt("%.0x", 127u), "7f");
+   test(#fmt("%.0x", 127u), "7f");
 
 //   test(#fmt("%.1d", 0), "0");
-//   test(#fmt("%.1u", 0u), "0");
-//   test(#fmt("%.1x", 0u), "0");
+   test(#fmt("%.1u", 0u), "0");
+   test(#fmt("%.1x", 0u), "0");
 //   test(#fmt("%.1d", 10), "10");
 //   test(#fmt("%.1d", -10), "-10");
-//   test(#fmt("%.1u", 10u), "10");
+   test(#fmt("%.1u", 10u), "10");
    test(#fmt("%.1s", "test"), "t");
-//   test(#fmt("%.1x", 127u), "7f");
+   test(#fmt("%.1x", 127u), "7f");
 
 //   test(#fmt("%.5d", 0), "00000");
-//   test(#fmt("%.5u", 0u), "00000");
-//   test(#fmt("%.5x", 0u), "00000");
+   test(#fmt("%.5u", 0u), "00000");
+   test(#fmt("%.5x", 0u), "00000");
 //   test(#fmt("%.5d", 10), "00010");
 //   test(#fmt("%.5d", -10), "-00010");
-//   test(#fmt("%.5u", 10u), "00010");
+   test(#fmt("%.5u", 10u), "00010");
    test(#fmt("%.5s", "test"), "test");
-//   test(#fmt("%.5x", 127u), "0007f");
+   test(#fmt("%.5x", 127u), "0007f");
 }