From 40d01d9d57c52bbef54bf68b97f63de044f9fd0a Mon Sep 17 00:00:00 2001 From: jD91mZM2 <me@krake.one> Date: Mon, 22 Apr 2019 16:25:29 +0200 Subject: [PATCH] Convert printf internals to iterator --- include.sh | 18 +- src/header/stdio/printf.rs | 603 ++++++++++++++++++++++--------------- src/platform/redox/mod.rs | 2 - 3 files changed, 377 insertions(+), 246 deletions(-) diff --git a/include.sh b/include.sh index 16d265a2..c6821291 100755 --- a/include.sh +++ b/include.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +SUPRESS_ALL_THE_ERRORS=yes + set -e include="$(realpath "$1")" @@ -7,6 +9,10 @@ include="$(realpath "$1")" cargo build --release --manifest-path cbindgen/Cargo.toml cbindgen="$(realpath target/release/cbindgen)" +if [ "$SUPRESS_ALL_THE_ERRORS" = "yes" ]; then + echo -e "\e[91mNote: Warnings by cbindgen are suppressed in include.sh.\e[0m" +fi + jobs=() for config in src/header/*/cbindgen.toml do @@ -15,10 +21,16 @@ do if [ "${name:0:1}" != "_" ] then header="$include/${name/_//}.h" - pushd "$dir" - "$cbindgen" -c cbindgen.toml -o "$header" mod.rs & + pushd "$dir" > /dev/null + echo "$dir" + cbindgen_cmd='"$cbindgen" -c cbindgen.toml -o "$header" mod.rs' + if [ "$SUPRESS_ALL_THE_ERRORS" = "yes" ]; then + eval "$cbindgen_cmd" 2>&1 | (grep "^ERROR" -A 3 || true) & + else + eval "$cbindgen_cmd" & + fi jobs+=($!) - popd + popd > /dev/null fi done diff --git a/src/header/stdio/printf.rs b/src/header/stdio/printf.rs index e41f24b3..1c9dcb01 100644 --- a/src/header/stdio/printf.rs +++ b/src/header/stdio/printf.rs @@ -20,8 +20,37 @@ enum IntKind { PtrDiff, Size, } +enum FmtKind { + Percent, -enum ArgType { + Signed, + Unsigned, + + Scientific, + Decimal, + AnyNotation, + + String, + Char, + Pointer, + GetWritten +} +#[derive(Clone, Copy, Debug)] +enum Number { + Static(usize), + Index(usize), + Next +} +impl Number { + unsafe fn resolve(&self, ap: &mut BufferedVaList) -> usize { + match *self { + Number::Static(num) => num, + Number::Index(i) => ap.index(ArgKind::Int, i).int as usize, + Number::Next => ap.next(ArgKind::Int).int as usize, + } + } +} +enum ArgKind { Byte, Short, Int, @@ -69,58 +98,58 @@ impl<'a> BufferedVaList<'a> { } } - unsafe fn get_arg(&mut self, ty: ArgType) -> VaArg { + unsafe fn get_arg(&mut self, ty: ArgKind) -> VaArg { match ty { - ArgType::Byte => VaArg { + ArgKind::Byte => VaArg { byte: self.list.arg::<c_char>(), }, - ArgType::Short => VaArg { + ArgKind::Short => VaArg { short: self.list.arg::<c_short>(), }, - ArgType::Int => VaArg { + ArgKind::Int => VaArg { int: self.list.arg::<c_int>(), }, - ArgType::Long => VaArg { + ArgKind::Long => VaArg { long: self.list.arg::<c_long>(), }, - ArgType::LongLong => VaArg { + ArgKind::LongLong => VaArg { longlong: self.list.arg::<c_longlong>(), }, - ArgType::PtrDiff => VaArg { + ArgKind::PtrDiff => VaArg { ptrdiff: self.list.arg::<ptrdiff_t>(), }, - ArgType::Size => VaArg { + ArgKind::Size => VaArg { size: self.list.arg::<ssize_t>(), }, - ArgType::IntMax => VaArg { + ArgKind::IntMax => VaArg { intmax: self.list.arg::<intmax_t>(), }, - ArgType::Double => VaArg { + ArgKind::Double => VaArg { double: self.list.arg::<c_double>(), }, - ArgType::CharPtr => VaArg { + ArgKind::CharPtr => VaArg { char_ptr: self.list.arg::<*const c_char>(), }, - ArgType::VoidPtr => VaArg { + ArgKind::VoidPtr => VaArg { void_ptr: self.list.arg::<*const c_void>(), }, - ArgType::IntPtr => VaArg { + ArgKind::IntPtr => VaArg { int_ptr: self.list.arg::<*mut c_int>(), }, - ArgType::ArgDefault => VaArg { + ArgKind::ArgDefault => VaArg { arg_default: self.list.arg::<usize>(), }, } } - unsafe fn get(&mut self, ty: ArgType, i: Option<usize>) -> VaArg { + unsafe fn get(&mut self, ty: ArgKind, i: Option<usize>) -> VaArg { match i { None => self.next(ty), Some(i) => self.index(ty, i), } } - unsafe fn next(&mut self, ty: ArgType) -> VaArg { + unsafe fn next(&mut self, ty: ArgKind) -> VaArg { if self.i >= self.buf.len() { let arg = self.get_arg(ty); self.buf.push(arg); @@ -130,7 +159,7 @@ impl<'a> BufferedVaList<'a> { arg } - unsafe fn index(&mut self, ty: ArgType, i: usize) -> VaArg { + unsafe fn index(&mut self, ty: ArgKind, i: usize) -> VaArg { if self.i >= self.buf.len() { while self.buf.len() < (i - 1) { // Getting a usize here most definitely isn't sane, however, @@ -142,7 +171,7 @@ impl<'a> BufferedVaList<'a> { // This chooses the width 10. How does it know the type of 0 and "hello"? // It clearly can't. - let arg = self.get_arg(ArgType::ArgDefault); + let arg = self.get_arg(ArgKind::ArgDefault); self.buf.push(arg); } let arg = self.get_arg(ty); @@ -155,7 +184,7 @@ impl<'a> BufferedVaList<'a> { unsafe fn pop_int_raw(format: &mut *const u8) -> Option<usize> { let mut int = None; while let Some(digit) = (**format as char).to_digit(10) { - *format = format.offset(1); + *format = format.add(1); if int.is_none() { int = Some(0); } @@ -164,23 +193,27 @@ unsafe fn pop_int_raw(format: &mut *const u8) -> Option<usize> { } int } - -unsafe fn pop_int(format: &mut *const u8, ap: &mut BufferedVaList) -> Option<usize> { - if **format == b'*' { - *format = format.offset(1); - - // Peek ahead for a positional argument: - let mut format2 = *format; - if let Some(i) = pop_int_raw(&mut format2) { - if *format2 == b'$' { - *format = format2.offset(1); - return Some(ap.index(ArgType::ArgDefault, i).arg_default); - } +unsafe fn pop_index(format: &mut *const u8) -> Option<usize> { + // Peek ahead for a positional argument: + let mut format2 = *format; + if let Some(i) = pop_int_raw(&mut format2) { + if *format2 == b'$' { + *format = format2.add(1); + return Some(i); } - - Some(ap.next(ArgType::ArgDefault).arg_default) + } + None +} +unsafe fn pop_int(format: &mut *const u8) -> Option<Number> { + if **format == b'*' { + *format = format.add(1); + Some( + pop_index(format) + .map(Number::Index) + .unwrap_or(Number::Next) + ) } else { - pop_int_raw(format) + pop_int_raw(format).map(Number::Static) } } @@ -193,7 +226,7 @@ where b'u' => i.to_string(), b'x' => format!("{:x}", i), b'X' => format!("{:X}", i), - _ => panic!("fmt_int should never be called with the fmt {}", fmt), + _ => panic!("fmt_int should never be called with the fmt {:?}", fmt as char), } } @@ -305,26 +338,57 @@ fn fmt_float_normal<W: Write>( Ok(string.len()) } -unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: va_list) -> io::Result<c_int> { - let w = &mut platform::CountingWriter::new(w); - let mut ap = BufferedVaList::new(ap); - let mut format = format as *const u8; - - while *format != 0 { - if *format != b'%' { - w.write_all(&[*format])?; - } else { - format = format.offset(1); - - // Peek ahead to maybe specify argument to fetch from - let mut index = None; - let mut format2 = format; - if let Some(i) = pop_int_raw(&mut format2) { - if *format2 == b'$' { - format = format2.offset(1); - index = Some(i); - } +#[derive(Clone, Copy)] +struct PrintfIter { + format: *const u8 +} +struct PrintfArg { + index: Option<usize>, + alternate: bool, + zero: bool, + left: bool, + sign_reserve: bool, + sign_always: bool, + min_width: Number, + precision: Option<Number>, + pad_space: Number, + pad_zero: Number, + intkind: IntKind, + fmt: u8, + fmtkind: FmtKind +} +enum PrintfFmt { + Plain(&'static [u8]), + Arg(PrintfArg) +} +impl Iterator for PrintfIter { + type Item = Result<PrintfFmt, ()>; + fn next(&mut self) -> Option<Self::Item> { + unsafe { + // Send PrintfFmt::Plain until the next % + let mut len = 0; + while *self.format.add(len) != 0 && *self.format.add(len) != b'%' { + len += 1; + } + if len > 0 { + let slice = slice::from_raw_parts(self.format as *const u8, len); + self.format = self.format.add(len); + return Some(Ok(PrintfFmt::Plain(slice))); } + self.format = self.format.add(len); + if *self.format == 0 { + return None; + } + + // *self.format is guaranteed to be '%' at this point + self.format = self.format.add(1); + + let mut peekahead = self.format; + let index = pop_index(&mut peekahead) + .map(|i| { + self.format = peekahead; + i + }); // Flags: let mut alternate = false; @@ -334,7 +398,7 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: va_list) -> io let mut sign_always = false; loop { - match *format { + match *self.format { b'#' => alternate = true, b'0' => zero = true, b'-' => left = true, @@ -342,30 +406,30 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: va_list) -> io b'+' => sign_always = true, _ => break, } - format = format.offset(1); + self.format = self.format.add(1); } // Width and precision: - let min_width = pop_int(&mut format, &mut ap).unwrap_or(0); - let precision = if *format == b'.' { - format = format.offset(1); - match pop_int(&mut format, &mut ap) { + let min_width = pop_int(&mut self.format).unwrap_or(Number::Static(0)); + let precision = if *self.format == b'.' { + self.format = self.format.add(1); + match pop_int(&mut self.format) { int @ Some(_) => int, - None => return Ok(-1), + None => return Some(Err(())), } } else { None }; - let pad_space = if zero { 0 } else { min_width }; - let pad_zero = if zero { min_width } else { 0 }; + let pad_space = if zero { Number::Static(0) } else { min_width }; + let pad_zero = if zero { min_width } else { Number::Static(0) }; // Integer size: - let mut kind = IntKind::Int; + let mut intkind = IntKind::Int; loop { - kind = match *format { + intkind = match *self.format { b'h' => { - if kind == IntKind::Short || kind == IntKind::Byte { + if intkind == IntKind::Short || intkind == IntKind::Byte { IntKind::Byte } else { IntKind::Short @@ -373,7 +437,7 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: va_list) -> io } b'j' => IntKind::IntMax, b'l' => { - if kind == IntKind::Long || kind == IntKind::LongLong { + if intkind == IntKind::Long || intkind == IntKind::LongLong { IntKind::LongLong } else { IntKind::Long @@ -385,213 +449,270 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: va_list) -> io _ => break, }; - format = format.offset(1); + self.format = self.format.add(1); } + let fmt = *self.format; + let fmtkind = match fmt { + b'%' => FmtKind::Percent, + b'd' | b'i' => FmtKind::Signed, + b'o' | b'u' | b'x' | b'X' => FmtKind::Unsigned, + b'e' | b'E' => FmtKind::Scientific, + b'f' | b'F' => FmtKind::Decimal, + b'g' | b'G' => FmtKind::AnyNotation, + b's' => FmtKind::String, + b'c' => FmtKind::Char, + b'p' => FmtKind::Pointer, + b'n' => FmtKind::GetWritten, + _ => return Some(Err(())), + }; + self.format = self.format.add(1); + + Some(Ok(PrintfFmt::Arg(PrintfArg { + index, + alternate, + zero, + left, + sign_reserve, + sign_always, + min_width, + precision, + pad_space, + pad_zero, + intkind, + fmt, + fmtkind + }))) + } + } +} - // Finally, type: - match *format { - b'%' => w.write_all(&[b'%'])?, - b'd' | b'i' => { - let string = match kind { - // Per the C standard using va_arg with a type with a size - // less than that of an int for integers and double for floats - // is invalid. As a result any arguments smaller than an int or - // double passed to a function will be promoted to the smallest - // possible size. The va_list::arg function will handle this - // automagically. - IntKind::Byte => ap.get(ArgType::Byte, index).byte.to_string(), - IntKind::Short => ap.get(ArgType::Short, index).short.to_string(), - // Types that will not be promoted - IntKind::Int => ap.get(ArgType::Int, index).int.to_string(), - IntKind::Long => ap.get(ArgType::Long, index).long.to_string(), - IntKind::LongLong => ap.get(ArgType::LongLong, index).longlong.to_string(), - IntKind::PtrDiff => ap.get(ArgType::PtrDiff, index).ptrdiff.to_string(), - IntKind::Size => ap.get(ArgType::Size, index).size.to_string(), - IntKind::IntMax => ap.get(ArgType::IntMax, index).intmax.to_string(), - }; - let positive = !string.starts_with('-'); - let zero = precision == Some(0) && string == "0"; +unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, ap: va_list) -> io::Result<c_int> { + let w = &mut platform::CountingWriter::new(w); + let mut ap = BufferedVaList::new(ap); - let mut len = string.len(); - let mut final_len = string.len().max(precision.unwrap_or(0)); - if positive && (sign_reserve || sign_always) { - final_len += 1; - } - if zero { - len = 0; - final_len = 0; - } + let iterator = PrintfIter { + format: format as *const u8 + }; - pad(w, !left, b' ', final_len..pad_space)?; + for section in iterator { + let arg = match section { + Ok(PrintfFmt::Plain(text)) => { + w.write_all(text)?; + continue; + }, + Ok(PrintfFmt::Arg(arg)) => arg, + Err(()) => return Ok(-1) + }; + let index = arg.index; + let alternate = arg.alternate; + let zero = arg.zero; + let left = arg.left; + let sign_reserve = arg.sign_reserve; + let sign_always = arg.sign_always; + let min_width = arg.min_width.resolve(&mut ap); + let precision = arg.precision.map(|n| n.resolve(&mut ap)); + let pad_space = arg.pad_space.resolve(&mut ap); + let pad_zero = arg.pad_zero.resolve(&mut ap); + let intkind = arg.intkind; + let fmt = arg.fmt; + let fmtkind = arg.fmtkind; + + // Finally, type: + match fmtkind { + FmtKind::Percent => w.write_all(&[b'%'])?, + FmtKind::Signed => { + let string = match intkind { + // Per the C standard using va_arg with a type with a size + // less than that of an int for integers and double for floats + // is invalid. As a result any arguments smaller than an int or + // double passed to a function will be promoted to the smallest + // possible size. The va_list::arg function will handle this + // automagically. + IntKind::Byte => ap.get(ArgKind::Byte, index).byte.to_string(), + IntKind::Short => ap.get(ArgKind::Short, index).short.to_string(), + // Types that will not be promoted + IntKind::Int => ap.get(ArgKind::Int, index).int.to_string(), + IntKind::Long => ap.get(ArgKind::Long, index).long.to_string(), + IntKind::LongLong => ap.get(ArgKind::LongLong, index).longlong.to_string(), + IntKind::PtrDiff => ap.get(ArgKind::PtrDiff, index).ptrdiff.to_string(), + IntKind::Size => ap.get(ArgKind::Size, index).size.to_string(), + IntKind::IntMax => ap.get(ArgKind::IntMax, index).intmax.to_string(), + }; + let positive = !string.starts_with('-'); + let zero = precision == Some(0) && string == "0"; - let bytes = if positive { - if sign_reserve { - w.write_all(&[b' '])?; - } else if sign_always { - w.write_all(&[b'+'])?; - } - string.as_bytes() - } else { - w.write_all(&[b'-'])?; - &string.as_bytes()[1..] - }; - pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?; + let mut len = string.len(); + let mut final_len = string.len().max(precision.unwrap_or(0)); + if positive && (sign_reserve || sign_always) { + final_len += 1; + } + if zero { + len = 0; + final_len = 0; + } + + pad(w, !left, b' ', final_len..pad_space)?; - if !zero { - w.write_all(bytes)?; + let bytes = if positive { + if sign_reserve { + w.write_all(&[b' '])?; + } else if sign_always { + w.write_all(&[b'+'])?; } + string.as_bytes() + } else { + w.write_all(&[b'-'])?; + &string.as_bytes()[1..] + }; + pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?; - pad(w, left, b' ', final_len..pad_space)?; + if !zero { + w.write_all(bytes)?; } - b'o' | b'u' | b'x' | b'X' => { - let fmt = *format; - let string = match kind { - // va_list will promote the following two to a c_int - IntKind::Byte => fmt_int(fmt, ap.get(ArgType::Byte, index).byte), - IntKind::Short => fmt_int(fmt, ap.get(ArgType::Short, index).short), - IntKind::Int => fmt_int(fmt, ap.get(ArgType::Int, index).int), - IntKind::Long => fmt_int(fmt, ap.get(ArgType::Long, index).long), - IntKind::LongLong => { - fmt_int(fmt, ap.get(ArgType::LongLong, index).longlong) - } - IntKind::PtrDiff => fmt_int(fmt, ap.get(ArgType::PtrDiff, index).ptrdiff), - IntKind::Size => fmt_int(fmt, ap.get(ArgType::Size, index).size), - IntKind::IntMax => fmt_int(fmt, ap.get(ArgType::IntMax, index).intmax), - }; - let zero = precision == Some(0) && string == "0"; - - // If this int is padded out to be larger than it is, don't - // add an extra zero if octal. - let no_precision = precision.map(|pad| pad < string.len()).unwrap_or(true); - - let mut len = string.len(); - let mut final_len = string.len().max(precision.unwrap_or(0)) - + if alternate && string != "0" { - match fmt { - b'o' if no_precision => 1, - b'x' | b'X' => 2, - _ => 0, - } - } else { - 0 - }; - if zero { - len = 0; - final_len = 0; + pad(w, left, b' ', final_len..pad_space)?; + }, + FmtKind::Unsigned => { + let string = match intkind { + // va_list will promote the following two to a c_int + IntKind::Byte => fmt_int(fmt, ap.get(ArgKind::Byte, index).byte), + IntKind::Short => fmt_int(fmt, ap.get(ArgKind::Short, index).short), + IntKind::Int => fmt_int(fmt, ap.get(ArgKind::Int, index).int), + IntKind::Long => fmt_int(fmt, ap.get(ArgKind::Long, index).long), + IntKind::LongLong => { + fmt_int(fmt, ap.get(ArgKind::LongLong, index).longlong) } + IntKind::PtrDiff => fmt_int(fmt, ap.get(ArgKind::PtrDiff, index).ptrdiff), + IntKind::Size => fmt_int(fmt, ap.get(ArgKind::Size, index).size), + IntKind::IntMax => fmt_int(fmt, ap.get(ArgKind::IntMax, index).intmax), + }; + let zero = precision == Some(0) && string == "0"; - pad(w, !left, b' ', final_len..pad_space)?; + // If this int is padded out to be larger than it is, don't + // add an extra zero if octal. + let no_precision = precision.map(|pad| pad < string.len()).unwrap_or(true); - if alternate && string != "0" { + let mut len = string.len(); + let mut final_len = string.len().max(precision.unwrap_or(0)) + + if alternate && string != "0" { match fmt { - b'o' if no_precision => w.write_all(&[b'0'])?, - b'x' => w.write_all(&[b'0', b'x'])?, - b'X' => w.write_all(&[b'0', b'X'])?, - _ => (), + b'o' if no_precision => 1, + b'x' | b'X' => 2, + _ => 0, } - } - pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?; - - if !zero { - w.write_all(string.as_bytes())?; - } + } else { + 0 + }; - pad(w, left, b' ', final_len..pad_space)?; + if zero { + len = 0; + final_len = 0; } - b'e' | b'E' => { - let exp_fmt = *format; - let mut float = ap.get(ArgType::Double, index).double; - let precision = precision.unwrap_or(6); - - fmt_float_exp( - w, exp_fmt, None, false, precision, float, left, pad_space, pad_zero, - )?; - } - b'f' | b'F' => { - let mut float = ap.get(ArgType::Double, index).double; - let precision = precision.unwrap_or(6); - fmt_float_normal(w, false, precision, float, left, pad_space, pad_zero)?; - } - b'g' | b'G' => { - let exp_fmt = b'E' | (*format & 32); - let mut float = ap.get(ArgType::Double, index).double; - let precision = precision.unwrap_or(6); - - if !fmt_float_exp( - w, - exp_fmt, - Some((-4, precision as isize)), - true, - precision, - float, - left, - pad_space, - pad_zero, - )? { - fmt_float_normal(w, true, precision, float, left, pad_space, pad_zero)?; + pad(w, !left, b' ', final_len..pad_space)?; + + if alternate && string != "0" { + match fmt { + b'o' if no_precision => w.write_all(&[b'0'])?, + b'x' => w.write_all(&[b'0', b'x'])?, + b'X' => w.write_all(&[b'0', b'X'])?, + _ => (), } } - b's' => { - // if kind == IntKind::Long || kind == IntKind::LongLong, handle *const wchar_t + pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?; - let ptr = ap.get(ArgType::CharPtr, index).char_ptr; + if !zero { + w.write_all(string.as_bytes())?; + } - if ptr.is_null() { - w.write_all(b"(null)")?; - } else { - let mut len = 0; - while *ptr.offset(len) != 0 { - len += 1; - } + pad(w, left, b' ', final_len..pad_space)?; + }, + FmtKind::Scientific => { + let mut float = ap.get(ArgKind::Double, index).double; + let precision = precision.unwrap_or(6); - let len = (len as usize).min(precision.unwrap_or(::core::usize::MAX)); + fmt_float_exp(w, fmt, None, false, precision, float, left, pad_space, pad_zero)?; + }, + FmtKind::Decimal => { + let mut float = ap.get(ArgKind::Double, index).double; + let precision = precision.unwrap_or(6); - pad(w, !left, b' ', len..pad_space)?; - w.write_all(slice::from_raw_parts(ptr as *const u8, len))?; - pad(w, left, b' ', len..pad_space)?; - } + fmt_float_normal(w, false, precision, float, left, pad_space, pad_zero)?; + }, + FmtKind::AnyNotation => { + let exp_fmt = b'E' | (fmt & 32); + let mut float = ap.get(ArgKind::Double, index).double; + let precision = precision.unwrap_or(6); + + if !fmt_float_exp( + w, + exp_fmt, + Some((-4, precision as isize)), + true, + precision, + float, + left, + pad_space, + pad_zero, + )? { + fmt_float_normal(w, true, precision, float, left, pad_space, pad_zero)?; } - b'c' => { - // if kind == IntKind::Long || kind == IntKind::LongLong, handle wint_t - - let c = ap.get(ArgType::Byte, index).byte; + }, + FmtKind::String => { + // if intkind == IntKind::Long || intkind == IntKind::LongLong, handle *const wchar_t + + let ptr = ap.get(ArgKind::CharPtr, index).char_ptr; + + if ptr.is_null() { + w.write_all(b"(null)")?; + } else { + let max = precision.unwrap_or(::core::usize::MAX); + let mut len = 0; + while *ptr.add(len) != 0 && len < max { + len += 1; + } - pad(w, !left, b' ', 1..pad_space)?; - w.write_all(&[c as u8])?; - pad(w, left, b' ', 1..pad_space)?; + pad(w, !left, b' ', len..pad_space)?; + w.write_all(slice::from_raw_parts(ptr as *const u8, len))?; + pad(w, left, b' ', len..pad_space)?; } - b'p' => { - let ptr = ap.get(ArgType::VoidPtr, index).int_ptr; + }, + FmtKind::Char => { + // if intkind == IntKind::Long || intkind == IntKind::LongLong, handle wint_t - let mut len = 1; - if ptr.is_null() { - len = "(nil)".len(); - } else { - let mut ptr = ptr as usize; - while ptr >= 10 { - ptr /= 10; - len += 1; - } - } + let c = ap.get(ArgKind::Byte, index).byte; - pad(w, !left, b' ', len..pad_space)?; - if ptr.is_null() { - write!(w, "(nil)")?; - } else { - write!(w, "0x{:x}", ptr as usize)?; + pad(w, !left, b' ', 1..pad_space)?; + w.write_all(&[c as u8])?; + pad(w, left, b' ', 1..pad_space)?; + }, + FmtKind::Pointer => { + let ptr = ap.get(ArgKind::VoidPtr, index).int_ptr; + + let mut len = 1; + if ptr.is_null() { + len = "(nil)".len(); + } else { + let mut ptr = ptr as usize; + while ptr >= 10 { + ptr /= 10; + len += 1; } - pad(w, left, b' ', len..pad_space)?; } - b'n' => { - let ptr = ap.get(ArgType::IntPtr, index).int_ptr; - *ptr = w.written as c_int; + + pad(w, !left, b' ', len..pad_space)?; + if ptr.is_null() { + write!(w, "(nil)")?; + } else { + write!(w, "0x{:x}", ptr as usize)?; } - _ => return Ok(-1), + pad(w, left, b' ', len..pad_space)?; + }, + FmtKind::GetWritten => { + let ptr = ap.get(ArgKind::IntPtr, index).int_ptr; + *ptr = w.written as c_int; } } - format = format.offset(1); } Ok(w.written as c_int) } diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index a6092cc7..eb45d814 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -151,8 +151,6 @@ impl Pal for Sys { mut argv: *const *mut c_char, mut envp: *const *mut c_char, ) -> c_int { - use alloc::vec::Vec; - let mut file = match File::open(path, fcntl::O_RDONLY | fcntl::O_CLOEXEC) { Ok(file) => file, Err(_) => return -1, -- GitLab