}
}
- priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
+#[cfg(stage0)]
+ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
let mut s = match val {
Number(d) => {
match op {
String(s) => {
match op {
FormatString => {
- let mut s = s.to_bytes_with_null();
- s.pop(); // remove the null
+ let mut s = s.as_bytes().to_owned();
+ if flags.precision > 0 && flags.precision < s.len() {
+ s.truncate(flags.precision);
+ }
+ s
+ }
+ _ => {
+ return Err(fmt!("non-string on stack with %%%c", op.to_char()))
+ }
+ }
+ }
+ };
+ if flags.width > s.len() {
+ let n = flags.width - s.len();
+ if flags.left {
+ s.grow(n, &(' ' as u8));
+ } else {
+ let mut s_ = vec::with_capacity(flags.width);
+ s_.grow(n, &(' ' as u8));
+ s_.push_all_move(s);
+ s = s_;
+ }
+ }
+ Ok(s)
+}
+
+#[cfg(not(stage0))]
- priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
++fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
+ let mut s = match val {
+ Number(d) => {
+ match op {
+ FormatString => {
+ return Err(~"non-number on stack with %s")
+ }
+ _ => {
+ let radix = match op {
+ FormatDigit => 10,
+ FormatOctal => 8,
+ FormatHex|FormatHEX => 16,
+ FormatString => util::unreachable()
+ };
+ let mut s = ~[];
+ match op {
+ FormatDigit => {
+ let sign = if flags.sign { SignAll } else { SignNeg };
+ do int_to_str_bytes_common(d, radix, sign) |c| {
+ s.push(c);
+ }
+ }
+ _ => {
+ do int_to_str_bytes_common(d as uint, radix, SignNone) |c| {
+ s.push(c);
+ }
+ }
+ };
+ if flags.precision > s.len() {
+ let mut s_ = vec::with_capacity(flags.precision);
+ let n = flags.precision - s.len();
+ s_.grow(n, &('0' as u8));
+ s_.push_all_move(s);
+ s = s_;
+ }
+ assert!(!s.is_empty(), "string conversion produced empty result");
+ match op {
+ FormatDigit => {
+ if flags.space && !(s[0] == '-' as u8 || s[0] == '+' as u8) {
+ s.unshift(' ' as u8);
+ }
+ }
+ FormatOctal => {
+ if flags.alternate && s[0] != '0' as u8 {
+ s.unshift('0' as u8);
+ }
+ }
+ FormatHex => {
+ if flags.alternate {
+ let s_ = util::replace(&mut s, ~['0' as u8, 'x' as u8]);
+ s.push_all_move(s_);
+ }
+ }
+ FormatHEX => {
+ s = s.into_ascii().to_upper().into_bytes();
+ if flags.alternate {
+ let s_ = util::replace(&mut s, ~['0' as u8, 'X' as u8]);
+ s.push_all_move(s_);
+ }
+ }
+ FormatString => util::unreachable()
+ }
+ s
+ }
+ }
+ }
+ String(s) => {
+ match op {
+ FormatString => {
+ let mut s = s.as_bytes().to_owned();
if flags.precision > 0 && flags.precision < s.len() {
s.truncate(flags.precision);
}