Support #fmt precision for string types

This commit is contained in:
Brian Anderson 2011-04-17 13:10:02 -04:00
parent 96e3e29e88
commit c7edcb3a72
3 changed files with 70 additions and 4 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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");
}