2014-01-24 01:40:54 -06:00
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
2014-02-16 23:40:26 -06:00
|
|
|
|
|
|
|
//! Standard library macros
|
|
|
|
//!
|
|
|
|
//! This modules contains a set of macros which are exported from the standard
|
|
|
|
//! library. Each macro is available for use when linking against the standard
|
|
|
|
//! library.
|
|
|
|
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_escape];
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// The standard logging macro
|
|
|
|
///
|
|
|
|
/// This macro will generically log over a provided level (of type u32) with a
|
|
|
|
/// format!-based argument list. See documentation in `std::fmt` for details on
|
|
|
|
/// how to use the syntax, and documentation in `std::logging` for info about
|
|
|
|
/// logging macros.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// log!(::std::logging::DEBUG, "this is a debug message");
|
|
|
|
/// log!(::std::logging::WARN, "this is a warning {}", "message");
|
|
|
|
/// log!(6, "this is a custom logging level: {level}", level=6);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! log(
|
|
|
|
($lvl:expr, $($arg:tt)+) => ({
|
|
|
|
let lvl = $lvl;
|
|
|
|
if lvl <= __log_level() {
|
|
|
|
format_args!(|args| {
|
|
|
|
::std::logging::log(lvl, args)
|
|
|
|
}, $($arg)+)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
)
|
2014-02-07 11:42:11 -06:00
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// A convenience macro for logging at the error log level. See `std::logging`
|
|
|
|
/// for more information. about logging.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # let error = 3;
|
|
|
|
/// error!("the build has failed with error code: {}", error);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! error(
|
|
|
|
($($arg:tt)*) => (log!(1u32, $($arg)*))
|
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// A convenience macro for logging at the warning log level. See `std::logging`
|
|
|
|
/// for more information. about logging.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # let code = 3;
|
|
|
|
/// warn!("you may like to know that a process exited with: {}", code);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! warn(
|
|
|
|
($($arg:tt)*) => (log!(2u32, $($arg)*))
|
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// A convenience macro for logging at the info log level. See `std::logging`
|
|
|
|
/// for more information. about logging.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # let ret = 3;
|
|
|
|
/// info!("this function is about to return: {}", ret);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! info(
|
|
|
|
($($arg:tt)*) => (log!(3u32, $($arg)*))
|
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// A convenience macro for logging at the debug log level. See `std::logging`
|
|
|
|
/// for more information. about logging.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// debug!("x = {x}, y = {y}", x=10, y=20);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! debug(
|
|
|
|
($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(4u32, $($arg)*) })
|
|
|
|
)
|
2014-01-24 01:40:54 -06:00
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// A macro to test whether a log level is enabled for the current module.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # struct Point { x: int, y: int }
|
|
|
|
/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
|
|
|
|
/// if log_enabled!(std::logging::DEBUG) {
|
|
|
|
/// let x = some_expensive_computation();
|
|
|
|
/// debug!("x.x = {}, x.y = {}", x.x, x.y);
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! log_enabled(
|
2014-02-07 11:42:11 -06:00
|
|
|
($lvl:expr) => ({
|
2014-01-24 01:40:54 -06:00
|
|
|
let lvl = $lvl;
|
|
|
|
lvl <= __log_level() && (lvl != 4 || cfg!(not(ndebug)))
|
2014-02-07 11:42:11 -06:00
|
|
|
})
|
2014-01-24 01:40:54 -06:00
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// The entry point for failure of rust tasks.
|
|
|
|
///
|
|
|
|
/// This macro is used to inject failure into a rust task, causing the task to
|
|
|
|
/// unwind and fail entirely. Each task's failure can be reaped as the `~Any`
|
|
|
|
/// type, and the single-argument form of the `fail!` macro will be the value
|
|
|
|
/// which is transmitted.
|
|
|
|
///
|
|
|
|
/// The multi-argument form of this macro fails with a string and has the
|
|
|
|
/// `format!` sytnax for building a string.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```should_fail
|
|
|
|
/// fail!();
|
|
|
|
/// fail!("this is a terrible mistake!");
|
|
|
|
/// fail!(4); // fail with the value of 4 to be collected elsewhere
|
|
|
|
/// fail!("this is a {} {message}", "fancy", message = "message");
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! fail(
|
|
|
|
() => (
|
|
|
|
fail!("explicit failure")
|
|
|
|
);
|
|
|
|
($msg:expr) => (
|
|
|
|
::std::rt::begin_unwind($msg, file!(), line!())
|
|
|
|
);
|
2014-02-07 11:42:11 -06:00
|
|
|
($fmt:expr, $($arg:tt)*) => ({
|
|
|
|
// a closure can't have return type !, so we need a full
|
|
|
|
// function to pass to format_args!, *and* we need the
|
|
|
|
// file and line numbers right here; so an inner bare fn
|
|
|
|
// is our only choice.
|
|
|
|
#[inline]
|
|
|
|
fn run_fmt(fmt: &::std::fmt::Arguments) -> ! {
|
|
|
|
::std::rt::begin_unwind_fmt(fmt, file!(), line!())
|
2014-01-27 05:37:55 -06:00
|
|
|
}
|
2014-02-07 11:42:11 -06:00
|
|
|
format_args!(run_fmt, $fmt, $($arg)*)
|
|
|
|
});
|
2014-01-24 01:40:54 -06:00
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Ensure that a boolean expression is `true` at runtime.
|
|
|
|
///
|
|
|
|
/// This will invoke the `fail!` macro if the provided expression cannot be
|
|
|
|
/// evaluated to `true` at runtime.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // the failure message for these assertions is the stringified value of the
|
|
|
|
/// // expression given.
|
|
|
|
/// assert!(true);
|
|
|
|
/// # fn some_computation() -> bool { true }
|
|
|
|
/// assert!(some_computation());
|
|
|
|
///
|
|
|
|
/// // assert with a custom message
|
|
|
|
/// # let x = true;
|
|
|
|
/// assert!(x, "x wasn't true!");
|
|
|
|
/// # let a = 3; let b = 27;
|
|
|
|
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
|
|
|
macro_rules! assert(
|
2014-02-07 11:42:11 -06:00
|
|
|
($cond:expr) => (
|
2014-01-24 01:40:54 -06:00
|
|
|
if !$cond {
|
|
|
|
fail!("assertion failed: {:s}", stringify!($cond))
|
|
|
|
}
|
2014-02-07 11:42:11 -06:00
|
|
|
);
|
|
|
|
($cond:expr, $msg:expr) => (
|
2014-01-24 01:40:54 -06:00
|
|
|
if !$cond {
|
|
|
|
fail!($msg)
|
|
|
|
}
|
2014-02-07 11:42:11 -06:00
|
|
|
);
|
|
|
|
($cond:expr, $($arg:expr),+) => (
|
2014-01-24 01:40:54 -06:00
|
|
|
if !$cond {
|
2014-02-07 11:42:11 -06:00
|
|
|
fail!($($arg),+)
|
2014-01-24 01:40:54 -06:00
|
|
|
}
|
2014-02-07 11:42:11 -06:00
|
|
|
);
|
2014-01-24 01:40:54 -06:00
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Asserts that two expressions are equal to each other, testing equality in
|
|
|
|
/// both directions.
|
|
|
|
///
|
|
|
|
/// On failure, this macro will print the values of the expressions.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let a = 3;
|
|
|
|
/// let b = 1 + 2;
|
|
|
|
/// assert_eq!(a, b);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! assert_eq(
|
|
|
|
($given:expr , $expected:expr) => ({
|
|
|
|
let given_val = &($given);
|
|
|
|
let expected_val = &($expected);
|
|
|
|
// check both directions of equality....
|
|
|
|
if !((*given_val == *expected_val) &&
|
|
|
|
(*expected_val == *given_val)) {
|
|
|
|
fail!("assertion failed: `(left == right) && (right == left)` \
|
|
|
|
(left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
|
2014-01-24 01:40:54 -06:00
|
|
|
}
|
2014-02-07 11:42:11 -06:00
|
|
|
})
|
2014-01-24 01:40:54 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
/// A utility macro for indicating unreachable code. It will fail if
|
|
|
|
/// executed. This is occasionally useful to put after loops that never
|
|
|
|
/// terminate normally, but instead directly return from a function.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
2014-02-07 11:42:11 -06:00
|
|
|
/// ~~~rust
|
2014-01-24 01:40:54 -06:00
|
|
|
/// fn choose_weighted_item(v: &[Item]) -> Item {
|
|
|
|
/// assert!(!v.is_empty());
|
|
|
|
/// let mut so_far = 0u;
|
|
|
|
/// for item in v.iter() {
|
|
|
|
/// so_far += item.weight;
|
|
|
|
/// if so_far > 100 {
|
|
|
|
/// return item;
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// // The above loop always returns, so we must hint to the
|
|
|
|
/// // type checker that it isn't possible to get down here
|
|
|
|
/// unreachable!();
|
|
|
|
/// }
|
2014-02-07 11:42:11 -06:00
|
|
|
/// ~~~
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! unreachable(
|
|
|
|
() => (fail!("internal error: entered unreachable code"))
|
|
|
|
)
|
2014-01-24 01:40:54 -06:00
|
|
|
|
2014-02-07 04:18:17 -06:00
|
|
|
/// A standardised placeholder for marking unfinished code. It fails with the
|
|
|
|
/// message `"not yet implemented"` when executed.
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! unimplemented(
|
|
|
|
() => (fail!("not yet implemented"))
|
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Use the syntax described in `std::fmt` to create a value of type `~str`.
|
|
|
|
/// See `std::fmt` for more information.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// format!("test");
|
|
|
|
/// format!("hello {}", "world!");
|
|
|
|
/// format!("x = {}, y = {y}", 10, y = 30);
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! format(
|
|
|
|
($($arg:tt)*) => (
|
|
|
|
format_args!(::std::fmt::format, $($arg)*)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
|
|
|
|
/// See `std::fmt` for more information.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # #[allow(unused_must_use)];
|
|
|
|
/// use std::io::MemWriter;
|
|
|
|
///
|
|
|
|
/// let mut w = MemWriter::new();
|
|
|
|
/// write!(&mut w, "test");
|
|
|
|
/// write!(&mut w, "formatted {}", "arguments");
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! write(
|
2014-02-13 06:31:19 -06:00
|
|
|
($dst:expr, $($arg:tt)*) => ({
|
|
|
|
let dst: &mut ::std::io::Writer = $dst;
|
|
|
|
format_args!(|args| { ::std::fmt::write(dst, args) }, $($arg)*)
|
|
|
|
})
|
2014-02-07 11:42:11 -06:00
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Equivalent to the `write!` macro, except that a newline is appended after
|
|
|
|
/// the message is written.
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! writeln(
|
2014-02-13 06:31:19 -06:00
|
|
|
($dst:expr, $($arg:tt)*) => ({
|
|
|
|
let dst: &mut ::std::io::Writer = $dst;
|
|
|
|
format_args!(|args| { ::std::fmt::writeln(dst, args) }, $($arg)*)
|
|
|
|
})
|
2014-02-07 11:42:11 -06:00
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Equivalent to the `println!` macro except that a newline is not printed at
|
|
|
|
/// the end of the message.
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! print(
|
2014-01-24 01:40:54 -06:00
|
|
|
($($arg:tt)*) => (format_args!(::std::io::stdio::print_args, $($arg)*))
|
|
|
|
)
|
2014-02-07 11:42:11 -06:00
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Macro for printing to a task's stdout handle.
|
|
|
|
///
|
|
|
|
/// Each task can override its stdout handle via `std::io::stdio::set_stdout`.
|
|
|
|
/// The syntax of this macro is the same as that used for `format!`. For more
|
|
|
|
/// information, see `std::fmt` and `std::io::stdio`.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// println!("hello there!");
|
|
|
|
/// println!("format {} arguments", "some");
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! println(
|
2014-01-24 01:40:54 -06:00
|
|
|
($($arg:tt)*) => (format_args!(::std::io::stdio::println_args, $($arg)*))
|
|
|
|
)
|
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Declare a task-local key with a specific type.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::local_data;
|
|
|
|
///
|
|
|
|
/// local_data_key!(my_integer: int)
|
|
|
|
///
|
|
|
|
/// local_data::set(my_integer, 2);
|
|
|
|
/// local_data::get(my_integer, |val| println!("{}", val));
|
|
|
|
/// ```
|
2014-01-24 01:40:54 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! local_data_key(
|
2014-01-24 01:40:54 -06:00
|
|
|
($name:ident: $ty:ty) => (
|
|
|
|
static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
|
|
|
|
);
|
|
|
|
(pub $name:ident: $ty:ty) => (
|
|
|
|
pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
|
2014-02-07 11:42:11 -06:00
|
|
|
);
|
2014-01-24 01:40:54 -06:00
|
|
|
)
|
2014-01-29 18:33:57 -06:00
|
|
|
|
2014-02-16 23:40:26 -06:00
|
|
|
/// Helper macro for unwrapping `Result` values while returning early with an
|
|
|
|
/// error if the value of the expression is `Err`. For more information, see
|
|
|
|
/// `std::io`.
|
2014-01-29 18:33:57 -06:00
|
|
|
#[macro_export]
|
2014-02-07 11:42:11 -06:00
|
|
|
macro_rules! if_ok(
|
2014-01-29 18:33:57 -06:00
|
|
|
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
|
|
|
|
)
|