1 //! Standard library macros 2 //! 3 //! This module contains a set of macros which are exported from the standard 4 //! library. Each macro is available for use when linking against the standard 5 //! library. 6 // ignore-tidy-dbg 7 8 //#[doc = include_str!("../../core/src/macros/panic.md")] 9 #[macro_export] 10 #[rustc_builtin_macro(std_panic)] 11 #[allow_internal_unstable(edition_panic)] 12 #[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")] 13 macro_rules! panic { 14 // Expands to either `$crate::std::panic::panic_2015` or `$crate::std::panic::panic_2021` 15 // depending on the edition of the caller. 16 ($($arg:tt)*) => { 17 /* compiler built-in */ 18 }; 19 } 20 21 /// Prints to the standard output. 22 /// 23 /// Equivalent to the [`println!`] macro except that a newline is not printed at 24 /// the end of the message. 25 /// 26 /// Note that stdout is frequently line-buffered by default so it may be 27 /// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted 28 /// immediately. 29 /// 30 /// The `print!` macro will lock the standard output on each call. If you call 31 /// `print!` within a hot loop, this behavior may be the bottleneck of the loop. 32 /// To avoid this, lock stdout with [`io::stdout().lock()`][lock]: 33 /// ``` 34 /// use std::io::{stdout, Write}; 35 /// 36 /// let mut lock = stdout().lock(); 37 /// write!(lock, "hello world").unwrap(); 38 /// ``` 39 /// 40 /// Use `print!` only for the primary output of your program. Use 41 /// [`eprint!`] instead to print error and progress messages. 42 /// 43 /// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) 44 /// for details of the macro argument syntax. 45 /// 46 /// [flush]: crate::std::io::Write::flush 47 /// [`println!`]: crate::std::println 48 /// [`eprint!`]: crate::std::eprint 49 /// [lock]: crate::std::io::Stdout 50 /// 51 /// # Panics 52 /// 53 /// Panics if writing to `io::stdout()` fails. 54 /// 55 /// Writing to non-blocking stdout can cause an error, which will lead 56 /// this macro to panic. 57 /// 58 /// # Examples 59 /// 60 /// ``` 61 /// use std::io::{self, Write}; 62 /// 63 /// print!("this "); 64 /// print!("will "); 65 /// print!("be "); 66 /// print!("on "); 67 /// print!("the "); 68 /// print!("same "); 69 /// print!("line "); 70 /// 71 /// io::stdout().flush().unwrap(); 72 /// 73 /// print!("this string has a newline, why not choose println! instead?\n"); 74 /// 75 /// io::stdout().flush().unwrap(); 76 /// ``` 77 #[macro_export] 78 #[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")] 79 #[allow_internal_unstable(print_internals)] 80 macro_rules! print { 81 ($($arg:tt)*) => {{ 82 $crate::std::io::_print($crate::std::format_args!($($arg)*)); 83 }}; 84 } 85 86 /// Prints to the standard output, with a newline. 87 /// 88 /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone 89 /// (no additional CARRIAGE RETURN (`\r`/`U+000D`)). 90 /// 91 /// This macro uses the same syntax as [`format!`], but writes to the standard output instead. 92 /// See [`std::fmt`] for more information. 93 /// 94 /// The `println!` macro will lock the standard output on each call. If you call 95 /// `println!` within a hot loop, this behavior may be the bottleneck of the loop. 96 /// To avoid this, lock stdout with [`io::stdout().lock()`][lock]: 97 /// ``` 98 /// use std::io::{stdout, Write}; 99 /// 100 /// let mut lock = stdout().lock(); 101 /// writeln!(lock, "hello world").unwrap(); 102 /// ``` 103 /// 104 /// Use `println!` only for the primary output of your program. Use 105 /// [`eprintln!`] instead to print error and progress messages. 106 /// 107 /// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) 108 /// for details of the macro argument syntax. 109 /// 110 /// [`std::fmt`]: crate::std::fmt 111 /// [`eprintln!`]: crate::std::eprintln 112 /// [lock]: crate::std::io::Stdout 113 /// 114 /// # Panics 115 /// 116 /// Panics if writing to [`io::stdout`] fails. 117 /// 118 /// Writing to non-blocking stdout can cause an error, which will lead 119 /// this macro to panic. 120 /// 121 /// [`io::stdout`]: crate::std::io::stdout 122 /// 123 /// # Examples 124 /// 125 /// ``` 126 /// println!(); // prints just a newline 127 /// println!("hello there!"); 128 /// println!("format {} arguments", "some"); 129 /// let local_variable = "some"; 130 /// println!("format {local_variable} arguments"); 131 /// ``` 132 #[macro_export] 133 #[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")] 134 #[allow_internal_unstable(print_internals, format_args_nl)] 135 macro_rules! println { 136 () => { 137 $crate::std::print!("\n") 138 }; 139 ($($arg:tt)*) => {{ 140 $crate::std::io::_print($crate::std::format_args_nl!($($arg)*)); 141 }}; 142 } 143 144 /// Prints to the standard error. 145 /// 146 /// Equivalent to the [`print!`] macro, except that output goes to 147 /// [`io::stderr`] instead of [`io::stdout`]. See [`print!`] for 148 /// example usage. 149 /// 150 /// Use `eprint!` only for error and progress messages. Use `print!` 151 /// instead for the primary output of your program. 152 /// 153 /// [`io::stderr`]: crate::std::io::stderr 154 /// [`io::stdout`]: crate::std::io::stdout 155 /// 156 /// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) 157 /// for details of the macro argument syntax. 158 /// 159 /// # Panics 160 /// 161 /// Panics if writing to `io::stderr` fails. 162 /// 163 /// Writing to non-blocking stderr can cause an error, which will lead 164 /// this macro to panic. 165 /// 166 /// # Examples 167 /// 168 /// ``` 169 /// eprint!("Error: Could not complete task"); 170 /// ``` 171 #[macro_export] 172 #[cfg_attr(not(test), rustc_diagnostic_item = "eprint_macro")] 173 #[allow_internal_unstable(print_internals)] 174 macro_rules! eprint { 175 ($($arg:tt)*) => {{ 176 $crate::std::io::_eprint($crate::std::format_args!($($arg)*)); 177 }}; 178 } 179 180 /// Prints to the standard error, with a newline. 181 /// 182 /// Equivalent to the [`println!`] macro, except that output goes to 183 /// [`io::stderr`] instead of [`io::stdout`]. See [`println!`] for 184 /// example usage. 185 /// 186 /// Use `eprintln!` only for error and progress messages. Use `println!` 187 /// instead for the primary output of your program. 188 /// 189 /// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) 190 /// for details of the macro argument syntax. 191 /// 192 /// [`io::stderr`]: crate::std::io::stderr 193 /// [`io::stdout`]: crate::std::io::stdout 194 /// [`println!`]: crate::std::println 195 /// 196 /// # Panics 197 /// 198 /// Panics if writing to `io::stderr` fails. 199 /// 200 /// Writing to non-blocking stderr can cause an error, which will lead 201 /// this macro to panic. 202 /// 203 /// # Examples 204 /// 205 /// ``` 206 /// eprintln!("Error: Could not complete task"); 207 /// ``` 208 #[macro_export] 209 #[cfg_attr(not(test), rustc_diagnostic_item = "eprintln_macro")] 210 #[allow_internal_unstable(print_internals, format_args_nl)] 211 macro_rules! eprintln { 212 () => { 213 $crate::std::eprint!("\n") 214 }; 215 ($($arg:tt)*) => {{ 216 $crate::std::io::_eprint($crate::std::format_args_nl!($($arg)*)); 217 }}; 218 } 219 220 /// Prints and returns the value of a given expression for quick and dirty 221 /// debugging. 222 /// 223 /// An example: 224 /// 225 /// ```rust 226 /// let a = 2; 227 /// let b = dbg!(a * 2) + 1; 228 /// // ^-- prints: [src/main.rs:2] a * 2 = 4 229 /// assert_eq!(b, 5); 230 /// ``` 231 /// 232 /// The macro works by using the `Debug` implementation of the type of 233 /// the given expression to print the value to [stderr] along with the 234 /// source location of the macro invocation as well as the source code 235 /// of the expression. 236 /// 237 /// Invoking the macro on an expression moves and takes ownership of it 238 /// before returning the evaluated expression unchanged. If the type 239 /// of the expression does not implement `Copy` and you don't want 240 /// to give up ownership, you can instead borrow with `dbg!(&expr)` 241 /// for some expression `expr`. 242 /// 243 /// The `dbg!` macro works exactly the same in release builds. 244 /// This is useful when debugging issues that only occur in release 245 /// builds or when debugging in release mode is significantly faster. 246 /// 247 /// Note that the macro is intended as a debugging tool and therefore you 248 /// should avoid having uses of it in version control for long periods 249 /// (other than in tests and similar). 250 /// Debug output from production code is better done with other facilities 251 /// such as the [`debug!`] macro from the [`log`] crate. 252 /// 253 /// # Stability 254 /// 255 /// The exact output printed by this macro should not be relied upon 256 /// and is subject to future changes. 257 /// 258 /// # Panics 259 /// 260 /// Panics if writing to `io::stderr` fails. 261 /// 262 /// # Further examples 263 /// 264 /// With a method call: 265 /// 266 /// ```rust 267 /// fn foo(n: usize) { 268 /// if let Some(_) = dbg!(n.checked_sub(4)) { 269 /// // ... 270 /// } 271 /// } 272 /// 273 /// foo(3) 274 /// ``` 275 /// 276 /// This prints to [stderr]: 277 /// 278 /// ```text,ignore 279 /// [src/main.rs:4] n.checked_sub(4) = None 280 /// ``` 281 /// 282 /// Naive factorial implementation: 283 /// 284 /// ```rust 285 /// fn factorial(n: u32) -> u32 { 286 /// if dbg!(n <= 1) { 287 /// dbg!(1) 288 /// } else { 289 /// dbg!(n * factorial(n - 1)) 290 /// } 291 /// } 292 /// 293 /// dbg!(factorial(4)); 294 /// ``` 295 /// 296 /// This prints to [stderr]: 297 /// 298 /// ```text,ignore 299 /// [src/main.rs:3] n <= 1 = false 300 /// [src/main.rs:3] n <= 1 = false 301 /// [src/main.rs:3] n <= 1 = false 302 /// [src/main.rs:3] n <= 1 = true 303 /// [src/main.rs:4] 1 = 1 304 /// [src/main.rs:5] n * factorial(n - 1) = 2 305 /// [src/main.rs:5] n * factorial(n - 1) = 6 306 /// [src/main.rs:5] n * factorial(n - 1) = 24 307 /// [src/main.rs:11] factorial(4) = 24 308 /// ``` 309 /// 310 /// The `dbg!(..)` macro moves the input: 311 /// 312 /// ```compile_fail 313 /// /// A wrapper around `usize` which importantly is not Copyable. 314 /// #[derive(Debug)] 315 /// struct NoCopy(usize); 316 /// 317 /// let a = NoCopy(42); 318 /// let _ = dbg!(a); // <-- `a` is moved here. 319 /// let _ = dbg!(a); // <-- `a` is moved again; error! 320 /// ``` 321 /// 322 /// You can also use `dbg!()` without a value to just print the 323 /// file and line whenever it's reached. 324 /// 325 /// Finally, if you want to `dbg!(..)` multiple values, it will treat them as 326 /// a tuple (and return it, too): 327 /// 328 /// ``` 329 /// assert_eq!(dbg!(1usize, 2u32), (1, 2)); 330 /// ``` 331 /// 332 /// However, a single argument with a trailing comma will still not be treated 333 /// as a tuple, following the convention of ignoring trailing commas in macro 334 /// invocations. You can use a 1-tuple directly if you need one: 335 /// 336 /// ``` 337 /// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored 338 /// assert_eq!((1,), dbg!((1u32,))); // 1-tuple 339 /// ``` 340 /// 341 /// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr) 342 /// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html 343 /// [`log`]: https://crates.io/crates/log 344 #[macro_export] 345 #[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")] 346 macro_rules! dbg { 347 // NOTE: We cannot use `concat!` to make a static string as a format argument 348 // of `eprintln!` because `file!` could contain a `{` or 349 // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` 350 // will be malformed. 351 () => { 352 $crate::std::eprintln!("[{}:{}]", $crate::std::file!(), $crate::std::line!()) 353 }; 354 ($val:expr $(,)?) => { 355 // Use of `match` here is intentional because it affects the lifetimes 356 // of temporaries - https://stackoverflow.com/a/48732525/1063961 357 match $val { 358 tmp => { 359 $crate::std::eprintln!("[{}:{}] {} = {:#?}", 360 $crate::std::file!(), $crate::std::line!(), $crate::std::stringify!($val), &tmp); 361 tmp 362 } 363 } 364 }; 365 ($($val:expr),+ $(,)?) => { 366 ($($crate::std::dbg!($val)),+,) 367 }; 368 } 369 370 #[cfg(test)] 371 macro_rules! assert_approx_eq { 372 ($a:expr, $b:expr) => {{ 373 let (a, b) = (&$a, &$b); 374 assert!((*a - *b).abs() < 1.0e-6, "{} is not approximately equal to {}", *a, *b); 375 }}; 376 } 377 378 #[macro_export] 379 #[cfg(not(feature = "trace"))] 380 macro_rules! trace { 381 ($($arg:tt)*) => {}; 382 } 383 384 #[macro_export] 385 #[cfg(feature = "trace")] 386 macro_rules! trace { 387 ($($arg:tt)*) => ({ 388 use $crate::{Pal, Sys}; 389 eprintln!($($arg)*); 390 }); 391 } 392 393 #[macro_export] 394 #[cfg(not(feature = "trace"))] 395 macro_rules! trace_expr { 396 ($expr:expr, $($arg:tt)*) => { 397 $expr 398 }; 399 } 400 401 #[macro_export] 402 #[cfg(feature = "trace")] 403 macro_rules! trace_expr { 404 ($expr:expr, $($arg:tt)*) => ({ 405 use $crate::header::errno::STR_ERROR; 406 use $crate::platform; 407 408 trace!("{}", format_args!($($arg)*)); 409 410 #[allow(unused_unsafe)] 411 let trace_old_errno = unsafe { dlibc::errno }; 412 #[allow(unused_unsafe)] 413 unsafe { dlibc::errno = 0; } 414 415 let ret = $expr; 416 417 #[allow(unused_unsafe)] 418 let trace_errno = unsafe { dlibc::errno } as isize; 419 if trace_errno == 0 { 420 #[allow(unused_unsafe)] 421 unsafe { dlibc::errno = trace_old_errno; } 422 } 423 424 let trace_strerror = if trace_errno >= 0 && trace_errno < STR_ERROR.len() as isize { 425 STR_ERROR[trace_errno as usize] 426 } else { 427 "Unknown error" 428 }; 429 430 trace!("{} = {} ({}, {})", format_args!($($arg)*), ret, trace_errno, trace_strerror); 431 432 ret 433 }); 434 } 435 436 #[macro_export] 437 macro_rules! strto_impl { 438 ( 439 $rettype:ty, $signed:expr, $maxval:expr, $minval:expr, $s:ident, $endptr:ident, $base:ident 440 ) => {{ 441 // ensure these are constants 442 const CHECK_SIGN: bool = $signed; 443 const MAX_VAL: $rettype = $maxval; 444 const MIN_VAL: $rettype = $minval; 445 446 let set_endptr = |idx: isize| { 447 if !$endptr.is_null() { 448 // This is stupid, but apparently strto* functions want 449 // const input but mut output, yet the man page says 450 // "stores the address of the first invalid character in *endptr" 451 // so obviously it doesn't want us to clone it. 452 *$endptr = $s.offset(idx) as *mut _; 453 } 454 }; 455 456 let invalid_input = || { 457 dlibc::errno = EINVAL; 458 set_endptr(0); 459 }; 460 461 // only valid bases are 2 through 36 462 if $base != 0 && ($base < 2 || $base > 36) { 463 invalid_input(); 464 return 0; 465 } 466 467 let mut idx = 0; 468 469 // skip any whitespace at the beginning of the string 470 while ctype::isspace(*$s.offset(idx) as c_int) != 0 { 471 idx += 1; 472 } 473 474 // check for +/- 475 let positive = match is_positive(*$s.offset(idx)) { 476 Some((pos, i)) => { 477 idx += i; 478 pos 479 } 480 None => { 481 invalid_input(); 482 return 0; 483 } 484 }; 485 486 // convert the string to a number 487 let num_str = $s.offset(idx); 488 let res = match $base { 489 0 => detect_base(num_str) 490 .and_then(|($base, i)| convert_integer(num_str.offset(i), $base)), 491 8 => convert_octal(num_str), 492 16 => convert_hex(num_str), 493 _ => convert_integer(num_str, $base), 494 }; 495 496 // check for error parsing octal/hex prefix 497 // also check to ensure a number was indeed parsed 498 let (num, i, overflow) = match res { 499 Some(res) => res, 500 None => { 501 invalid_input(); 502 return 0; 503 } 504 }; 505 idx += i; 506 507 let overflow = if CHECK_SIGN { 508 overflow || (num as c_long).is_negative() 509 } else { 510 overflow 511 }; 512 // account for the sign 513 let num = num as $rettype; 514 let num = if overflow { 515 dlibc::errno = ERANGE; 516 if CHECK_SIGN { 517 if positive { 518 MAX_VAL 519 } else { 520 MIN_VAL 521 } 522 } else { 523 MAX_VAL 524 } 525 } else { 526 if positive { 527 num 528 } else { 529 // not using -num to keep the compiler happy 530 num.overflowing_neg().0 531 } 532 }; 533 534 set_endptr(idx); 535 536 num 537 }}; 538 } 539 #[macro_export] 540 macro_rules! strto_float_impl { 541 ($type:ident, $s:expr, $endptr:expr) => {{ 542 let mut s = $s; 543 let endptr = $endptr; 544 545 // TODO: Handle named floats: NaN, Inf... 546 547 while ctype::isspace(*s as c_int) != 0 { 548 s = s.offset(1); 549 } 550 551 let mut result: $type = 0.0; 552 let mut radix = 10; 553 554 let result_sign = match *s as u8 { 555 b'-' => { 556 s = s.offset(1); 557 -1.0 558 } 559 b'+' => { 560 s = s.offset(1); 561 1.0 562 } 563 _ => 1.0, 564 }; 565 566 if *s as u8 == b'0' && *s.offset(1) as u8 == b'x' { 567 s = s.offset(2); 568 radix = 16; 569 } 570 571 while let Some(digit) = (*s as u8 as char).to_digit(radix) { 572 result *= radix as $type; 573 result += digit as $type; 574 s = s.offset(1); 575 } 576 577 if *s as u8 == b'.' { 578 s = s.offset(1); 579 580 let mut i = 1.0; 581 while let Some(digit) = (*s as u8 as char).to_digit(radix) { 582 i *= radix as $type; 583 result += digit as $type / i; 584 s = s.offset(1); 585 } 586 } 587 588 let s_before_exponent = s; 589 590 let exponent = match (*s as u8, radix) { 591 (b'e' | b'E', 10) | (b'p' | b'P', 16) => { 592 s = s.offset(1); 593 594 let is_exponent_positive = match *s as u8 { 595 b'-' => { 596 s = s.offset(1); 597 false 598 } 599 b'+' => { 600 s = s.offset(1); 601 true 602 } 603 _ => true, 604 }; 605 606 // Exponent digits are always in base 10. 607 if (*s as u8 as char).is_digit(10) { 608 let mut exponent_value = 0; 609 610 while let Some(digit) = (*s as u8 as char).to_digit(10) { 611 exponent_value *= 10; 612 exponent_value += digit; 613 s = s.offset(1); 614 } 615 616 let exponent_base = match radix { 617 10 => 10u128, 618 16 => 2u128, 619 _ => unreachable!(), 620 }; 621 622 if is_exponent_positive { 623 Some(exponent_base.pow(exponent_value) as $type) 624 } else { 625 Some(1.0 / (exponent_base.pow(exponent_value) as $type)) 626 } 627 } else { 628 // Exponent had no valid digits after 'e'/'p' and '+'/'-', rollback 629 s = s_before_exponent; 630 None 631 } 632 } 633 _ => None, 634 }; 635 636 if !endptr.is_null() { 637 // This is stupid, but apparently strto* functions want 638 // const input but mut output, yet the man page says 639 // "stores the address of the first invalid character in *endptr" 640 // so obviously it doesn't want us to clone it. 641 *endptr = s as *mut _; 642 } 643 644 if let Some(exponent) = exponent { 645 result_sign * result * exponent 646 } else { 647 result_sign * result 648 } 649 }}; 650 } 651 #[macro_export] 652 macro_rules! c_str { 653 ($lit:expr) => { 654 #[allow(unused_unsafe)] 655 unsafe { 656 $crate::c_str::CStr::from_bytes_with_nul_unchecked(concat!($lit, "\0").as_bytes()) 657 } 658 }; 659 } 660