use lookahead buffer in inner_scanf

This commit is contained in:
oddcoder
2020-06-03 13:38:37 +02:00
parent 14e011b72c
commit a49139ca2f
2 changed files with 26 additions and 19 deletions
+6 -8
View File
@@ -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
View File
@@ -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,