189 lines
4.5 KiB
Rust
189 lines
4.5 KiB
Rust
//! This would've been called `io`, but rust-analyzer refuses to see
|
|
//! the submodules of this module when it's named `io`.
|
|
|
|
#![allow(unused_variables)]
|
|
|
|
use core::{
|
|
ffi::{CStr, VaList, c_char, c_int, c_long, c_size_t, c_void},
|
|
ptr::null_mut,
|
|
};
|
|
|
|
use alloc::string::String;
|
|
use log::{info, warn};
|
|
use printf_compat::output::fmt_write;
|
|
|
|
use crate::ffi::{
|
|
inout::file::{FILE, STDERR, STDOUT},
|
|
string::__xkbc_memcpy,
|
|
};
|
|
|
|
pub mod dir;
|
|
pub mod file;
|
|
|
|
// File management
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_fopen(filename: *const c_char, mode: *const c_char) -> *mut FILE {
|
|
warn!(
|
|
"The xkbcommon library is attempting to open a file at path: {:?}",
|
|
unsafe { CStr::from_ptr(filename) }
|
|
);
|
|
null_mut()
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_fclose(file: *mut FILE) -> c_int {
|
|
todo!()
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_fseek(stream: *mut FILE, offset: c_long, whence: c_int) -> c_int {
|
|
todo!()
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_ftell(stream: *mut FILE) -> c_long {
|
|
todo!()
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_fread(
|
|
ptr: *mut c_void,
|
|
size: c_size_t,
|
|
nobj: c_size_t,
|
|
stream: *mut FILE,
|
|
) -> c_size_t {
|
|
todo!()
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
unsafe extern "C" fn __xkbc_fputs(s: *const c_char, stream: *mut FILE) -> c_int {
|
|
todo!()
|
|
}
|
|
|
|
// Printing
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_fprintf(
|
|
stream: *mut FILE,
|
|
format: *const c_char,
|
|
mut args: ...
|
|
) -> c_int {
|
|
unsafe { __xkbc_vfprintf(stream, format, args.as_va_list()) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_fprintf(
|
|
stream: *mut FILE,
|
|
format: *const c_char,
|
|
mut args: ...
|
|
) -> c_int {
|
|
unsafe { __xkbc_fprintf(stream, format) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_vfprintf(
|
|
stream: *mut FILE,
|
|
format: *const c_char,
|
|
ap: VaList,
|
|
) -> c_int {
|
|
if stream == STDOUT || stream == STDERR {
|
|
let string = ::alloc::format!(
|
|
"vfprintf({:?}, {:?}, {:?})",
|
|
stream,
|
|
unsafe { CStr::from_ptr(format) },
|
|
ap
|
|
);
|
|
info!("{}", string);
|
|
string.len() as c_int
|
|
} else {
|
|
-1
|
|
}
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_vasprintf(
|
|
strp: *mut *mut c_char,
|
|
fmt: *const c_char,
|
|
ap: VaList,
|
|
) -> c_int {
|
|
todo!()
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_snprintf(
|
|
string: *mut c_char,
|
|
size: c_size_t,
|
|
format: *const c_char,
|
|
mut args: ...
|
|
) -> c_int {
|
|
unsafe { __xkbc_vsnprintf(string, size, format, args.as_va_list()) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __xkbc_vsnprintf(
|
|
string: *mut c_char,
|
|
// Length in bytes **including the terminating null byte**.
|
|
size: c_size_t,
|
|
format: *const c_char,
|
|
ap: VaList,
|
|
) -> c_int {
|
|
if size == 0 {
|
|
return 0;
|
|
}
|
|
|
|
let mut rust_buffer = String::new();
|
|
unsafe {
|
|
printf_compat::format(format, ap, fmt_write(&mut rust_buffer));
|
|
let string_length = core::cmp::min(rust_buffer.len(), size - 1);
|
|
// __xkbc_strncpy would be preferrable, if it was available
|
|
__xkbc_memcpy(
|
|
string as *mut _,
|
|
rust_buffer.as_ptr() as *mut _,
|
|
string_length,
|
|
);
|
|
*string.add(string_length) = 0; // Add terminating null byte.
|
|
string_length as c_int
|
|
}
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_sprintf(
|
|
string: *mut c_char,
|
|
format: *const c_char,
|
|
mut args: ...
|
|
) -> c_int {
|
|
unsafe { vsprintf(string, format, args.as_va_list()) }
|
|
}
|
|
|
|
pub unsafe fn vsprintf(string: *mut c_char, format: *const c_char, ap: VaList) -> c_int {
|
|
let mut rust_buffer = String::new();
|
|
unsafe {
|
|
printf_compat::format(format, ap, fmt_write(&mut rust_buffer));
|
|
// __xkbc_strncpy would be preferrable, if it was available
|
|
__xkbc_memcpy(
|
|
string as *mut _,
|
|
rust_buffer.as_ptr() as *mut _,
|
|
rust_buffer.len(),
|
|
);
|
|
*string.add(rust_buffer.len()) = 0; // Add terminating null byte.
|
|
rust_buffer.len() as c_int
|
|
}
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_vsnprintf(
|
|
string: *mut c_char,
|
|
// Length in bytes **including the terminating null byte**.
|
|
size: c_size_t,
|
|
format: *const c_char,
|
|
ap: VaList,
|
|
) -> c_int {
|
|
unsafe { __xkbc_vsnprintf(string, size, format, ap) }
|
|
}
|
|
|
|
#[unsafe(no_mangle)]
|
|
pub unsafe extern "C" fn __spre_sscanf(s: *const c_char, format: *const c_char, ...) -> c_int {
|
|
todo!()
|
|
}
|