orion_cfmt/lib.rs
1//! cfmt - Format output without Rust code segment in binary
2//!
3//! # Design objective:
4//! 1. The print output depends on the API of C
5//! 2. Eliminate the dependency on Display/Debug trait.
6//!
7//! # Examples
8//!
9//! ```rust
10//! #[link(name = "c")]
11//! extern "C" {
12//! fn dprintf(fd: i32, format: *const u8, ...) -> i32;
13//! fn snprintf(buf: *mut u8, size: usize, format: *const u8, ...) -> i32;
14//! }
15//! orion_cfmt::println!("hello world");
16//! orion_cfmt::println!("signed decimal {:d}", -1);
17//! orion_cfmt::println!("unsigned decimal {:u}", -1);
18//! orion_cfmt::println!("hexadecimal {:x}", -1);
19//! orion_cfmt::println!("pointer {:p}", &1);
20//! orion_cfmt::println!("float {:e}", -1.0);
21//! orion_cfmt::println!("rust &str {:rs}", "hello world");
22//! orion_cfmt::println!("rust &[u8] {:rb}", b"hello world");
23//! orion_cfmt::println!("rust char {:rc}", 'δΈ');
24//! orion_cfmt::println!("c str {:cs}", b"hello world\0");
25//! orion_cfmt::println!("c char {:cc}", b'0');
26//!
27//! let mut buf = [0_u8; 100];
28//! orion_cfmt::bprint!(&mut buf, "snprintf rust string {:rs}", "hello world");
29//! orion_cfmt::println!("c str {:cs}", &buf);
30//!
31
32#![no_std]
33
34pub use cfmt_macros::{
35 print, println, eprint, eprintln,
36 cprint, cprintln, ceprint, ceprintln,
37 csprint, cbprint, sprint, bprint
38};
39
40#[inline(never)]
41pub fn encode_utf8(c: char, buf: &mut [u8; 5]) -> *const u8 {
42 let mut u = c as u32;
43 buf[4] = 0_u8;
44 if u <= 0x7F {
45 buf[3] = u as u8;
46 return &buf[3] as *const u8;
47 }
48 buf[3] = (u as u8 & 0x3F) | 0x80;
49 u >>= 6;
50 if u <= 0x1F {
51 buf[2] = (u | 0xC0) as u8;
52 return &buf[2] as *const u8;
53 }
54 buf[2] = (u as u8 & 0x3F) | 0x80;
55 u >>= 6;
56 if u <= 0xF {
57 buf[1] = (u | 0xE0) as u8;
58 return &buf[1] as *const u8;
59 }
60 buf[1] = (u as u8 & 0x3F) | 0x80;
61 u >>= 6;
62 buf[0] = (u | 0xF0) as u8;
63 return buf as *const u8;
64}
65
66#[cfg(test)]
67mod test {
68 extern crate std;
69 use std::format;
70 #[link(name = "c")]
71 extern "C" {
72 fn snprintf(buf: *mut u8, len: usize, format: *const u8, ...) -> i32;
73 }
74
75 #[test]
76 fn test_fat_pointer() {
77 let mut buf = [0_u8; 100];
78 let s = "hello";
79 let n = s as *const _ as *const u8 as usize;
80 super::bprint!(&mut buf[0..], "{:p} {:p}", s, s);
81 let s = format!("0x{:x} 0x{:x}\0", n, n);
82 assert_eq!(s.as_bytes(), &buf[0..s.len()]);
83 }
84}