diff --git a/stdio/src/lib.rs b/stdio/src/lib.rs index a84c5a31935aca70e66fa299b79c174fc8e5703c..c8bdcbdd51e28c1a57dea81b10049e79f44f540c 100644 --- a/stdio/src/lib.rs +++ b/stdio/src/lib.rs @@ -8,113 +8,23 @@ extern crate va_list as vl; use platform::types::*; use vl::VaList as va_list; +mod printf; + pub const BUFSIZ: c_int = 4096; pub const FILENAME_MAX: c_int = 4096; pub struct FILE; +#[no_mangle] pub static mut stdout: *mut FILE = 1 as *mut FILE; -pub static mut stderr: *mut FILE = 2 as *mut FILE; #[no_mangle] -pub unsafe extern "C" fn vfprintf(file: *mut FILE, format: *const c_char, mut ap: va_list) -> c_int { - use core::fmt::Write; - use core::slice; - use core::str; - - extern "C" { - fn strlen(s: *const c_char) -> size_t; - } - - let mut w = platform::FileWriter(file as c_int); - - let format = slice::from_raw_parts(format as *const u8, strlen(format)); - - let mut i = 0; - let mut found_percent = false; - while i < format.len() { - let b = format[i]; - - if found_percent { - match b as char { - '%' => { - w.write_char('%'); - found_percent = false; - }, - 'c' => { - let a = ap.get::<u32>(); - - w.write_char(a as u8 as char); - - found_percent = false; - }, - 'd' | 'i' => { - let a = ap.get::<c_int>(); - - w.write_fmt(format_args!("{}", a)); - - found_percent = false; - }, - 'n' => { - let _a = ap.get::<c_int>(); - - found_percent = false; - }, - 'p' => { - let a = ap.get::<usize>(); - - w.write_fmt(format_args!("0x{:x}", a)); - - found_percent = false; - }, - 's' => { - let a = ap.get::<usize>(); - - w.write_str(str::from_utf8_unchecked( - slice::from_raw_parts(a as *const u8, strlen(a as *const c_char)) - )); - - found_percent = false; - }, - 'u' => { - let a = ap.get::<c_uint>(); - - w.write_fmt(format_args!("{}", a)); - - found_percent = false; - }, - 'x' => { - let a = ap.get::<c_uint>(); - - w.write_fmt(format_args!("{:x}", a)); - - found_percent = false; - }, - 'X' => { - let a = ap.get::<c_uint>(); - - w.write_fmt(format_args!("{:X}", a)); - - found_percent = false; - }, - '-' => {}, - '+' => {}, - ' ' => {}, - '#' => {}, - '0' ... '9' => {}, - _ => {} - } - } else if b == b'%' { - found_percent = true; - } else { - w.write_char(b as char); - } - - i += 1; - } +pub static mut stderr: *mut FILE = 2 as *mut FILE; - 0 +#[no_mangle] +pub unsafe extern "C" fn vfprintf(file: *mut FILE, format: *const c_char, ap: va_list) -> c_int { + printf::printf(platform::FileWriter(file as c_int), format, ap) } #[no_mangle] diff --git a/stdio/src/printf.rs b/stdio/src/printf.rs new file mode 100644 index 0000000000000000000000000000000000000000..7dc2f53bbfd3e46ac0335680a845a9f271e93b95 --- /dev/null +++ b/stdio/src/printf.rs @@ -0,0 +1,101 @@ +use core::fmt; + +use platform::types::*; +use vl::VaList; + +pub unsafe fn printf<W: fmt::Write>(mut w: W, format: *const c_char, mut ap: VaList) -> c_int { + use core::fmt::Write; + use core::slice; + use core::str; + + extern "C" { + fn strlen(s: *const c_char) -> size_t; + } + + let format = slice::from_raw_parts(format as *const u8, strlen(format)); + + let mut i = 0; + let mut found_percent = false; + while i < format.len() { + let b = format[i]; + + if found_percent { + match b as char { + '%' => { + w.write_char('%'); + found_percent = false; + }, + 'c' => { + let a = ap.get::<u32>(); + + w.write_char(a as u8 as char); + + found_percent = false; + }, + 'd' | 'i' => { + let a = ap.get::<c_int>(); + + w.write_fmt(format_args!("{}", a)); + + found_percent = false; + }, + 'n' => { + let _a = ap.get::<c_int>(); + + found_percent = false; + }, + 'p' => { + let a = ap.get::<usize>(); + + w.write_fmt(format_args!("0x{:x}", a)); + + found_percent = false; + }, + 's' => { + let a = ap.get::<usize>(); + + w.write_str(str::from_utf8_unchecked( + slice::from_raw_parts(a as *const u8, strlen(a as *const c_char)) + )); + + found_percent = false; + }, + 'u' => { + let a = ap.get::<c_uint>(); + + w.write_fmt(format_args!("{}", a)); + + found_percent = false; + }, + 'x' => { + let a = ap.get::<c_uint>(); + + w.write_fmt(format_args!("{:x}", a)); + + found_percent = false; + }, + 'X' => { + let a = ap.get::<c_uint>(); + + w.write_fmt(format_args!("{:X}", a)); + + found_percent = false; + }, + '-' => {}, + '+' => {}, + ' ' => {}, + '#' => {}, + '0' ... '9' => {}, + _ => {} + } + } else if b == b'%' { + found_percent = true; + } else { + w.write_char(b as char); + } + + i += 1; + } + + 0 +} diff --git a/tests/alloc.c b/tests/alloc.c index 934f74861b5d7b4c6661cba6e22ceddced51240c..99f11ff75fb8c28a60fc6a7db5ca9f45914369b6 100644 --- a/tests/alloc.c +++ b/tests/alloc.c @@ -1,14 +1,12 @@ +#include <stdio.h> #include <stdlib.h> -#include <unistd.h> int main(int argc, char ** argv) { - write(STDERR_FILENO, "malloc\n", 7); char * ptr = (char *)malloc(256); - write(STDERR_FILENO, "set\n", 4); + printf("malloc %p\n", ptr); int i; for(i = 0; i < 256; i++) { ptr[i] = (char)i; } - write(STDERR_FILENO, "free\n", 5); free(ptr); }