Commit 865b7962 authored by Wren Turkal's avatar Wren Turkal
Browse files

Add implmentation for fwide posix function.

This function is used to set the orientation of a stream to either
byte-oriented or wchar-oriented.

More info on this function is here:
https://man7.org/linux/man-pages/man3/fwide.3p.html



This implementation only impmlemnts the manual switching and does
not yet guard against using a byte-oriented stream with wchar
functions and vice versa. Those step will come in additional
commits.
Signed-off-by: Wren Turkal's avatarWren Turkal <wt@penguintechs.org>
parent c13ba648
......@@ -21,6 +21,8 @@ impl GlobalFile {
writer,
pid: None,
orientation: 0,
}))
}
pub fn get(&self) -> *mut FILE {
......
......@@ -76,5 +76,7 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> {
writer,
pid: None,
orientation: 0,
})))
}
......@@ -9,7 +9,7 @@ use core::{
cmp,
ffi::VaList as va_list,
fmt::{self, Write as WriteFmt},
mem,
i32, mem,
ops::{Deref, DerefMut},
ptr, slice, str,
};
......@@ -85,6 +85,9 @@ pub struct FILE {
// Optional pid for use with popen/pclose
pid: Option<c_int>,
// wchar support
pub(crate) orientation: c_int,
}
impl Read for FILE {
......@@ -169,6 +172,18 @@ impl FILE {
}
LockGuard(self)
}
pub fn try_set_orientation(&mut self, mode: c_int) -> c_int {
let mut stream = self.lock();
if stream.0.orientation == 0 {
stream.0.orientation = match mode {
1..=i32::MAX => 1,
i32::MIN..=-1 => -1,
0 => stream.0.orientation,
};
}
stream.0.orientation
}
}
pub struct LockGuard<'a>(&'a mut FILE);
......
......@@ -89,9 +89,9 @@ pub unsafe extern "C" fn fputws(ws: *const wchar_t, stream: *mut FILE) -> c_int
}
}
// #[no_mangle]
pub extern "C" fn fwide(stream: *mut FILE, mode: c_int) -> c_int {
unimplemented!();
#[no_mangle]
pub unsafe extern "C" fn fwide(stream: *mut FILE, mode: c_int) -> c_int {
(*stream).try_set_orientation(mode)
}
#[no_mangle]
......
use core::i32;
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
// more optimization opportunities around it recognizing things like
// malloc/free.
......
......@@ -100,6 +100,7 @@ EXPECT_NAMES=\
unistd/swab \
unistd/write \
waitpid \
wchar/fwide \
wchar/mbrtowc \
wchar/mbsrtowcs \
wchar/printf-on-wchars \
......
#include <assert.h>
#include <stdio.h>
#include <wchar.h>
int test_initial_orientation(void) {
FILE *f = tmpfile();
assert(fwide(f, 0) == 0);
return 0;
}
int test_manual_byte_orientation(void) {
FILE *f = tmpfile();
// set manually to byte orientation
assert(fwide(f, -483) == -1);
// Cannot change to wchar orientation
assert(fwide(f, 1) == -1);
fclose(f);
return 0;
}
int test_manual_wchar_orientation(void) {
FILE *f = tmpfile();
// set manually to wchar orientation
assert(fwide(f, 483) == 1);
// Cannot change to byte orientation
assert(fwide(f, -1) == 1);
fclose(f);
return 0;
}
int main() {
int(*tests[])(void) = {
&test_initial_orientation,
&test_manual_byte_orientation,
&test_manual_wchar_orientation,
};
for(int i=0; i<sizeof(tests)/sizeof(int(*)(void)); i++) {
printf("%d\n", (*tests[i])());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment