123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #![feature(c_variadic)]
- use core::{ffi::*, ptr::null_mut};
- extern "C" {
- fn asprintf(s: *mut *mut u8, format: *const u8, ...) -> c_int;
- fn free(p: *mut c_void);
- }
- unsafe extern "C" fn rust_fmt(str: *const u8, mut args: ...) -> Box<(c_int, String)> {
- let mut s = String::new();
- let bytes_written = printf_compat::format(
- str as _,
- args.clone().as_va_list(),
- printf_compat::output::fmt_write(&mut s),
- );
- assert!(bytes_written >= 0);
- let mut s2 = std::io::Cursor::new(vec![]);
- assert_eq!(
- bytes_written,
- printf_compat::format(
- str as _,
- args.as_va_list(),
- printf_compat::output::io_write(&mut s2),
- )
- );
- assert_eq!(s.as_bytes(), s2.get_ref());
- Box::new((bytes_written, s))
- }
- macro_rules! c_fmt {
- ($format:expr $(, $p:expr)*) => {{
- let mut ptr = null_mut();
- let bytes_written = asprintf(&mut ptr, $format $(, $p)*);
- assert!(bytes_written >= 0);
- let s: String = CStr::from_ptr(ptr as *const _).to_string_lossy().into();
- free(ptr as _);
- (bytes_written, s)
- }};
- }
- macro_rules! assert_eq_fmt {
- ($format:expr $(, $p:expr)*) => {
- assert_eq!(
- c_fmt!($format.as_ptr().cast() $(, $p)*),
- *rust_fmt($format.as_ptr().cast(), $($p),*)
- );
- };
- }
- #[test]
- fn test_plain() {
- unsafe {
- assert_eq_fmt!(c"abc");
- assert_eq_fmt!(c"");
- assert_eq_fmt!(c"%%");
- assert_eq_fmt!(c"%% def");
- assert_eq_fmt!(c"abc %%");
- assert_eq_fmt!(c"abc %% def");
- assert_eq_fmt!(c"abc %%%% def");
- assert_eq_fmt!(c"%%%%%%");
- }
- }
- #[test]
- fn test_str() {
- unsafe {
- assert_eq_fmt!(c"hello %s", c"world");
- assert_eq_fmt!(c"hello %%%s", c"world");
- assert_eq_fmt!(c"%10s", c"world");
- assert_eq_fmt!(c"%.4s", c"world");
- assert_eq_fmt!(c"%10.4s", c"world");
- assert_eq_fmt!(c"%-10.4s", c"world");
- assert_eq_fmt!(c"%-10s", c"world");
- assert_eq_fmt!(c"%s", null_mut::<c_char>());
- }
- }
- #[test]
- fn test_int() {
- unsafe {
- assert_eq_fmt!(c"% 0*i", 23125, 17);
- assert_eq_fmt!(c"% 010i", 23125);
- assert_eq_fmt!(c"% 10i", 23125);
- assert_eq_fmt!(c"% 5i", 23125);
- assert_eq_fmt!(c"% 4i", 23125);
- assert_eq_fmt!(c"%- 010i", 23125);
- assert_eq_fmt!(c"%- 10i", 23125);
- assert_eq_fmt!(c"%- 5i", 23125);
- assert_eq_fmt!(c"%- 4i", 23125);
- assert_eq_fmt!(c"%+ 010i", 23125);
- assert_eq_fmt!(c"%+ 10i", 23125);
- assert_eq_fmt!(c"%+ 5i", 23125);
- assert_eq_fmt!(c"%+ 4i", 23125);
- assert_eq_fmt!(c"%-010i", 23125);
- assert_eq_fmt!(c"%-10i", 23125);
- assert_eq_fmt!(c"%-5i", 23125);
- assert_eq_fmt!(c"%-4i", 23125);
- }
- }
- #[test]
- fn test_octal() {
- unsafe {
- assert_eq_fmt!(c"% 010o", 23125);
- assert_eq_fmt!(c"% 10o", 23125);
- assert_eq_fmt!(c"% 5o", 23125);
- assert_eq_fmt!(c"% 4o", 23125);
- assert_eq_fmt!(c"%- 010o", 23125);
- assert_eq_fmt!(c"%- 10o", 23125);
- assert_eq_fmt!(c"%- 5o", 23125);
- assert_eq_fmt!(c"%- 4o", 23125);
- assert_eq_fmt!(c"%+ 010o", 23125);
- assert_eq_fmt!(c"%+ 10o", 23125);
- assert_eq_fmt!(c"%+ 5o", 23125);
- assert_eq_fmt!(c"%+ 4o", 23125);
- assert_eq_fmt!(c"%-010o", 23125);
- assert_eq_fmt!(c"%-10o", 23125);
- assert_eq_fmt!(c"%-5o", 23125);
- assert_eq_fmt!(c"%-4o", 23125);
- }
- }
- #[test]
- fn test_hex() {
- unsafe {
- assert_eq_fmt!(c"% 010x", 23125);
- assert_eq_fmt!(c"% 10x", 23125);
- assert_eq_fmt!(c"% 5x", 23125);
- assert_eq_fmt!(c"% 4x", 23125);
- assert_eq_fmt!(c"%- 010x", 23125);
- assert_eq_fmt!(c"%- 10x", 23125);
- assert_eq_fmt!(c"%- 5x", 23125);
- assert_eq_fmt!(c"%- 4x", 23125);
- assert_eq_fmt!(c"%+ 010x", 23125);
- assert_eq_fmt!(c"%+ 10x", 23125);
- assert_eq_fmt!(c"%+ 5x", 23125);
- assert_eq_fmt!(c"%+ 4x", 23125);
- assert_eq_fmt!(c"%-010x", 23125);
- assert_eq_fmt!(c"%-10x", 23125);
- assert_eq_fmt!(c"%-5x", 23125);
- assert_eq_fmt!(c"%-4x", 23125);
- assert_eq_fmt!(c"%# 010x", 23125);
- assert_eq_fmt!(c"%# 10x", 23125);
- assert_eq_fmt!(c"%# 5x", 23125);
- assert_eq_fmt!(c"%# 4x", 23125);
- assert_eq_fmt!(c"%#- 010x", 23125);
- assert_eq_fmt!(c"%#- 10x", 23125);
- assert_eq_fmt!(c"%#- 5x", 23125);
- assert_eq_fmt!(c"%#- 4x", 23125);
- assert_eq_fmt!(c"%#+ 010x", 23125);
- assert_eq_fmt!(c"%#+ 10x", 23125);
- assert_eq_fmt!(c"%#+ 5x", 23125);
- assert_eq_fmt!(c"%#+ 4x", 23125);
- assert_eq_fmt!(c"%#-010x", 23125);
- assert_eq_fmt!(c"%#-10x", 23125);
- assert_eq_fmt!(c"%#-5x", 23125);
- assert_eq_fmt!(c"%#-4x", 23125);
- assert_eq_fmt!(c"% 010X", 23125);
- assert_eq_fmt!(c"% 10X", 23125);
- assert_eq_fmt!(c"% 5X", 23125);
- assert_eq_fmt!(c"% 4X", 23125);
- assert_eq_fmt!(c"%- 010X", 23125);
- assert_eq_fmt!(c"%- 10X", 23125);
- assert_eq_fmt!(c"%- 5X", 23125);
- assert_eq_fmt!(c"%- 4X", 23125);
- assert_eq_fmt!(c"%+ 010X", 23125);
- assert_eq_fmt!(c"%+ 10X", 23125);
- assert_eq_fmt!(c"%+ 5X", 23125);
- assert_eq_fmt!(c"%+ 4X", 23125);
- assert_eq_fmt!(c"%-010X", 23125);
- assert_eq_fmt!(c"%-10X", 23125);
- assert_eq_fmt!(c"%-5X", 23125);
- assert_eq_fmt!(c"%-4X", 23125);
- }
- }
- #[test]
- fn test_float() {
- unsafe {
- assert_eq_fmt!(c"%f", 1234f64);
- assert_eq_fmt!(c"%.5f", 1234f64);
- assert_eq_fmt!(c"%.*f", 1234f64, 3);
- }
- }
- #[test]
- fn test_char() {
- unsafe {
- assert_eq_fmt!(c"%c", b'a' as c_int);
- assert_eq_fmt!(c"%10c", b'a' as c_int);
- assert_eq_fmt!(c"%-10c", b'a' as c_int);
- }
- }
|