acid/firmware2/src/ffi/inout/mod.rs
2026-01-19 20:13:25 +01:00

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!()
}