1#![no_std]
2extern crate alloc;
3
4use alloc::string::ToString;
5use core::{ffi::c_int, fmt};
6use syscalls::{Sysno, raw_syscall};
7mod arch;
8
9#[inline(always)]
11fn from_ret(value: usize, msg: &str) -> Result<usize, &str> {
12 if value > -4096isize as usize {
13 return Err(msg);
17 }
18 Ok(value)
19}
20
21#[inline]
22pub fn print_char(c: char) {
23 let mut buffer = [0u8; 4];
25 let encoded = c.encode_utf8(&mut buffer);
26 let bytes = encoded.as_bytes();
27
28 unsafe {
29 from_ret(
30 raw_syscall!(Sysno::write, 1, bytes.as_ptr(), bytes.len()),
31 "print char failed",
32 )
33 .unwrap();
34 }
35}
36
37#[macro_export]
38macro_rules! println {
39 ($fmt: literal $(, $($arg: tt)+)?) => {
40 $crate::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?))
41 }
42}
43
44pub fn print(args: fmt::Arguments) {
45 let s = &args.to_string();
46 print_str(s);
47}
48
49#[inline]
50pub fn print_str(s: &str) {
51 unsafe {
52 from_ret(
53 raw_syscall!(Sysno::write, 1, s.as_ptr(), s.len()),
54 "print failed",
55 )
56 .unwrap();
57 }
58}
59
60pub fn exit(status: c_int) -> ! {
61 unsafe {
62 from_ret(raw_syscall!(Sysno::exit, status), "exit failed").unwrap();
63 }
64 unreachable!()
65}