use lookahead buffer in inner_scanf
This commit is contained in:
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user