Parcourir la source

Merge branch 'gcc-regressions' into 'master'

Gcc regressions

See merge request redox-os/relibc!270
Jeremy Soller il y a 4 ans
Parent
commit
e4c26cfaa0

+ 1 - 0
include/sys/types.h

@@ -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 - 1
src/header/stdio/default.rs

@@ -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,

+ 3 - 3
src/header/stdio/helpers.rs

@@ -1,5 +1,6 @@
 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,

+ 21 - 18
src/header/stdio/mod.rs

@@ -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]

+ 9 - 3
src/header/stdio/printf.rs

@@ -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;

+ 4 - 0
tests/Makefile

@@ -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 - 0
tests/expected/stdio/fscanf_offby1.stderr


+ 1 - 0
tests/expected/stdio/fscanf_offby1.stdout

@@ -0,0 +1 @@
+1234, 7, 32

+ 0 - 0
tests/expected/stdio/printf_neg_pad.stderr


+ 2 - 0
tests/expected/stdio/printf_neg_pad.stdout

@@ -0,0 +1,2 @@
+A    BCC/
+AB    CC/

+ 0 - 0
tests/expected/stdio/ungetc_ftell.stderr


+ 28 - 0
tests/expected/stdio/ungetc_ftell.stdout

@@ -0,0 +1,28 @@
+#, 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

+ 0 - 0
tests/expected/stdio/ungetc_multiple.stderr


+ 1 - 0
tests/expected/stdio/ungetc_multiple.stdout

@@ -0,0 +1 @@
+hello world

+ 8 - 0
tests/stdio/fscanf_offby1.c

@@ -0,0 +1,8 @@
+//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));
+}

+ 5 - 0
tests/stdio/printf_neg_pad.c

@@ -0,0 +1,5 @@
+#include <stdio.h>
+int main() {
+        printf ("A%*s%s/\n", 5, "B", "CC");
+        printf ("A%*s%s/\n", -5, "B", "CC");
+}

+ 37 - 0
tests/stdio/ungetc_ftell.c

@@ -0,0 +1,37 @@
+#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));
+}

+ 27 - 0
tests/stdio/ungetc_multiple.c

@@ -0,0 +1,27 @@
+#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());
+}