printf.rs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. use crate::io::{self, Write};
  2. use alloc::{
  3. collections::BTreeMap,
  4. string::{String, ToString},
  5. vec::Vec,
  6. };
  7. use core::{char, cmp, f64, ffi::VaList, fmt, num::FpCategory, ops::Range, slice};
  8. use crate::{
  9. header::errno::EILSEQ,
  10. platform::{self, types::*},
  11. };
  12. // ____ _ _ _ _
  13. // | __ ) ___ (_) | ___ _ __ _ __ | | __ _| |_ ___ _
  14. // | _ \ / _ \| | |/ _ \ '__| '_ \| |/ _` | __/ _ (_)
  15. // | |_) | (_) | | | __/ | | |_) | | (_| | || __/_
  16. // |____/ \___/|_|_|\___|_| | .__/|_|\__,_|\__\___(_)
  17. // |_|
  18. #[derive(Clone, Copy, PartialEq, Eq)]
  19. enum IntKind {
  20. Byte,
  21. Short,
  22. Int,
  23. Long,
  24. LongLong,
  25. IntMax,
  26. PtrDiff,
  27. Size,
  28. }
  29. #[derive(Clone, Copy, PartialEq, Eq)]
  30. enum FmtKind {
  31. Percent,
  32. Signed,
  33. Unsigned,
  34. Scientific,
  35. Decimal,
  36. AnyNotation,
  37. String,
  38. Char,
  39. Pointer,
  40. GetWritten,
  41. }
  42. #[derive(Clone, Copy, Debug)]
  43. enum Number {
  44. Static(usize),
  45. Index(usize),
  46. Next,
  47. }
  48. impl Number {
  49. unsafe fn resolve(&self, varargs: &mut VaListCache, ap: &mut VaList) -> usize {
  50. let arg = match *self {
  51. Number::Static(num) => return num,
  52. Number::Index(i) => varargs.get(i - 1, ap, None),
  53. Number::Next => {
  54. let i = varargs.i;
  55. varargs.i += 1;
  56. varargs.get(i, ap, None)
  57. }
  58. };
  59. match arg {
  60. VaArg::c_char(i) => i as usize,
  61. VaArg::c_double(i) => i as usize,
  62. VaArg::c_int(i) => i as usize,
  63. VaArg::c_long(i) => i as usize,
  64. VaArg::c_longlong(i) => i as usize,
  65. VaArg::c_short(i) => i as usize,
  66. VaArg::intmax_t(i) => i as usize,
  67. VaArg::pointer(i) => i as usize,
  68. VaArg::ptrdiff_t(i) => i as usize,
  69. VaArg::ssize_t(i) => i as usize,
  70. VaArg::wint_t(i) => i as usize,
  71. }
  72. }
  73. }
  74. #[derive(Clone, Copy, Debug)]
  75. enum VaArg {
  76. c_char(c_char),
  77. c_double(c_double),
  78. c_int(c_int),
  79. c_long(c_long),
  80. c_longlong(c_longlong),
  81. c_short(c_short),
  82. intmax_t(intmax_t),
  83. pointer(*const c_void),
  84. ptrdiff_t(ptrdiff_t),
  85. ssize_t(ssize_t),
  86. wint_t(wint_t),
  87. }
  88. impl VaArg {
  89. unsafe fn arg_from(fmtkind: FmtKind, intkind: IntKind, ap: &mut VaList) -> VaArg {
  90. // Per the C standard using va_arg with a type with a size
  91. // less than that of an int for integers and double for floats
  92. // is invalid. As a result any arguments smaller than an int or
  93. // double passed to a function will be promoted to the smallest
  94. // possible size. The VaList::arg function will handle this
  95. // automagically.
  96. match (fmtkind, intkind) {
  97. (FmtKind::Percent, _) => panic!("Can't call arg_from on %"),
  98. (FmtKind::Char, IntKind::Long) | (FmtKind::Char, IntKind::LongLong) => {
  99. VaArg::wint_t(ap.arg::<wint_t>())
  100. }
  101. (FmtKind::Char, _)
  102. | (FmtKind::Unsigned, IntKind::Byte)
  103. | (FmtKind::Signed, IntKind::Byte) => VaArg::c_char(ap.arg::<c_char>()),
  104. (FmtKind::Unsigned, IntKind::Short) | (FmtKind::Signed, IntKind::Short) => {
  105. VaArg::c_short(ap.arg::<c_short>())
  106. }
  107. (FmtKind::Unsigned, IntKind::Int) | (FmtKind::Signed, IntKind::Int) => {
  108. VaArg::c_int(ap.arg::<c_int>())
  109. }
  110. (FmtKind::Unsigned, IntKind::Long) | (FmtKind::Signed, IntKind::Long) => {
  111. VaArg::c_long(ap.arg::<c_long>())
  112. }
  113. (FmtKind::Unsigned, IntKind::LongLong) | (FmtKind::Signed, IntKind::LongLong) => {
  114. VaArg::c_longlong(ap.arg::<c_longlong>())
  115. }
  116. (FmtKind::Unsigned, IntKind::IntMax) | (FmtKind::Signed, IntKind::IntMax) => {
  117. VaArg::intmax_t(ap.arg::<intmax_t>())
  118. }
  119. (FmtKind::Unsigned, IntKind::PtrDiff) | (FmtKind::Signed, IntKind::PtrDiff) => {
  120. VaArg::ptrdiff_t(ap.arg::<ptrdiff_t>())
  121. }
  122. (FmtKind::Unsigned, IntKind::Size) | (FmtKind::Signed, IntKind::Size) => {
  123. VaArg::ssize_t(ap.arg::<ssize_t>())
  124. }
  125. (FmtKind::AnyNotation, _) | (FmtKind::Decimal, _) | (FmtKind::Scientific, _) => {
  126. VaArg::c_double(ap.arg::<c_double>())
  127. }
  128. (FmtKind::GetWritten, _) | (FmtKind::Pointer, _) | (FmtKind::String, _) => {
  129. VaArg::pointer(ap.arg::<*const c_void>())
  130. }
  131. }
  132. }
  133. unsafe fn transmute(&self, fmtkind: FmtKind, intkind: IntKind) -> VaArg {
  134. // At this point, there are conflicting printf arguments. An
  135. // example of this is:
  136. // ```c
  137. // printf("%1$d %1$lf\n", 5, 0.1);
  138. // ```
  139. // We handle it just like glibc: We read it from the VaList
  140. // using the *last* argument type, but we transmute it when we
  141. // try to access the other ones.
  142. union Untyped {
  143. c_char: c_char,
  144. c_double: c_double,
  145. c_int: c_int,
  146. c_long: c_long,
  147. c_longlong: c_longlong,
  148. c_short: c_short,
  149. intmax_t: intmax_t,
  150. pointer: *const c_void,
  151. ptrdiff_t: ptrdiff_t,
  152. ssize_t: ssize_t,
  153. wint_t: wint_t,
  154. }
  155. let untyped = match *self {
  156. VaArg::c_char(i) => Untyped { c_char: i },
  157. VaArg::c_double(i) => Untyped { c_double: i },
  158. VaArg::c_int(i) => Untyped { c_int: i },
  159. VaArg::c_long(i) => Untyped { c_long: i },
  160. VaArg::c_longlong(i) => Untyped { c_longlong: i },
  161. VaArg::c_short(i) => Untyped { c_short: i },
  162. VaArg::intmax_t(i) => Untyped { intmax_t: i },
  163. VaArg::pointer(i) => Untyped { pointer: i },
  164. VaArg::ptrdiff_t(i) => Untyped { ptrdiff_t: i },
  165. VaArg::ssize_t(i) => Untyped { ssize_t: i },
  166. VaArg::wint_t(i) => Untyped { wint_t: i },
  167. };
  168. match (fmtkind, intkind) {
  169. (FmtKind::Percent, _) => panic!("Can't call transmute on %"),
  170. (FmtKind::Char, IntKind::Long) | (FmtKind::Char, IntKind::LongLong) => {
  171. VaArg::wint_t(untyped.wint_t)
  172. }
  173. (FmtKind::Char, _)
  174. | (FmtKind::Unsigned, IntKind::Byte)
  175. | (FmtKind::Signed, IntKind::Byte) => VaArg::c_char(untyped.c_char),
  176. (FmtKind::Unsigned, IntKind::Short) | (FmtKind::Signed, IntKind::Short) => {
  177. VaArg::c_short(untyped.c_short)
  178. }
  179. (FmtKind::Unsigned, IntKind::Int) | (FmtKind::Signed, IntKind::Int) => {
  180. VaArg::c_int(untyped.c_int)
  181. }
  182. (FmtKind::Unsigned, IntKind::Long) | (FmtKind::Signed, IntKind::Long) => {
  183. VaArg::c_long(untyped.c_long)
  184. }
  185. (FmtKind::Unsigned, IntKind::LongLong) | (FmtKind::Signed, IntKind::LongLong) => {
  186. VaArg::c_longlong(untyped.c_longlong)
  187. }
  188. (FmtKind::Unsigned, IntKind::IntMax) | (FmtKind::Signed, IntKind::IntMax) => {
  189. VaArg::intmax_t(untyped.intmax_t)
  190. }
  191. (FmtKind::Unsigned, IntKind::PtrDiff) | (FmtKind::Signed, IntKind::PtrDiff) => {
  192. VaArg::ptrdiff_t(untyped.ptrdiff_t)
  193. }
  194. (FmtKind::Unsigned, IntKind::Size) | (FmtKind::Signed, IntKind::Size) => {
  195. VaArg::ssize_t(untyped.ssize_t)
  196. }
  197. (FmtKind::AnyNotation, _) | (FmtKind::Decimal, _) | (FmtKind::Scientific, _) => {
  198. VaArg::c_double(untyped.c_double)
  199. }
  200. (FmtKind::GetWritten, _) | (FmtKind::Pointer, _) | (FmtKind::String, _) => {
  201. VaArg::pointer(untyped.pointer)
  202. }
  203. }
  204. }
  205. }
  206. #[derive(Default)]
  207. struct VaListCache {
  208. args: Vec<VaArg>,
  209. i: usize,
  210. }
  211. impl VaListCache {
  212. unsafe fn get(
  213. &mut self,
  214. i: usize,
  215. ap: &mut VaList,
  216. default: Option<(FmtKind, IntKind)>,
  217. ) -> VaArg {
  218. if let Some(&arg) = self.args.get(i) {
  219. let mut arg = arg;
  220. if let Some((fmtkind, intkind)) = default {
  221. arg = arg.transmute(fmtkind, intkind);
  222. }
  223. return arg;
  224. }
  225. while self.args.len() < i {
  226. // We can't POSSIBLY know the type if we reach this
  227. // point. Reaching here means there are unused gaps in the
  228. // arguments. Ultimately we'll have to settle down with
  229. // defaulting to c_int.
  230. self.args.push(VaArg::c_int(ap.arg::<c_int>()))
  231. }
  232. self.args.push(match default {
  233. Some((fmtkind, intkind)) => VaArg::arg_from(fmtkind, intkind, ap),
  234. None => VaArg::c_int(ap.arg::<c_int>()),
  235. });
  236. self.args[i]
  237. }
  238. }
  239. // ___ _ _ _ _
  240. // |_ _|_ __ ___ _ __ | | ___ _ __ ___ ___ _ __ | |_ __ _| |_(_) ___ _ __ _
  241. // | || '_ ` _ \| '_ \| |/ _ \ '_ ` _ \ / _ \ '_ \| __/ _` | __| |/ _ \| '_ \(_)
  242. // | || | | | | | |_) | | __/ | | | | | __/ | | | || (_| | |_| | (_) | | | |_
  243. // |___|_| |_| |_| .__/|_|\___|_| |_| |_|\___|_| |_|\__\__,_|\__|_|\___/|_| |_(_)
  244. // |_|
  245. enum FmtCase {
  246. Lower,
  247. Upper,
  248. }
  249. // The spelled-out "infinity"/"INFINITY" is also permitted by the standard
  250. static INF_STR_LOWER: &str = "inf";
  251. static INF_STR_UPPER: &str = "INF";
  252. static NAN_STR_LOWER: &str = "nan";
  253. static NAN_STR_UPPER: &str = "NAN";
  254. unsafe fn pop_int_raw(format: &mut *const u8) -> Option<usize> {
  255. let mut int = None;
  256. while let Some(digit) = (**format as char).to_digit(10) {
  257. *format = format.add(1);
  258. if int.is_none() {
  259. int = Some(0);
  260. }
  261. *int.as_mut().unwrap() *= 10;
  262. *int.as_mut().unwrap() += digit as usize;
  263. }
  264. int
  265. }
  266. unsafe fn pop_index(format: &mut *const u8) -> Option<usize> {
  267. // Peek ahead for a positional argument:
  268. let mut format2 = *format;
  269. if let Some(i) = pop_int_raw(&mut format2) {
  270. if *format2 == b'$' {
  271. *format = format2.add(1);
  272. return Some(i);
  273. }
  274. }
  275. None
  276. }
  277. unsafe fn pop_int(format: &mut *const u8) -> Option<Number> {
  278. if **format == b'*' {
  279. *format = format.add(1);
  280. Some(pop_index(format).map(Number::Index).unwrap_or(Number::Next))
  281. } else {
  282. pop_int_raw(format).map(Number::Static)
  283. }
  284. }
  285. unsafe fn fmt_int<I>(fmt: u8, i: I) -> String
  286. where
  287. I: fmt::Display + fmt::Octal + fmt::LowerHex + fmt::UpperHex,
  288. {
  289. match fmt {
  290. b'o' => format!("{:o}", i),
  291. b'u' => i.to_string(),
  292. b'x' => format!("{:x}", i),
  293. b'X' => format!("{:X}", i),
  294. _ => panic!(
  295. "fmt_int should never be called with the fmt {:?}",
  296. fmt as char
  297. ),
  298. }
  299. }
  300. fn pad<W: Write>(
  301. w: &mut W,
  302. current_side: bool,
  303. pad_char: u8,
  304. range: Range<usize>,
  305. ) -> io::Result<()> {
  306. if current_side {
  307. for _ in range {
  308. w.write_all(&[pad_char])?;
  309. }
  310. }
  311. Ok(())
  312. }
  313. fn abs(float: c_double) -> c_double {
  314. // Don't ask me whe float.abs() seems absent...
  315. if float.is_sign_negative() {
  316. -float
  317. } else {
  318. float
  319. }
  320. }
  321. fn float_string(float: c_double, precision: usize, trim: bool) -> String {
  322. let mut string = format!("{:.p$}", float, p = precision);
  323. if trim && string.contains('.') {
  324. let truncate = {
  325. let slice = string.trim_end_matches('0');
  326. let mut truncate = slice.len();
  327. if slice.ends_with('.') {
  328. truncate -= 1;
  329. }
  330. truncate
  331. };
  332. string.truncate(truncate);
  333. }
  334. string
  335. }
  336. fn float_exp(mut float: c_double) -> (c_double, isize) {
  337. let mut exp: isize = 0;
  338. while abs(float) >= 10.0 {
  339. float /= 10.0;
  340. exp += 1;
  341. }
  342. while f64::EPSILON < abs(float) && abs(float) < 1.0 {
  343. float *= 10.0;
  344. exp -= 1;
  345. }
  346. (float, exp)
  347. }
  348. fn fmt_float_exp<W: Write>(
  349. w: &mut W,
  350. exp_fmt: u8,
  351. trim: bool,
  352. precision: usize,
  353. float: c_double,
  354. exp: isize,
  355. left: bool,
  356. pad_space: usize,
  357. pad_zero: usize,
  358. ) -> io::Result<()> {
  359. let mut exp2 = exp;
  360. let mut exp_len = 1;
  361. while exp2 >= 10 {
  362. exp2 /= 10;
  363. exp_len += 1;
  364. }
  365. let string = float_string(float, precision, trim);
  366. let len = string.len() + 2 + 2.max(exp_len);
  367. pad(w, !left, b' ', len..pad_space)?;
  368. let bytes = if string.starts_with('-') {
  369. w.write_all(&[b'-'])?;
  370. &string.as_bytes()[1..]
  371. } else {
  372. string.as_bytes()
  373. };
  374. pad(w, !left, b'0', len..pad_zero)?;
  375. w.write_all(bytes)?;
  376. write!(w, "{}{:+03}", exp_fmt as char, exp)?;
  377. pad(w, left, b' ', len..pad_space)?;
  378. Ok(())
  379. }
  380. fn fmt_float_normal<W: Write>(
  381. w: &mut W,
  382. trim: bool,
  383. precision: usize,
  384. float: c_double,
  385. left: bool,
  386. pad_space: usize,
  387. pad_zero: usize,
  388. ) -> io::Result<usize> {
  389. let string = float_string(float, precision, trim);
  390. pad(w, !left, b' ', string.len()..pad_space)?;
  391. let bytes = if string.starts_with('-') {
  392. w.write_all(&[b'-'])?;
  393. &string.as_bytes()[1..]
  394. } else {
  395. string.as_bytes()
  396. };
  397. pad(w, true, b'0', string.len()..pad_zero)?;
  398. w.write_all(bytes)?;
  399. pad(w, left, b' ', string.len()..pad_space)?;
  400. Ok(string.len())
  401. }
  402. /// Write ±infinity or ±NaN representation for any floating-point style
  403. fn fmt_float_nonfinite<W: Write>(w: &mut W, float: c_double, case: FmtCase) -> io::Result<()> {
  404. if float.is_sign_negative() {
  405. w.write_all(&[b'-'])?;
  406. }
  407. let nonfinite_str = match float.classify() {
  408. FpCategory::Infinite => match case {
  409. FmtCase::Lower => INF_STR_LOWER,
  410. FmtCase::Upper => INF_STR_UPPER,
  411. },
  412. FpCategory::Nan => match case {
  413. FmtCase::Lower => NAN_STR_LOWER,
  414. FmtCase::Upper => NAN_STR_UPPER,
  415. },
  416. _ => {
  417. // This function should only be called with infinite or NaN value.
  418. panic!("this should not be possible")
  419. }
  420. };
  421. w.write_all(nonfinite_str.as_bytes())?;
  422. Ok(())
  423. }
  424. #[derive(Clone, Copy)]
  425. struct PrintfIter {
  426. format: *const u8,
  427. }
  428. #[derive(Clone, Copy)]
  429. struct PrintfArg {
  430. index: Option<usize>,
  431. alternate: bool,
  432. zero: bool,
  433. left: bool,
  434. sign_reserve: bool,
  435. sign_always: bool,
  436. min_width: Number,
  437. precision: Option<Number>,
  438. pad_space: Number,
  439. pad_zero: Number,
  440. intkind: IntKind,
  441. fmt: u8,
  442. fmtkind: FmtKind,
  443. }
  444. enum PrintfFmt {
  445. Plain(&'static [u8]),
  446. Arg(PrintfArg),
  447. }
  448. impl Iterator for PrintfIter {
  449. type Item = Result<PrintfFmt, ()>;
  450. fn next(&mut self) -> Option<Self::Item> {
  451. unsafe {
  452. // Send PrintfFmt::Plain until the next %
  453. let mut len = 0;
  454. while *self.format.add(len) != 0 && *self.format.add(len) != b'%' {
  455. len += 1;
  456. }
  457. if len > 0 {
  458. let slice = slice::from_raw_parts(self.format as *const u8, len);
  459. self.format = self.format.add(len);
  460. return Some(Ok(PrintfFmt::Plain(slice)));
  461. }
  462. self.format = self.format.add(len);
  463. if *self.format == 0 {
  464. return None;
  465. }
  466. // *self.format is guaranteed to be '%' at this point
  467. self.format = self.format.add(1);
  468. let mut peekahead = self.format;
  469. let index = pop_index(&mut peekahead).map(|i| {
  470. self.format = peekahead;
  471. i
  472. });
  473. // Flags:
  474. let mut alternate = false;
  475. let mut zero = false;
  476. let mut left = false;
  477. let mut sign_reserve = false;
  478. let mut sign_always = false;
  479. loop {
  480. match *self.format {
  481. b'#' => alternate = true,
  482. b'0' => zero = true,
  483. b'-' => left = true,
  484. b' ' => sign_reserve = true,
  485. b'+' => sign_always = true,
  486. _ => break,
  487. }
  488. self.format = self.format.add(1);
  489. }
  490. // Width and precision:
  491. let min_width = pop_int(&mut self.format).unwrap_or(Number::Static(0));
  492. let precision = if *self.format == b'.' {
  493. self.format = self.format.add(1);
  494. match pop_int(&mut self.format) {
  495. int @ Some(_) => int,
  496. None => return Some(Err(())),
  497. }
  498. } else {
  499. None
  500. };
  501. let pad_space = if zero { Number::Static(0) } else { min_width };
  502. let pad_zero = if zero { min_width } else { Number::Static(0) };
  503. // Integer size:
  504. let mut intkind = IntKind::Int;
  505. loop {
  506. intkind = match *self.format {
  507. b'h' => {
  508. if intkind == IntKind::Short || intkind == IntKind::Byte {
  509. IntKind::Byte
  510. } else {
  511. IntKind::Short
  512. }
  513. }
  514. b'j' => IntKind::IntMax,
  515. b'l' => {
  516. if intkind == IntKind::Long || intkind == IntKind::LongLong {
  517. IntKind::LongLong
  518. } else {
  519. IntKind::Long
  520. }
  521. }
  522. b'q' | b'L' => IntKind::LongLong,
  523. b't' => IntKind::PtrDiff,
  524. b'z' => IntKind::Size,
  525. _ => break,
  526. };
  527. self.format = self.format.add(1);
  528. }
  529. let fmt = *self.format;
  530. let fmtkind = match fmt {
  531. b'%' => FmtKind::Percent,
  532. b'd' | b'i' => FmtKind::Signed,
  533. b'o' | b'u' | b'x' | b'X' => FmtKind::Unsigned,
  534. b'e' | b'E' => FmtKind::Scientific,
  535. b'f' | b'F' => FmtKind::Decimal,
  536. b'g' | b'G' => FmtKind::AnyNotation,
  537. b's' => FmtKind::String,
  538. b'c' => FmtKind::Char,
  539. b'p' => FmtKind::Pointer,
  540. b'n' => FmtKind::GetWritten,
  541. _ => return Some(Err(())),
  542. };
  543. self.format = self.format.add(1);
  544. Some(Ok(PrintfFmt::Arg(PrintfArg {
  545. index,
  546. alternate,
  547. zero,
  548. left,
  549. sign_reserve,
  550. sign_always,
  551. min_width,
  552. precision,
  553. pad_space,
  554. pad_zero,
  555. intkind,
  556. fmt,
  557. fmtkind,
  558. })))
  559. }
  560. }
  561. }
  562. unsafe fn inner_printf<W: Write>(w: W, format: *const c_char, mut ap: VaList) -> io::Result<c_int> {
  563. let w = &mut platform::CountingWriter::new(w);
  564. let iterator = PrintfIter {
  565. format: format as *const u8,
  566. };
  567. // Pre-fetch vararg types
  568. let mut varargs = VaListCache::default();
  569. let mut positional = BTreeMap::new();
  570. // ^ NOTE: This depends on the sorted order, do not change to HashMap or whatever
  571. for section in iterator {
  572. let arg = match section {
  573. Ok(PrintfFmt::Plain(text)) => continue,
  574. Ok(PrintfFmt::Arg(arg)) => arg,
  575. Err(()) => return Ok(-1),
  576. };
  577. if arg.fmtkind == FmtKind::Percent {
  578. continue;
  579. }
  580. for num in &[arg.min_width, arg.precision.unwrap_or(Number::Static(0))] {
  581. match num {
  582. Number::Next => varargs.args.push(VaArg::c_int(ap.arg::<c_int>())),
  583. Number::Index(i) => {
  584. positional.insert(i - 1, (FmtKind::Signed, IntKind::Int));
  585. }
  586. Number::Static(_) => (),
  587. }
  588. }
  589. match arg.index {
  590. Some(i) => {
  591. positional.insert(i - 1, (arg.fmtkind, arg.intkind));
  592. }
  593. None => varargs
  594. .args
  595. .push(VaArg::arg_from(arg.fmtkind, arg.intkind, &mut ap)),
  596. }
  597. }
  598. // Make sure, in order, the positional arguments exist with the specified type
  599. for (i, arg) in positional {
  600. varargs.get(i, &mut ap, Some(arg));
  601. }
  602. // Main loop
  603. for section in iterator {
  604. let arg = match section {
  605. Ok(PrintfFmt::Plain(text)) => {
  606. w.write_all(text)?;
  607. continue;
  608. }
  609. Ok(PrintfFmt::Arg(arg)) => arg,
  610. Err(()) => return Ok(-1),
  611. };
  612. let alternate = arg.alternate;
  613. let zero = arg.zero;
  614. let left = arg.left;
  615. let sign_reserve = arg.sign_reserve;
  616. let sign_always = arg.sign_always;
  617. let min_width = arg.min_width.resolve(&mut varargs, &mut ap);
  618. let precision = arg.precision.map(|n| n.resolve(&mut varargs, &mut ap));
  619. let pad_space = arg.pad_space.resolve(&mut varargs, &mut ap);
  620. let pad_zero = arg.pad_zero.resolve(&mut varargs, &mut ap);
  621. let intkind = arg.intkind;
  622. let fmt = arg.fmt;
  623. let fmtkind = arg.fmtkind;
  624. let fmtcase = match fmt {
  625. b'x' | b'f' | b'e' | b'g' => Some(FmtCase::Lower),
  626. b'X' | b'F' | b'E' | b'G' => Some(FmtCase::Upper),
  627. _ => None,
  628. };
  629. let index = arg.index.map(|i| i - 1).unwrap_or_else(|| {
  630. if fmtkind == FmtKind::Percent {
  631. 0
  632. } else {
  633. let i = varargs.i;
  634. varargs.i += 1;
  635. i
  636. }
  637. });
  638. match fmtkind {
  639. FmtKind::Percent => w.write_all(&[b'%'])?,
  640. FmtKind::Signed => {
  641. let string = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  642. VaArg::c_char(i) => i.to_string(),
  643. VaArg::c_double(i) => panic!("this should not be possible"),
  644. VaArg::c_int(i) => i.to_string(),
  645. VaArg::c_long(i) => i.to_string(),
  646. VaArg::c_longlong(i) => i.to_string(),
  647. VaArg::c_short(i) => i.to_string(),
  648. VaArg::intmax_t(i) => i.to_string(),
  649. VaArg::pointer(i) => (i as usize).to_string(),
  650. VaArg::ptrdiff_t(i) => i.to_string(),
  651. VaArg::ssize_t(i) => i.to_string(),
  652. VaArg::wint_t(_) => unreachable!("this should not be possible"),
  653. };
  654. let positive = !string.starts_with('-');
  655. let zero = precision == Some(0) && string == "0";
  656. let mut len = string.len();
  657. let mut final_len = string.len().max(precision.unwrap_or(0));
  658. if positive && (sign_reserve || sign_always) {
  659. final_len += 1;
  660. }
  661. if zero {
  662. len = 0;
  663. final_len = 0;
  664. }
  665. pad(w, !left, b' ', final_len..pad_space)?;
  666. let bytes = if positive {
  667. if sign_reserve {
  668. w.write_all(&[b' '])?;
  669. } else if sign_always {
  670. w.write_all(&[b'+'])?;
  671. }
  672. string.as_bytes()
  673. } else {
  674. w.write_all(&[b'-'])?;
  675. &string.as_bytes()[1..]
  676. };
  677. pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?;
  678. if !zero {
  679. w.write_all(bytes)?;
  680. }
  681. pad(w, left, b' ', final_len..pad_space)?;
  682. }
  683. FmtKind::Unsigned => {
  684. let string = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  685. VaArg::c_char(i) => fmt_int(fmt, i as c_uchar),
  686. VaArg::c_double(i) => panic!("this should not be possible"),
  687. VaArg::c_int(i) => fmt_int(fmt, i as c_uint),
  688. VaArg::c_long(i) => fmt_int(fmt, i as c_ulong),
  689. VaArg::c_longlong(i) => fmt_int(fmt, i as c_ulonglong),
  690. VaArg::c_short(i) => fmt_int(fmt, i as c_ushort),
  691. VaArg::intmax_t(i) => fmt_int(fmt, i as uintmax_t),
  692. VaArg::pointer(i) => fmt_int(fmt, i as usize),
  693. VaArg::ptrdiff_t(i) => fmt_int(fmt, i as size_t),
  694. VaArg::ssize_t(i) => fmt_int(fmt, i as size_t),
  695. VaArg::wint_t(_) => unreachable!("this should not be possible"),
  696. };
  697. let zero = precision == Some(0) && string == "0";
  698. // If this int is padded out to be larger than it is, don't
  699. // add an extra zero if octal.
  700. let no_precision = precision.map(|pad| pad < string.len()).unwrap_or(true);
  701. let len;
  702. let final_len = if zero {
  703. len = 0;
  704. 0
  705. } else {
  706. len = string.len();
  707. len.max(precision.unwrap_or(0))
  708. + if alternate && string != "0" {
  709. match fmt {
  710. b'o' if no_precision => 1,
  711. b'x' | b'X' => 2,
  712. _ => 0,
  713. }
  714. } else {
  715. 0
  716. }
  717. };
  718. pad(w, !left, b' ', final_len..pad_space)?;
  719. if alternate && string != "0" {
  720. match fmt {
  721. b'o' if no_precision => w.write_all(&[b'0'])?,
  722. b'x' => w.write_all(&[b'0', b'x'])?,
  723. b'X' => w.write_all(&[b'0', b'X'])?,
  724. _ => (),
  725. }
  726. }
  727. pad(w, true, b'0', len..precision.unwrap_or(pad_zero))?;
  728. if !zero {
  729. w.write_all(string.as_bytes())?;
  730. }
  731. pad(w, left, b' ', final_len..pad_space)?;
  732. }
  733. FmtKind::Scientific => {
  734. let float = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  735. VaArg::c_double(i) => i,
  736. _ => panic!("this should not be possible"),
  737. };
  738. if float.is_finite() {
  739. let (float, exp) = float_exp(float);
  740. let precision = precision.unwrap_or(6);
  741. fmt_float_exp(
  742. w, fmt, false, precision, float, exp, left, pad_space, pad_zero,
  743. )?;
  744. } else {
  745. fmt_float_nonfinite(w, float, fmtcase.unwrap())?;
  746. }
  747. }
  748. FmtKind::Decimal => {
  749. let float = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  750. VaArg::c_double(i) => i,
  751. _ => panic!("this should not be possible"),
  752. };
  753. if float.is_finite() {
  754. let precision = precision.unwrap_or(6);
  755. fmt_float_normal(w, false, precision, float, left, pad_space, pad_zero)?;
  756. } else {
  757. fmt_float_nonfinite(w, float, fmtcase.unwrap())?;
  758. }
  759. }
  760. FmtKind::AnyNotation => {
  761. let float = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  762. VaArg::c_double(i) => i,
  763. _ => panic!("this should not be possible"),
  764. };
  765. if float.is_finite() {
  766. let (log, exp) = float_exp(float);
  767. let exp_fmt = b'E' | (fmt & 32);
  768. let precision = precision.unwrap_or(6);
  769. let use_exp_format = exp < -4 || exp >= precision as isize;
  770. if use_exp_format {
  771. // Length of integral part will always be 1 here,
  772. // because that's how x/floor(log10(x)) works
  773. let precision = precision.saturating_sub(1);
  774. fmt_float_exp(
  775. w, exp_fmt, true, precision, log, exp, left, pad_space, pad_zero,
  776. )?;
  777. } else {
  778. // Length of integral part will be the exponent of
  779. // the unused logarithm, unless the exponent is
  780. // negative which in case the integral part must
  781. // of course be 0, 1 in length
  782. let len = 1 + cmp::max(0, exp) as usize;
  783. let precision = precision.saturating_sub(len);
  784. fmt_float_normal(w, true, precision, float, left, pad_space, pad_zero)?;
  785. }
  786. } else {
  787. fmt_float_nonfinite(w, float, fmtcase.unwrap())?;
  788. }
  789. }
  790. FmtKind::String => {
  791. let ptr = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  792. VaArg::pointer(p) => p,
  793. _ => panic!("this should not be possible"),
  794. } as *const c_char;
  795. if ptr.is_null() {
  796. w.write_all(b"(null)")?;
  797. } else {
  798. let max = precision.unwrap_or(::core::usize::MAX);
  799. if intkind == IntKind::Long || intkind == IntKind::LongLong {
  800. // Handle wchar_t
  801. let mut ptr = ptr as *const wchar_t;
  802. let mut string = String::new();
  803. while *ptr != 0 {
  804. let c = match char::from_u32(*ptr as _) {
  805. Some(c) => c,
  806. None => {
  807. platform::errno = EILSEQ;
  808. return Err(io::last_os_error());
  809. }
  810. };
  811. if string.len() + c.len_utf8() >= max {
  812. break;
  813. }
  814. string.push(c);
  815. ptr = ptr.add(1);
  816. }
  817. pad(w, !left, b' ', string.len()..pad_space)?;
  818. w.write_all(string.as_bytes())?;
  819. pad(w, left, b' ', string.len()..pad_space)?;
  820. } else {
  821. let mut len = 0;
  822. while *ptr.add(len) != 0 && len < max {
  823. len += 1;
  824. }
  825. pad(w, !left, b' ', len..pad_space)?;
  826. w.write_all(slice::from_raw_parts(ptr as *const u8, len))?;
  827. pad(w, left, b' ', len..pad_space)?;
  828. }
  829. }
  830. }
  831. FmtKind::Char => match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  832. VaArg::c_char(c) => {
  833. pad(w, !left, b' ', 1..pad_space)?;
  834. w.write_all(&[c as u8])?;
  835. pad(w, left, b' ', 1..pad_space)?;
  836. }
  837. VaArg::wint_t(c) => {
  838. let c = match char::from_u32(c as _) {
  839. Some(c) => c,
  840. None => {
  841. platform::errno = EILSEQ;
  842. return Err(io::last_os_error());
  843. }
  844. };
  845. let mut buf = [0; 4];
  846. pad(w, !left, b' ', 1..pad_space)?;
  847. w.write_all(c.encode_utf8(&mut buf).as_bytes())?;
  848. pad(w, left, b' ', 1..pad_space)?;
  849. }
  850. _ => unreachable!("this should not be possible"),
  851. },
  852. FmtKind::Pointer => {
  853. let ptr = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  854. VaArg::pointer(p) => p,
  855. _ => panic!("this should not be possible"),
  856. };
  857. let mut len = 1;
  858. if ptr.is_null() {
  859. len = "(nil)".len();
  860. } else {
  861. let mut ptr = ptr as usize;
  862. while ptr >= 10 {
  863. ptr /= 10;
  864. len += 1;
  865. }
  866. }
  867. pad(w, !left, b' ', len..pad_space)?;
  868. if ptr.is_null() {
  869. write!(w, "(nil)")?;
  870. } else {
  871. write!(w, "0x{:x}", ptr as usize)?;
  872. }
  873. pad(w, left, b' ', len..pad_space)?;
  874. }
  875. FmtKind::GetWritten => {
  876. let ptr = match varargs.get(index, &mut ap, Some((arg.fmtkind, arg.intkind))) {
  877. VaArg::pointer(p) => p,
  878. _ => panic!("this should not be possible"),
  879. };
  880. match intkind {
  881. IntKind::Byte => *(ptr as *mut c_char) = w.written as c_char,
  882. IntKind::Short => *(ptr as *mut c_short) = w.written as c_short,
  883. IntKind::Int => *(ptr as *mut c_int) = w.written as c_int,
  884. IntKind::Long => *(ptr as *mut c_long) = w.written as c_long,
  885. IntKind::LongLong => *(ptr as *mut c_longlong) = w.written as c_longlong,
  886. IntKind::IntMax => *(ptr as *mut intmax_t) = w.written as intmax_t,
  887. IntKind::PtrDiff => *(ptr as *mut ptrdiff_t) = w.written as ptrdiff_t,
  888. IntKind::Size => *(ptr as *mut size_t) = w.written as size_t,
  889. }
  890. }
  891. }
  892. }
  893. Ok(w.written as c_int)
  894. }
  895. pub unsafe fn printf<W: Write>(w: W, format: *const c_char, ap: VaList) -> c_int {
  896. inner_printf(w, format, ap).unwrap_or(-1)
  897. }