tests.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #![feature(c_variadic)]
  2. use core::{ffi::*, ptr::null_mut};
  3. extern "C" {
  4. fn asprintf(s: *mut *mut u8, format: *const u8, ...) -> c_int;
  5. fn free(p: *mut c_void);
  6. }
  7. unsafe extern "C" fn rust_fmt(str: *const u8, mut args: ...) -> Box<(c_int, String)> {
  8. let mut s = String::new();
  9. let bytes_written = printf_compat::format(
  10. str as _,
  11. args.clone().as_va_list(),
  12. printf_compat::output::fmt_write(&mut s),
  13. );
  14. assert!(bytes_written >= 0);
  15. let mut s2 = std::io::Cursor::new(vec![]);
  16. assert_eq!(
  17. bytes_written,
  18. printf_compat::format(
  19. str as _,
  20. args.as_va_list(),
  21. printf_compat::output::io_write(&mut s2),
  22. )
  23. );
  24. assert_eq!(s.as_bytes(), s2.get_ref());
  25. Box::new((bytes_written, s))
  26. }
  27. macro_rules! c_fmt {
  28. ($format:expr $(, $p:expr)*) => {{
  29. let mut ptr = null_mut();
  30. let bytes_written = asprintf(&mut ptr, $format $(, $p)*);
  31. assert!(bytes_written >= 0);
  32. let s: String = CStr::from_ptr(ptr as *const _).to_string_lossy().into();
  33. free(ptr as _);
  34. (bytes_written, s)
  35. }};
  36. }
  37. macro_rules! assert_eq_fmt {
  38. ($format:expr $(, $p:expr)*) => {
  39. assert_eq!(
  40. c_fmt!($format.as_ptr().cast() $(, $p)*),
  41. *rust_fmt($format.as_ptr().cast(), $($p),*)
  42. );
  43. };
  44. }
  45. #[test]
  46. fn test_plain() {
  47. unsafe {
  48. assert_eq_fmt!(c"abc");
  49. assert_eq_fmt!(c"");
  50. assert_eq_fmt!(c"%%");
  51. assert_eq_fmt!(c"%% def");
  52. assert_eq_fmt!(c"abc %%");
  53. assert_eq_fmt!(c"abc %% def");
  54. assert_eq_fmt!(c"abc %%%% def");
  55. assert_eq_fmt!(c"%%%%%%");
  56. }
  57. }
  58. #[test]
  59. fn test_str() {
  60. unsafe {
  61. assert_eq_fmt!(c"hello %s", c"world");
  62. assert_eq_fmt!(c"hello %%%s", c"world");
  63. assert_eq_fmt!(c"%10s", c"world");
  64. assert_eq_fmt!(c"%.4s", c"world");
  65. assert_eq_fmt!(c"%10.4s", c"world");
  66. assert_eq_fmt!(c"%-10.4s", c"world");
  67. assert_eq_fmt!(c"%-10s", c"world");
  68. assert_eq_fmt!(c"%s", null_mut::<c_char>());
  69. }
  70. }
  71. #[test]
  72. fn test_int() {
  73. unsafe {
  74. assert_eq_fmt!(c"% 0*i", 23125, 17);
  75. assert_eq_fmt!(c"% 010i", 23125);
  76. assert_eq_fmt!(c"% 10i", 23125);
  77. assert_eq_fmt!(c"% 5i", 23125);
  78. assert_eq_fmt!(c"% 4i", 23125);
  79. assert_eq_fmt!(c"%- 010i", 23125);
  80. assert_eq_fmt!(c"%- 10i", 23125);
  81. assert_eq_fmt!(c"%- 5i", 23125);
  82. assert_eq_fmt!(c"%- 4i", 23125);
  83. assert_eq_fmt!(c"%+ 010i", 23125);
  84. assert_eq_fmt!(c"%+ 10i", 23125);
  85. assert_eq_fmt!(c"%+ 5i", 23125);
  86. assert_eq_fmt!(c"%+ 4i", 23125);
  87. assert_eq_fmt!(c"%-010i", 23125);
  88. assert_eq_fmt!(c"%-10i", 23125);
  89. assert_eq_fmt!(c"%-5i", 23125);
  90. assert_eq_fmt!(c"%-4i", 23125);
  91. }
  92. }
  93. #[test]
  94. fn test_octal() {
  95. unsafe {
  96. assert_eq_fmt!(c"% 010o", 23125);
  97. assert_eq_fmt!(c"% 10o", 23125);
  98. assert_eq_fmt!(c"% 5o", 23125);
  99. assert_eq_fmt!(c"% 4o", 23125);
  100. assert_eq_fmt!(c"%- 010o", 23125);
  101. assert_eq_fmt!(c"%- 10o", 23125);
  102. assert_eq_fmt!(c"%- 5o", 23125);
  103. assert_eq_fmt!(c"%- 4o", 23125);
  104. assert_eq_fmt!(c"%+ 010o", 23125);
  105. assert_eq_fmt!(c"%+ 10o", 23125);
  106. assert_eq_fmt!(c"%+ 5o", 23125);
  107. assert_eq_fmt!(c"%+ 4o", 23125);
  108. assert_eq_fmt!(c"%-010o", 23125);
  109. assert_eq_fmt!(c"%-10o", 23125);
  110. assert_eq_fmt!(c"%-5o", 23125);
  111. assert_eq_fmt!(c"%-4o", 23125);
  112. }
  113. }
  114. #[test]
  115. fn test_hex() {
  116. unsafe {
  117. assert_eq_fmt!(c"% 010x", 23125);
  118. assert_eq_fmt!(c"% 10x", 23125);
  119. assert_eq_fmt!(c"% 5x", 23125);
  120. assert_eq_fmt!(c"% 4x", 23125);
  121. assert_eq_fmt!(c"%- 010x", 23125);
  122. assert_eq_fmt!(c"%- 10x", 23125);
  123. assert_eq_fmt!(c"%- 5x", 23125);
  124. assert_eq_fmt!(c"%- 4x", 23125);
  125. assert_eq_fmt!(c"%+ 010x", 23125);
  126. assert_eq_fmt!(c"%+ 10x", 23125);
  127. assert_eq_fmt!(c"%+ 5x", 23125);
  128. assert_eq_fmt!(c"%+ 4x", 23125);
  129. assert_eq_fmt!(c"%-010x", 23125);
  130. assert_eq_fmt!(c"%-10x", 23125);
  131. assert_eq_fmt!(c"%-5x", 23125);
  132. assert_eq_fmt!(c"%-4x", 23125);
  133. assert_eq_fmt!(c"%# 010x", 23125);
  134. assert_eq_fmt!(c"%# 10x", 23125);
  135. assert_eq_fmt!(c"%# 5x", 23125);
  136. assert_eq_fmt!(c"%# 4x", 23125);
  137. assert_eq_fmt!(c"%#- 010x", 23125);
  138. assert_eq_fmt!(c"%#- 10x", 23125);
  139. assert_eq_fmt!(c"%#- 5x", 23125);
  140. assert_eq_fmt!(c"%#- 4x", 23125);
  141. assert_eq_fmt!(c"%#+ 010x", 23125);
  142. assert_eq_fmt!(c"%#+ 10x", 23125);
  143. assert_eq_fmt!(c"%#+ 5x", 23125);
  144. assert_eq_fmt!(c"%#+ 4x", 23125);
  145. assert_eq_fmt!(c"%#-010x", 23125);
  146. assert_eq_fmt!(c"%#-10x", 23125);
  147. assert_eq_fmt!(c"%#-5x", 23125);
  148. assert_eq_fmt!(c"%#-4x", 23125);
  149. assert_eq_fmt!(c"% 010X", 23125);
  150. assert_eq_fmt!(c"% 10X", 23125);
  151. assert_eq_fmt!(c"% 5X", 23125);
  152. assert_eq_fmt!(c"% 4X", 23125);
  153. assert_eq_fmt!(c"%- 010X", 23125);
  154. assert_eq_fmt!(c"%- 10X", 23125);
  155. assert_eq_fmt!(c"%- 5X", 23125);
  156. assert_eq_fmt!(c"%- 4X", 23125);
  157. assert_eq_fmt!(c"%+ 010X", 23125);
  158. assert_eq_fmt!(c"%+ 10X", 23125);
  159. assert_eq_fmt!(c"%+ 5X", 23125);
  160. assert_eq_fmt!(c"%+ 4X", 23125);
  161. assert_eq_fmt!(c"%-010X", 23125);
  162. assert_eq_fmt!(c"%-10X", 23125);
  163. assert_eq_fmt!(c"%-5X", 23125);
  164. assert_eq_fmt!(c"%-4X", 23125);
  165. }
  166. }
  167. #[test]
  168. fn test_float() {
  169. unsafe {
  170. assert_eq_fmt!(c"%f", 1234f64);
  171. assert_eq_fmt!(c"%.5f", 1234f64);
  172. assert_eq_fmt!(c"%.*f", 1234f64, 3);
  173. }
  174. }
  175. #[test]
  176. fn test_char() {
  177. unsafe {
  178. assert_eq_fmt!(c"%c", b'a' as c_int);
  179. assert_eq_fmt!(c"%10c", b'a' as c_int);
  180. assert_eq_fmt!(c"%-10c", b'a' as c_int);
  181. }
  182. }