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}