Ver código fonte

use lookahead buffer in inner_scanf

oddcoder 4 anos atrás
pai
commit
a49139ca2f
2 arquivos alterados com 26 adições e 19 exclusões
  1. 6 8
      src/header/stdio/mod.rs
  2. 20 11
      src/header/stdio/scanf.rs

+ 6 - 8
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)
 }

+ 20 - 11
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<u8, c_int> {
     }
 }
 
-unsafe fn inner_scanf<R: Read>(
-    mut r: R,
+unsafe fn inner_scanf(
+    mut r: LookAheadReader,
     mut format: *const c_char,
     mut ap: va_list,
 ) -> Result<c_int, c_int> {
@@ -37,15 +38,14 @@ unsafe fn inner_scanf<R: Read>(
 
     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<R: Read>(
         };
         (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<R: Read>(
             if c != byte {
                 return Ok(matched);
             }
+            r.commit();
         } else {
             c = next_byte(&mut format)?;
 
@@ -215,6 +219,7 @@ unsafe fn inner_scanf<R: Read>(
                             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<R: Read>(
                     if let Some(ptr) = ptr {
                         *ptr = 0;
                         matched += 1;
+                        r.commit();
                     }
                 }
                 b'c' => {
@@ -362,6 +368,7 @@ unsafe fn inner_scanf<R: Read>(
 
                     if ptr.is_some() {
                         matched += 1;
+                        r.commit();
                     }
                 }
                 b'[' => {
@@ -408,6 +415,7 @@ unsafe fn inner_scanf<R: Read>(
                             **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<R: Read>(
     }
     Ok(matched)
 }
-pub unsafe fn scanf<R: Read>(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,