printf.rs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. use core::fmt::Write as CoreWrite;
  2. use core::{slice, str, ptr};
  3. use platform::types::*;
  4. use platform::{self, Write};
  5. use va_list::VaList;
  6. pub unsafe fn printf<W: Write>(w: W, format: *const c_char, mut ap: VaList) -> c_int {
  7. let mut w = platform::CountingWriter::new(w);
  8. let format = slice::from_raw_parts(format as *const u8, usize::max_value());
  9. let mut found_percent = false;
  10. for &b in format.iter() {
  11. // check for NUL
  12. if b == 0 {
  13. break;
  14. }
  15. if found_percent {
  16. if match b as char {
  17. '%' => {
  18. found_percent = false;
  19. w.write_char('%')
  20. }
  21. 'c' => {
  22. let a = ap.get::<u32>();
  23. found_percent = false;
  24. w.write_u8(a as u8)
  25. }
  26. 'd' | 'i' => {
  27. let a = ap.get::<c_int>();
  28. found_percent = false;
  29. w.write_fmt(format_args!("{}", a))
  30. }
  31. 'f' | 'F' => {
  32. let a = ap.get::<f64>();
  33. found_percent = false;
  34. w.write_fmt(format_args!("{}", a))
  35. }
  36. 'n' => {
  37. let _a = ap.get::<c_int>();
  38. found_percent = false;
  39. Ok(())
  40. }
  41. 'p' => {
  42. let a = ap.get::<usize>();
  43. found_percent = false;
  44. w.write_fmt(format_args!("0x{:x}", a))
  45. }
  46. 's' => {
  47. let a = ap.get::<*const c_char>();
  48. found_percent = false;
  49. if a != ptr::null() {
  50. w.write_str(str::from_utf8_unchecked(platform::c_str(a)))
  51. } else {
  52. w.write_str("NULL")
  53. }
  54. }
  55. 'u' => {
  56. let a = ap.get::<c_uint>();
  57. found_percent = false;
  58. w.write_fmt(format_args!("{}", a))
  59. }
  60. 'x' => {
  61. let a = ap.get::<c_uint>();
  62. found_percent = false;
  63. w.write_fmt(format_args!("{:x}", a))
  64. }
  65. 'X' => {
  66. let a = ap.get::<c_uint>();
  67. found_percent = false;
  68. w.write_fmt(format_args!("{:X}", a))
  69. }
  70. 'o' => {
  71. let a = ap.get::<c_uint>();
  72. found_percent = false;
  73. w.write_fmt(format_args!("{:o}", a))
  74. }
  75. '-' => Ok(()),
  76. '+' => Ok(()),
  77. ' ' => Ok(()),
  78. '#' => Ok(()),
  79. '0'...'9' => Ok(()),
  80. _ => Ok(()),
  81. }.is_err()
  82. {
  83. return -1;
  84. }
  85. } else if b == b'%' {
  86. found_percent = true;
  87. } else {
  88. if w.write_u8(b).is_err() {
  89. return -1;
  90. }
  91. }
  92. }
  93. w.written as c_int
  94. }