irid-std 0.3.1

A replacement for std when running without a filesystem on the irid kernel
Documentation
#[cfg(target_os = "none")]
use core::{ffi::CStr, ptr::slice_from_raw_parts};

#[cfg(target_os = "none")]
use alloc::borrow::ToOwned;
#[cfg(target_os = "none")]
pub use irid_syscall::ffi::thread::syscall_exit as entrypoint_exit;

#[cfg(target_os = "none")]
use crate::env::{arg_lock, var_lock};

#[cfg(target_os = "none")]
#[macro_export]
macro_rules! entrypoint {
    () => {
        core::arch::global_asm!(r#"
        .global _start
        _start:
            mov rbp,0
            mov rdi,[rsp]
            lea rsi,[rsp + 0x8]
            call _std_entry
        "#);
  
        #[unsafe(no_mangle)]
        unsafe extern "C" fn _std_entry(argc: usize, argv: *const *const u8) -> ! {
            $crate::start::_std_init(argc, argv);
            
            main();
            
            $crate::start::entrypoint_exit(0);
        }
    };
}

#[cfg(target_os = "none")]
#[unsafe(no_mangle)]
pub extern "C" fn _std_init(argc: usize, argv: *const *const u8) {
    let mut arg_lock = arg_lock();
   
    let args = unsafe { slice_from_raw_parts(argv, argc).as_ref_unchecked() };

    for arg in args {
        let arg = unsafe { CStr::from_ptr(*arg as *const i8) }.to_str().expect("failed to parse program argument");

        arg_lock.push(arg.to_owned().into_boxed_str());
    }

    let mut env_lock = var_lock();

    unsafe {
        let mut envv = argv.byte_add((argc + 1) * size_of::<*const ()>());

        while !(*envv).is_null() {
            match CStr::from_ptr(*envv as *const i8).to_str() {
                Ok(env) => match env.split_once("=") {
                    Some((key, value)) => {
                        env_lock.insert(key.to_owned().into_boxed_str(), value.to_owned().into_boxed_str());
                    }
                    None => crate::eprintln!("invalid environment variable format @ {:?}: missing '='", *envv),
                },
                Err(err) => {
                    let bytes = CStr::from_ptr(*envv as *const i8).to_bytes();

                    crate::eprintln!("failed to parse environment variable @ {:?}: {err}\n{bytes:?}", *envv)
                },
            }

            envv = envv.byte_add(size_of::<*const ()>());
        }
    }
} 

#[cfg(not(target_os = "none"))]
#[macro_export]
macro_rules! entrypoint {
    () => {}
}