Address FIXMEs in extfmt / add issue numbers

This commit is contained in:
Tim Chevalier 2012-03-15 17:45:38 -07:00
parent ce3f369047
commit 20ec72830a
2 changed files with 35 additions and 29 deletions

View file

@ -53,7 +53,7 @@ mod ct {
ty_octal, ty_octal,
ty_float, ty_float,
ty_poly, ty_poly,
// FIXME: More types // FIXME: More types (Issue #1992)
} }
enum flag { enum flag {
flag_left_justify, flag_left_justify,
@ -275,31 +275,32 @@ mod rt {
// FIXME: This is a hack to avoid creating 0-length vec exprs, // FIXME: This is a hack to avoid creating 0-length vec exprs,
// which have some difficulty typechecking currently. See // which have some difficulty typechecking currently. See
// comments in front::extfmt::make_flags // comments in front::extfmt::make_flags
// (once #1993 is addressed, this won't be necessary)
flag_none, flag_none,
} }
enum count { count_is(int), count_implied, } enum count { count_is(int), count_implied, }
enum ty { ty_default, ty_bits, ty_hex_upper, ty_hex_lower, ty_octal, } enum ty { ty_default, ty_bits, ty_hex_upper, ty_hex_lower, ty_octal, }
// FIXME: May not want to use a vector here for flags; // FIXME: May not want to use a vector here for flags;
// instead just use a bool per flag // instead just use a bool per flag (see Issue #1993)
type conv = {flags: [flag], width: count, precision: count, ty: ty}; type conv = {flags: [flag], width: count, precision: count, ty: ty};
fn conv_int(cv: conv, i: int) -> str { fn conv_int(cv: conv, i: int) -> str {
let radix = 10u; let radix = 10u;
let prec = get_int_precision(cv); let prec = get_int_precision(cv);
let mut s = int_to_str_prec(i, radix, prec); let mut s : str = int_to_str_prec(i, radix, prec);
if 0 <= i { if 0 <= i {
if have_flag(cv.flags, flag_sign_always) { if have_flag(cv.flags, flag_sign_always) {
s = "+" + s; str::unshift_char(s, '+');
} else if have_flag(cv.flags, flag_space_for_sign) { } else if have_flag(cv.flags, flag_space_for_sign) {
s = " " + s; str::unshift_char(s, ' ');
} }
} }
ret pad(cv, s, pad_signed); ret pad(cv, s, pad_signed);
} }
fn conv_uint(cv: conv, u: uint) -> str { fn conv_uint(cv: conv, u: uint) -> str {
let prec = get_int_precision(cv); let prec = get_int_precision(cv);
let rs = let mut rs =
alt cv.ty { alt cv.ty {
ty_default { uint_to_str_prec(u, 10u, prec) } ty_default { uint_to_str_prec(u, 10u, prec) }
ty_hex_lower { uint_to_str_prec(u, 16u, prec) } ty_hex_lower { uint_to_str_prec(u, 16u, prec) }
@ -317,12 +318,13 @@ mod rt {
ret conv_str(cv, s); ret conv_str(cv, s);
} }
fn conv_char(cv: conv, c: char) -> str { fn conv_char(cv: conv, c: char) -> str {
ret pad(cv, str::from_char(c), pad_nozero); let mut s = str::from_char(c);
ret pad(cv, s, pad_nozero);
} }
fn conv_str(cv: conv, s: str) -> str unsafe { fn conv_str(cv: conv, s: str) -> str unsafe {
// For strings, precision is the maximum characters // For strings, precision is the maximum characters
// displayed // displayed
let unpadded = alt cv.precision { let mut unpadded = alt cv.precision {
count_implied { s } count_implied { s }
count_is(max) { count_is(max) {
if max as uint < str::char_len(s) { if max as uint < str::char_len(s) {
@ -371,7 +373,7 @@ mod rt {
let len = str::char_len(s); let len = str::char_len(s);
if len < prec { if len < prec {
let diff = prec - len; let diff = prec - len;
let pad = str_init_elt(diff, '0'); let pad = str::init_elt(diff, '0');
pad + s pad + s
} else { s } } else { s }
}; };
@ -382,20 +384,13 @@ mod rt {
count_implied { 1u } count_implied { 1u }
}; };
} }
// FIXME: This might be useful in str: but needs to be utf8 safe first
fn str_init_elt(n_elts: uint, c: char) -> str {
let svec = vec::from_elem::<u8>(n_elts, c as u8);
ret str::from_bytes(svec);
}
enum pad_mode { pad_signed, pad_unsigned, pad_nozero, } enum pad_mode { pad_signed, pad_unsigned, pad_nozero, }
fn pad(cv: conv, s: str, mode: pad_mode) -> str unsafe { fn pad(cv: conv, &s: str, mode: pad_mode) -> str unsafe {
let uwidth = alt cv.width { let uwidth : uint = alt cv.width {
count_implied { ret s; } count_implied { ret s; }
count_is(width) { count_is(width) {
// FIXME: Maybe width should be uint // FIXME: width should probably be uint (see Issue #1996)
width as uint width as uint
} }
}; };
let strlen = str::char_len(s); let strlen = str::char_len(s);
@ -403,7 +398,7 @@ mod rt {
let mut padchar = ' '; let mut padchar = ' ';
let diff = uwidth - strlen; let diff = uwidth - strlen;
if have_flag(cv.flags, flag_left_justify) { if have_flag(cv.flags, flag_left_justify) {
let padstr = str_init_elt(diff, padchar); let padstr = str::init_elt(diff, padchar);
ret s + padstr; ret s + padstr;
} }
let {might_zero_pad, signed} = alt mode { let {might_zero_pad, signed} = alt mode {
@ -423,20 +418,20 @@ mod rt {
false false
} }
}; };
let padstr = str_init_elt(diff, padchar); let padstr = str::init_elt(diff, padchar);
// This is completely heinous. If we have a signed value then // This is completely heinous. If we have a signed value then
// potentially rip apart the intermediate result and insert some // potentially rip apart the intermediate result and insert some
// zeros. It may make sense to convert zero padding to a precision // zeros. It may make sense to convert zero padding to a precision
// instead. // instead.
if signed && zero_padding && str::len(s) > 0u { if signed && zero_padding && str::len(s) > 0u {
let head = s[0]; let head = str::shift_char(s);
if head == '+' as u8 || head == '-' as u8 || head == ' ' as u8 { if head == '+' || head == '-' || head == ' ' {
let headstr = str::from_bytes([head]); let headstr = str::init_elt(1u, head);
// FIXME: not UTF-8 safe ret headstr + padstr + s;
let bytelen = str::len(s); }
let numpart = str::slice(s, 1u, bytelen); else {
ret headstr + padstr + numpart; str::unshift_char(s, head);
} }
} }
ret padstr + s; ret padstr + s;

View file

@ -20,6 +20,7 @@ export
push_char, push_char,
concat, concat,
connect, connect,
init_elt,
// Reinterpretation // Reinterpretation
as_bytes, as_bytes,
@ -240,6 +241,16 @@ fn connect(v: [str], sep: str) -> str {
ret s; ret s;
} }
#[doc = "Returns a string of <n_elts> repetitions of <c>, which must be \
UTF-8"]
fn init_elt(n_elts: uint, c: char) -> str {
let mut rslt = "";
uint::range(0u, n_elts) {|_i|
push_char(rslt, c);
}
rslt
}
/* /*
Section: Adding to and removing from a string Section: Adding to and removing from a string
*/ */