about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-04-17 13:10:02 -0400
committerBrian Anderson <andersrb@gmail.com>2011-04-17 13:10:02 -0400
commitc7edcb3a72f3991962acce0874c2ee24a4f38cf5 (patch)
tree7e0f3a79abea51f31a46e105970fe1fd5e074af7
parent96e3e29e88fa877aa087b616a58b3492b036ee85 (diff)
downloadrust-c7edcb3a72f3991962acce0874c2ee24a4f38cf5.tar.gz
rust-c7edcb3a72f3991962acce0874c2ee24a4f38cf5.zip
Support #fmt precision for string types
-rw-r--r--src/comp/front/extfmt.rs10
-rw-r--r--src/lib/ExtFmt.rs27
-rw-r--r--src/test/run-pass/syntax-extension-fmt.rs37
3 files changed, 70 insertions, 4 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index 241e71a8b94..3aa24a90fe6 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -234,18 +234,22 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
         fn make_conv_rec(common.span sp,
                          @ast.expr flags_expr,
                          @ast.expr width_expr,
+                         @ast.expr precision_expr,
                          @ast.expr ty_expr) -> @ast.expr {
             ret make_rec_expr(sp, vec(tup("flags", flags_expr),
                                       tup("width", width_expr),
+                                      tup("precision", precision_expr),
                                       tup("ty", ty_expr)));
         }
 
         auto rt_conv_flags = make_flags(sp, cnv.flags);
         auto rt_conv_width = make_count(sp, cnv.width);
+        auto rt_conv_precision = make_count(sp, cnv.precision);
         auto rt_conv_ty = make_ty(sp, cnv.ty);
         ret make_conv_rec(sp,
                           rt_conv_flags,
                           rt_conv_width,
+                          rt_conv_precision,
                           rt_conv_ty);
     }
 
@@ -296,6 +300,8 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
         alt (cnv.precision) {
             case (count_implied) {
             }
+            case (count_is(_)) {
+            }
             case (_) {
                 log unsupported;
                 fail;
@@ -444,8 +450,8 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
                 }
 
                 // TODO: Remove debug logging
-                // log "Building conversion:";
-                // log_conv(conv);
+                //log "Building conversion:";
+                //log_conv(conv);
 
                 n += 1u;
                 auto arg_expr = args.(n);
diff --git a/src/lib/ExtFmt.rs b/src/lib/ExtFmt.rs
index 432e936f65f..af18a0d6d76 100644
--- a/src/lib/ExtFmt.rs
+++ b/src/lib/ExtFmt.rs
@@ -246,7 +246,17 @@ mod CT {
         }
 
         if (s.(i) == '.' as u8) {
-            ret parse_count(s, i + 1u, lim);
+            auto count = parse_count(s, i + 1u, lim);
+            // If there were no digits specified, i.e. the precision
+            // was ".", then the precision is 0
+            alt (count._0) {
+                case (count_implied) {
+                    ret tup(count_is(0), count._1);
+                }
+                case (_) {
+                    ret count;
+                }
+            }
         } else {
             ret tup(count_implied, i);
         }
@@ -318,6 +328,7 @@ mod RT {
     // instead just use a bool per flag
     type conv = rec(vec[flag] flags,
                     count width,
+                    count precision,
                     ty ty);
 
     fn conv_int(&conv cv, int i) -> str {
@@ -356,7 +367,19 @@ mod RT {
     }
 
     fn conv_str(&conv cv, str s) -> str {
-        ret pad(cv, s);
+        auto unpadded = s;
+        alt (cv.precision) {
+            case (count_implied) {
+            }
+            case (count_is(?max)) {
+                // For strings, precision is the maximum characters displayed
+                if (max as uint < _str.char_len(s)) {
+                    // FIXME: substr works on bytes, not chars!
+                    unpadded = _str.substr(s, 0u, max as uint);
+                }
+            }
+        }
+        ret pad(cv, unpadded);
     }
 
     fn pad(&conv cv, str s) -> str {
diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs
index 2ffea946bc2..abe3a30acf2 100644
--- a/src/test/run-pass/syntax-extension-fmt.rs
+++ b/src/test/run-pass/syntax-extension-fmt.rs
@@ -53,4 +53,41 @@ fn main() {
   test(#fmt("%-10x", 0xff_u), "ff        ");
   test(#fmt("%-10X", 0xff_u), "FF        ");
   test(#fmt("%-10t", 0xff_u), "11111111  ");
+
+  // Precision
+//   test(#fmt("%.d", 0), "");
+//   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("%.s", "test"), "");
+//   test(#fmt("%.x", 127u), "7f");
+
+//   test(#fmt("%.0d", 0), "");
+//   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("%.0s", "test"), "");
+//   test(#fmt("%.0x", 127u), "7f");
+
+//   test(#fmt("%.1d", 0), "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("%.1s", "test"), "t");
+//   test(#fmt("%.1x", 127u), "7f");
+
+//   test(#fmt("%.5d", 0), "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("%.5s", "test"), "test");
+//   test(#fmt("%.5x", 127u), "0007f");
 }