diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs index f9ab3551e3..2ec1ef15f7 100644 --- a/src/header/stdio/mod.rs +++ b/src/header/stdio/mod.rs @@ -42,7 +42,7 @@ mod helpers; mod lookaheadreader; mod printf; mod scanf; - +use lookaheadreader::LookAheadReader; static mut TMPNAM_BUF: [c_char; L_tmpnam as usize + 1] = [0; L_tmpnam as usize + 1]; enum Buffer<'a> { @@ -1051,9 +1051,10 @@ pub unsafe extern "C" fn vsprintf(s: *mut c_char, format: *const c_char, ap: va_ pub unsafe extern "C" fn vfscanf(file: *mut FILE, format: *const c_char, ap: va_list) -> c_int { let ret = { let mut file = (*file).lock(); - scanf::scanf(&mut *file, format, ap) + let f :&mut FILE = &mut *file; + let reader: LookAheadReader = f.into(); + scanf::scanf(reader, format, ap) }; - fseeko(file, -1, SEEK_CUR); ret } @@ -1064,9 +1065,6 @@ pub unsafe extern "C" fn vscanf(format: *const c_char, ap: va_list) -> c_int { #[no_mangle] pub unsafe extern "C" fn vsscanf(s: *const c_char, format: *const c_char, ap: va_list) -> c_int { - scanf::scanf( - &mut platform::UnsafeStringReader(s as *const u8), - format, - ap, - ) + let reader = (s as *const u8).into(); + scanf::scanf(reader, format, ap) } diff --git a/src/header/stdio/scanf.rs b/src/header/stdio/scanf.rs index e8af010b4d..d13444e51b 100644 --- a/src/header/stdio/scanf.rs +++ b/src/header/stdio/scanf.rs @@ -1,4 +1,5 @@ -use crate::{io::Read, platform::types::*}; +use super::lookaheadreader::LookAheadReader; +use crate::platform::types::*; use alloc::{string::String, vec::Vec}; use core::ffi::VaList as va_list; @@ -25,8 +26,8 @@ unsafe fn next_byte(string: &mut *const c_char) -> Result { } } -unsafe fn inner_scanf( - mut r: R, +unsafe fn inner_scanf( + mut r: LookAheadReader, mut format: *const c_char, mut ap: va_list, ) -> Result { @@ -37,15 +38,14 @@ unsafe fn inner_scanf( macro_rules! read { () => {{ - let buf = &mut [byte]; - match r.read(buf) { - Ok(0) => false, - Ok(_) => { - byte = buf[0]; + match r.lookahead1() { + Ok(None) => false, + Ok(Some(b)) => { + byte = b; count += 1; true } - Err(_) => return Err(-1), + Err(x) => return Err(x), } }}; } @@ -59,7 +59,10 @@ unsafe fn inner_scanf( }; (inner $($placeholder:expr)*) => { if !skip_read && !read!() { - return Ok(matched); + match matched { + 0 => return Ok(-1), + a => return Ok(a), + } } $(else { // Hacky way of having this optional @@ -86,6 +89,7 @@ unsafe fn inner_scanf( if c != byte { return Ok(matched); } + r.commit(); } else { c = next_byte(&mut format)?; @@ -215,6 +219,7 @@ unsafe fn inner_scanf( dot = true; } n.push(byte as char); + r.commit(); width = width.map(|w| w - 1); if width.map(|w| w > 0).unwrap_or(true) && !read!() { return Ok(matched); @@ -344,6 +349,7 @@ unsafe fn inner_scanf( if let Some(ptr) = ptr { *ptr = 0; matched += 1; + r.commit(); } } b'c' => { @@ -362,6 +368,7 @@ unsafe fn inner_scanf( if ptr.is_some() { matched += 1; + r.commit(); } } b'[' => { @@ -408,6 +415,7 @@ unsafe fn inner_scanf( **ptr = byte as c_char; *ptr = ptr.offset(1); } + r.commit(); // Decrease the width, and read a new character unless the width is 0 width = width.map(|w| w - 1); if width.map(|w| w > 0).unwrap_or(true) && !read!() { @@ -444,7 +452,8 @@ unsafe fn inner_scanf( } Ok(matched) } -pub unsafe fn scanf(r: R, format: *const c_char, ap: va_list) -> c_int { + +pub unsafe fn scanf(r: LookAheadReader, format: *const c_char, ap: va_list) -> c_int { match inner_scanf(r, format, ap) { Ok(n) => n, Err(n) => n,