...
 
Commits (10)
......@@ -30,5 +30,6 @@ typedef unsigned int u_int, uint;
typedef unsigned long u_long, ulong;
typedef long long quad_t;
typedef unsigned long long u_quad_t;
typedef char *caddr_t;
#endif /* _SYS_TYPES_H */
......@@ -2,6 +2,7 @@ use super::{constants, Buffer, BUFSIZ, FILE};
use core::{cell::UnsafeCell, ptr};
use crate::{fs::File, io::LineWriter, platform::types::*, sync::Mutex};
use alloc::vec::Vec;
pub struct GlobalFile(UnsafeCell<FILE>);
impl GlobalFile {
......@@ -16,7 +17,7 @@ impl GlobalFile {
read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]),
read_pos: 0,
read_size: 0,
unget: None,
unget: Vec::new(),
writer,
pid: None,
......
use alloc::boxed::Box;
use super::{constants::*, Buffer, FILE};
use crate::{
fs::File,
header::{errno, fcntl::*, string::strchr},
......@@ -7,8 +8,7 @@ use crate::{
platform::{self, types::*},
sync::Mutex,
};
use super::{constants::*, Buffer, FILE};
use alloc::vec::Vec;
/// Parse mode flags as a string and output a mode flags integer
pub unsafe fn parse_mode_flags(mode_str: *const c_char) -> i32 {
......@@ -72,7 +72,7 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> {
read_buf: Buffer::Owned(vec![0; BUFSIZ as usize]),
read_pos: 0,
read_size: 0,
unget: None,
unget: Vec::new(),
writer,
pid: None,
......
......@@ -6,6 +6,7 @@ use alloc::{
vec::Vec,
};
use core::{
cmp,
ffi::VaList as va_list,
fmt::{self, Write as WriteFmt},
mem,
......@@ -76,7 +77,7 @@ pub struct FILE {
read_buf: Buffer<'static>,
read_pos: usize,
read_size: usize,
unget: Option<u8>,
unget: Vec<u8>,
// pub for stdio_ext
pub(crate) writer: LineWriter<File>,
......@@ -86,11 +87,12 @@ pub struct FILE {
impl Read for FILE {
fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
if !out.is_empty() {
if let Some(c) = self.unget.take() {
out[0] = c;
return Ok(1);
}
let unget_read_size = cmp::min(out.len(), self.unget.len());
for i in 0..unget_read_size {
out[i] = self.unget.pop().unwrap();
}
if unget_read_size != 0 {
return Ok(unget_read_size);
}
let len = {
......@@ -311,11 +313,12 @@ pub unsafe extern "C" fn fgets(
let mut wrote = false;
if left >= 1 {
if let Some(c) = stream.unget.take() {
*out = c as c_char;
let unget_read_size = cmp::min(left, stream.unget.len());
for _ in 0..unget_read_size {
*out = stream.unget.pop().unwrap() as i8;
out = out.offset(1);
left -= 1;
}
left -= unget_read_size;
}
loop {
......@@ -533,7 +536,7 @@ pub unsafe extern "C" fn fseeko(stream: *mut FILE, mut off: off_t, whence: c_int
stream.flags &= !(F_EOF | F_ERR);
stream.read_pos = 0;
stream.read_size = 0;
stream.unget = None;
stream.unget = Vec::new();
0
}
......@@ -558,7 +561,7 @@ pub unsafe extern "C" fn ftello(stream: *mut FILE) -> off_t {
return -1;
}
pos - (stream.read_size - stream.read_pos) as off_t
pos - (stream.read_size - stream.read_pos) as off_t - stream.unget.len() as off_t
}
/// Try to lock the file. Returns 0 for success, 1 for failure
......@@ -990,11 +993,7 @@ unsafe extern "C" fn tmpnam_inner(buf: *mut c_char, offset: usize) -> *mut c_cha
#[no_mangle]
pub unsafe extern "C" fn ungetc(c: c_int, stream: *mut FILE) -> c_int {
let mut stream = (*stream).lock();
if stream.unget.is_some() {
platform::errno = errno::EIO;
return EOF;
}
stream.unget = Some(c as u8);
stream.unget.push(c as u8);
c
}
......@@ -1042,8 +1041,12 @@ pub unsafe extern "C" fn vsprintf(s: *mut c_char, format: *const c_char, ap: va_
#[no_mangle]
pub unsafe extern "C" fn vfscanf(file: *mut FILE, format: *const c_char, ap: va_list) -> c_int {
let mut file = (*file).lock();
scanf::scanf(&mut *file, format, ap)
let ret = {
let mut file = (*file).lock();
scanf::scanf(&mut *file, format, ap)
};
fseeko(file, -1, SEEK_CUR);
ret
}
#[no_mangle]
......
......@@ -660,16 +660,22 @@ unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, mut ap: VaList) ->
};
let alternate = arg.alternate;
let zero = arg.zero;
let left = arg.left;
let mut left = arg.left;
let sign_reserve = arg.sign_reserve;
let sign_always = arg.sign_always;
let min_width = arg.min_width.resolve(&mut varargs, &mut ap);
let precision = arg.precision.map(|n| n.resolve(&mut varargs, &mut ap));
let pad_zero = arg.pad_zero.resolve(&mut varargs, &mut ap);
let pad_space = match pad_zero {
0 => min_width,
let signed_space = match pad_zero {
0 => min_width as isize,
_ => 0,
};
let pad_space = if signed_space < 0 {
left = true;
-signed_space as usize
} else {
signed_space as usize
};
let intkind = arg.intkind;
let fmt = arg.fmt;
let fmtkind = arg.fmtkind;
......
......@@ -42,6 +42,10 @@ EXPECT_NAMES=\
stdio/setvbuf \
stdio/sprintf \
stdio/printf_space_pad \
stdio/ungetc_multiple \
stdio/ungetc_ftell \
stdio/fscanf_offby1 \
stdio/printf_neg_pad \
stdlib/a64l \
stdlib/alloc \
stdlib/atof \
......
#, 0
i, 1
n, 2
h, -9
e, -8
l, -7
l, -6
o, -5
, -4
w, -3
o, -2
r, -1
l, 0
d, 1
, 2
c, 3
l, 4
u, 5
d, 6
e, 7
, 8
<, 9
s, 10
t, 11
d, 12
i, 13
o, 14
//1234 a
#include <stdio.h>
int main() {
FILE *f = fopen("stdio/fscanf_offby1.c", "r");
int x;
fscanf(f, "//%d", &x);
printf("%d, %ld, %d\n", x, ftell(f), fgetc(f));
}
#include <stdio.h>
int main() {
printf ("A%*s%s/\n", 5, "B", "CC");
printf ("A%*s%s/\n", -5, "B", "CC");
}
#include <stdio.h>
int main() {
FILE *f = fopen("stdio/ungetc_ftell.c", "r");
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
ungetc('\n', f);ungetc('d', f);
ungetc('l', f); ungetc('r', f);
ungetc('o', f); ungetc('w', f);
ungetc(' ', f); ungetc('o', f);
ungetc('l', f); ungetc('l', f);
ungetc('e', f); ungetc('h', f);
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
printf("%c, %ld\n", getc(f), ftell(f));
}
#include <stdio.h>
int main() {
ungetc('\n', stdin);
ungetc('d', stdin);
ungetc('l', stdin);
ungetc('r', stdin);
ungetc('o', stdin);
ungetc('w', stdin);
ungetc(' ', stdin);
ungetc('o', stdin);
ungetc('l', stdin);
ungetc('l', stdin);
ungetc('e', stdin);
ungetc('h', stdin);
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
putchar(getchar());
}