#![no_std]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const VERSION_MAJOR: u32 = version_part(VERSION, 0);
pub const VERSION_MINOR: u32 = version_part(VERSION, 1);
pub const VERSION_PATCH: u32 = version_part(VERSION, 2);
const _: () = assert!(version_part(VERSION, 3) == u32::MAX, "the version in Cargo.toml must be MAJOR.MINOR.PATCH");
const fn version_part(v: &str, n: usize) -> u32 {
let b = v.as_bytes();
let (mut i, mut part, mut value, mut digits) = (0, 0, 0u32, 0);
while i <= b.len() {
let c = if i < b.len() { b[i] } else { b'.' };
if c.is_ascii_digit() && digits < 9 {
value = value * 10 + (c - b'0') as u32;
digits += 1;
} else if c == b'.' || c == b'-' || c == b'+' {
if digits == 0 {
return u32::MAX;
}
if part == n {
return value;
}
if c != b'.' {
return u32::MAX; }
(part, value, digits) = (part + 1, 0, 0);
} else {
return u32::MAX;
}
i += 1;
}
u32::MAX
}
#[macro_export]
macro_rules! app_version {
() => {
match option_env!("JFGUI_VERSION") {
Some(v) => v,
None => "0.0.0",
}
};
}
#[cfg(not(feature = "std"))]
#[macro_export]
macro_rules! main {
($body:expr) => {
$crate::__jfgui_main!($body);
};
}
#[cfg(feature = "std")]
#[macro_export]
macro_rules! main {
($body:expr) => {
$crate::__jfgui_main!($body);
$crate::__std_main!();
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __jfgui_main {
($body:expr) => {
#[cfg(panic = "unwind")]
compile_error!("JFLib needs panic = \"abort\": add [profile.dev] and [profile.release] with panic = \"abort\" to this project's Cargo.toml");
#[allow(unsafe_code, unexpected_cfgs)]
#[unsafe(no_mangle)]
fn jfgui_main() -> i32 {
#[cfg(jfgui_manifest)]
const JF_MANIFEST: Option<&str> = Some(include_str!(env!("JFGUI_PERMISSIONS_FILE")));
#[cfg(not(jfgui_manifest))]
const JF_MANIFEST: Option<&str> = option_env!("JFGUI_PERMISSIONS");
#[cfg(jfgui_assets)]
static ASSETS: &[u8] = include_bytes!(env!("JFGUI_ASSETS"));
#[cfg(not(jfgui_assets))]
static ASSETS: &[u8] = &[];
let boot = $crate::boot::Boot { app: option_env!("JFGUI_APP"), manifest: JF_MANIFEST, assets: ASSETS };
if let Err(code) = $crate::boot::start(&boot) {
return code;
}
$body
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __std_main {
() => {
#[allow(unsafe_code, dead_code)]
fn main() {
unsafe extern "Rust" {
fn jfgui_std_start() -> !;
}
unsafe { jfgui_std_start() }
}
};
}
pub mod boot;
#[cfg_attr(any(target_arch = "wasm32", target_os = "android"), path = "portable/cpu.rs")]
pub mod cpu;
pub mod crash;
#[cfg_attr(target_arch = "aarch64", path = "aarch64/fx.rs")] #[cfg_attr(all(not(target_arch = "aarch64"), any(target_arch = "wasm32", target_os = "android")), path = "portable/fx.rs")]
pub mod fx;
#[cfg(target_os = "linux")]
pub mod kernel;
#[cfg(not(target_os = "android"))]
#[cfg_attr(target_arch = "wasm32", path = "portable/mem.rs")]
#[cfg_attr(feature = "std", allow(dead_code))] mod mem;
#[cfg(all(feature = "std", not(any(target_os = "android", target_arch = "wasm32"))))]
pub use mem::Alloc;
#[cfg_attr(target_arch = "wasm32", path = "portable/os.rs")]
#[cfg_attr(target_os = "android", path = "android.rs")]
pub mod os;
pub mod sync;
#[cfg_attr(any(target_arch = "wasm32", target_os = "android"), path = "portable/math.rs")]
pub mod x87;
#[cfg(not(target_arch = "wasm32"))]
pub mod portable {
pub mod fx;
pub mod math;
}
#[cfg(not(feature = "std"))]
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
panic_report(info)
}
#[cfg(feature = "std")]
mod hosted;
#[cfg(feature = "std")]
pub use hosted::panic_hook;
pub(crate) fn panic_report(info: &dyn core::fmt::Display) -> ! {
use core::fmt::Write;
if crash::busy() {
os::exit(3); }
let mut s = crash::StackText::<1024>::new(); let _ = writeln!(s, "panic: {info}");
os::write_stderr(s.bytes());
let text = s.as_str().trim_end();
let mut ci = crash::CrashInfo::empty();
ci.kind = crash::CK_PANIC;
ci.msg = text.strip_prefix("panic: ").unwrap_or(text);
crash::report(&ci)
}