1use crate::sync::Mutex;
3
4pub static __STDOUT_LOCK: Mutex<()> = Mutex::new(());
5pub static __STDERR_LOCK: Mutex<()> = Mutex::new(());
6
7use rusl::platform::Fd;
8
9#[macro_export]
11macro_rules! print {
12 ($($arg:tt)*) => {
13 {
14 let __tiny_std_unix_print_writer_guard = $crate::unix::print::__STDOUT_LOCK.lock();
15 let mut __tiny_std_unix_print_writer = $crate::unix::print::__STDOUT_WRITER;
16 let _ = core::fmt::Write::write_fmt(&mut __tiny_std_unix_print_writer, format_args!($($arg)*));
17 }
18 }
19}
20
21#[macro_export]
23macro_rules! println {
24 () => {
25 {
26 let __tiny_std_unix_print_writer_guard = $crate::unix::print::__STDOUT_LOCK.lock();
27 let __tiny_std_unix_print_writer = $crate::unix::print::__STDOUT_WRITER;
28 let _ = __tiny_std_unix_print_writer.__write_newline();
29 }
30 };
31 ($($arg:tt)*) => {
32 {
33 let __tiny_std_unix_print_writer_guard = $crate::unix::print::__STDOUT_LOCK.lock();
34 let mut __tiny_std_unix_print_writer = $crate::unix::print::__STDOUT_WRITER;
35 let _ = core::fmt::Write::write_fmt(&mut __tiny_std_unix_print_writer, format_args!($($arg)*));
36 let _ = __tiny_std_unix_print_writer.__write_newline();
37 }
38 }
39}
40
41#[macro_export]
43macro_rules! eprint {
44 ($($arg:tt)*) => {
45 {
46 let __tiny_std_unix_print_writer_guard = $crate::unix::print::__STDERR_LOCK.lock();
47 let mut __tiny_std_unix_print_writer = $crate::unix::print::__STDERR_WRITER;
48 let _ = core::fmt::Write::write_fmt(&mut __tiny_std_unix_print_writer, format_args!($($arg)*));
49 }
50 }
51}
52
53#[macro_export]
55macro_rules! eprintln {
56 () => {
57 {
58 let __tiny_std_unix_print_writer_guard = $crate::unix::print::__STDERR_LOCK.lock();
59 let __tiny_std_unix_print_writer = $crate::unix::print::__STDERR_WRITER;
60 let _ = __tiny_std_unix_print_writer.__write_newline();
61 }
62 };
63 ($($arg:tt)*) => {
64 {
65 let __tiny_std_unix_print_writer_guard = $crate::unix::print::__STDERR_LOCK.lock();
66 let mut __tiny_std_unix_print_writer = $crate::unix::print::__STDERR_WRITER;
67 let _ = core::fmt::Write::write_fmt(&mut __tiny_std_unix_print_writer, format_args!($($arg)*));
68 let _ = __tiny_std_unix_print_writer.__write_newline();
69 }
70 }
71}
72
73#[macro_export]
75macro_rules! dbg {
76 () => {
77 $crate::eprintln!("[{}:{}]", core::file!(), core::line!())
78 };
79 ($val:expr $(,)?) => {
80 match $val {
81 tmp => {
82 $crate::eprintln!("[{}:{}] {} = {:#?}",
83 core::file!(), core::line!(), core::stringify!($val), &tmp);
84 tmp
85 }
86 }
87 };
88 ($($val:expr),+ $(,)?) => {
89 ($($crate::dbg!($val)),+,)
90 };
91}
92
93fn try_print(fd: Fd, msg: &str) -> core::fmt::Result {
94 let buf = msg.as_bytes();
95 let len = buf.len();
96 let mut flushed = 0;
97 loop {
98 let res = rusl::unistd::write(fd, &buf[flushed..]).map_err(|_e| core::fmt::Error)?;
99 match res.cmp(&0) {
100 core::cmp::Ordering::Less => return Err(core::fmt::Error),
101 core::cmp::Ordering::Equal => return Ok(()),
102 core::cmp::Ordering::Greater => {
103 flushed += res as usize;
105 if flushed >= len {
106 return Ok(());
107 }
108 }
109 }
110 }
111}
112
113pub struct __UnixWriter(Fd);
114
115pub const __STDOUT_WRITER: __UnixWriter = __UnixWriter(rusl::platform::STDOUT);
116pub const __STDERR_WRITER: __UnixWriter = __UnixWriter(rusl::platform::STDERR);
117impl __UnixWriter {
118 pub fn __write_newline(&self) -> core::fmt::Result {
121 try_print(self.0, "\n")
122 }
123}
124
125impl core::fmt::Write for __UnixWriter {
126 #[inline]
127 fn write_str(&mut self, s: &str) -> core::fmt::Result {
128 try_print(self.0, s)
129 }
130}
131
132#[cfg(test)]
133mod tests {
134
135 #[test]
136 fn test_prints() {
137 print!("-- First");
138 print!("My first");
139 print!(" two messages");
140 print!(" were cutoff but it's fine");
141 println!();
142 println!("-- Second\nHello there {}", "me");
143 }
144
145 #[test]
146 fn test_eprints() {
147 eprintln!("-- First");
148 eprint!("My first");
149 eprint!(" two messages");
150 eprint!(" were cutoff but it's fine");
151 eprintln!();
152 eprintln!("-- Second\nHello there {}", "me");
153 }
154
155 #[test]
156 fn test_dbgs() {
157 dbg!();
158 let val = 5;
159 let res = dbg!(val) - 5;
160 assert_eq!(0, res);
161 }
162}