use crate::capi_state::CApiState;
use crate::null_terminated::ToNullTerminatedString;
#[allow(dead_code)]
pub fn log<S: alloc::string::ToString>(s: S) {
match CApiState::try_get() {
Some(capi) => {
let string = s.to_string();
let vec = string.to_null_terminated_utf8();
unsafe { capi.csystem.logToConsole.unwrap()(vec.as_ptr()) };
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
{
log_to_stdout("LOG: ");
log_to_stdout_with_newline(&string);
}
}
None =>
{
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
log_to_stdout_with_newline("ERROR: debug::log() called before debug::initialize()")
}
}
}
pub fn log_error<S: alloc::string::ToString>(s: S) {
match CApiState::try_get() {
Some(capi) => {
let string = s.to_string();
let vec = string.to_null_terminated_utf8();
unsafe { capi.csystem.error.unwrap()(vec.as_ptr()) };
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
{
log_to_stdout("ERROR: ");
log_to_stdout_with_newline(&string);
}
}
None =>
{
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
log_to_stdout_with_newline("ERROR: debug::error() called before debug::initialize()")
}
}
}
#[allow(dead_code)]
pub(crate) fn log_c<S: AsRef<str>>(cstr: S) {
match CApiState::try_get() {
Some(capi) => unsafe { capi.csystem.logToConsole.unwrap()(cstr.as_ref().as_ptr()) },
None =>
{
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
log_to_stdout_with_newline("debug::log() called before debug::initialize()")
}
}
}
#[allow(dead_code)]
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub(crate) fn log_to_stdout<S: AsRef<str>>(s: S) {
log_bytes_to_stdout(s.as_ref().as_bytes());
}
#[allow(dead_code)]
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub(crate) fn log_to_stdout_with_newline<S: AsRef<str>>(s: S) {
log_bytes_to_stdout(s.as_ref().as_bytes());
log_bytes_to_stdout(b"\n");
}
#[cfg(target_os = "windows")]
extern "C" {
fn putchar(c: u8);
fn _flushall();
}
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub(crate) fn log_bytes_to_stdout(bytes: &[u8]) {
for b in bytes {
unsafe {
#[cfg(target_os = "windows")]
putchar(*b);
}
}
unsafe {
#[cfg(target_os = "windows")]
_flushall()
};
}
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub(crate) fn log_byte_to_stdout(byte: u8) {
unsafe {
#[cfg(target_os = "windows")]
putchar(byte);
}
unsafe {
#[cfg(target_os = "windows")]
_flushall()
};
}
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub(crate) fn log_usize_to_stdout(num: usize) {
log_usize_to_stdout_with_radix(num, 10);
}
#[cfg(not(all(target_arch = "arm", target_os = "none")))]
pub(crate) fn log_usize_to_stdout_with_radix(mut num: usize, radix: usize) {
const MAX_DIGITS: usize = 20;
let mut digits: [u8; MAX_DIGITS] = [0; MAX_DIGITS];
let mut i = 0;
if num == 0 {
log_byte_to_stdout('0' as u8)
} else {
while num > 0 && i < MAX_DIGITS {
let digit = (num % radix) as u8;
num /= radix;
if digit < 10 {
digits[i] = '0' as u8 + digit;
} else {
digits[i] = 'a' as u8 + (10 - digit);
}
i += 1;
}
while i > 0 {
i -= 1;
log_byte_to_stdout(digits[i]);
}
}
}