diff options
Diffstat (limited to 'vendor/mac/src')
-rw-r--r-- | vendor/mac/src/cfg.rs | 90 | ||||
-rw-r--r-- | vendor/mac/src/format.rs | 50 | ||||
-rw-r--r-- | vendor/mac/src/inspect.rs | 93 | ||||
-rw-r--r-- | vendor/mac/src/lib.rs | 71 | ||||
-rw-r--r-- | vendor/mac/src/matches.rs | 44 | ||||
-rw-r--r-- | vendor/mac/src/mem.rs | 44 | ||||
-rw-r--r-- | vendor/mac/src/syntax_ext.rs | 31 | ||||
-rw-r--r-- | vendor/mac/src/test.rs | 24 |
8 files changed, 447 insertions, 0 deletions
diff --git a/vendor/mac/src/cfg.rs b/vendor/mac/src/cfg.rs new file mode 100644 index 000000000..3dbb8fbe0 --- /dev/null +++ b/vendor/mac/src/cfg.rs @@ -0,0 +1,90 @@ +//! Macros for conditional compilation. + +/// Compile-time matching on config variables. +/// +/// Only the branch relevant on your machine will be type-checked! +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// # fn main() { +/// let mascot = match_cfg! { +/// (target_os = "linux") => "penguin", +/// (target_os = "openbsd") => "blowfish", +/// _ => "unknown", +/// }; +/// println!("{}", mascot); +/// # } +/// ``` +/// +#[macro_export] +macro_rules! match_cfg { + ( $( ($cfg:meta) => $e:expr, )* _ => $last:expr, ) => { + match () { + $( + #[cfg($cfg)] + () => $e, + )* + + #[cfg(all( $( not($cfg) ),* ))] + () => $last, + } + }; + + ( $( ($cfg:meta) => $e:expr, )* ) => { + match_cfg! { + $( + ($cfg) => $e, + )* + + _ => { + #[allow(dead_code)] + #[static_assert] + static MATCH_CFG_FALLBACK_UNREACHABLE: bool = false; + } + } + }; +} + +/// Compile-time conditional expression. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// # fn main() { +/// if_cfg!(test { +/// println!("Crate built as a test suite"); +/// }) +/// # } +/// ``` +/// +/// Unlike `if cfg!(...)`, this will not even compile the unused branch. +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// # fn main() { +/// let x = if_cfg!(any(bleh, blah="bluh") { +/// some_undefined_function_name(); +/// 2 + "doesn't even typecheck" +/// } else { +/// 3 +/// }); +/// +/// assert_eq!(x, 3); +/// # } +/// ``` +#[macro_export] +macro_rules! if_cfg { + ($cfg:meta $t:block else $f:block) => { + match_cfg! { + ($cfg) => $t, + _ => $f, + } + }; + + ($cfg:meta $t:block) => { + if_cfg!($cfg $t else { }) + }; +} diff --git a/vendor/mac/src/format.rs b/vendor/mac/src/format.rs new file mode 100644 index 000000000..8d4c8bb09 --- /dev/null +++ b/vendor/mac/src/format.rs @@ -0,0 +1,50 @@ +//! Macros for string formatting. + +/// Conditionally perform string formatting. +/// +/// If `$enabled` is true, then do the formatting and return a `Cow::Owned`. +/// +/// Otherwise, just return the borrowed (often `'static`) string +/// `$borrowed`. +/// +/// When `$enabled` is false, this avoids the overhead of allocating +/// and writing to a buffer, as well as any overhead or side effects +/// of the format arguments. +/// +/// # Example +/// +/// You can use `format_if` to implement a detailed error logging facility +/// that can be enabled at runtime. +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// # use std::borrow::Cow::{Borrowed, Owned}; +/// # fn main() { +/// let formatted = format_if!(true, "Vague error", "Error code {:?}", 3); +/// +/// assert_eq!(&formatted[..], "Error code 3"); +/// if let Borrowed(_) = formatted { +/// panic!("Wrong!") +/// } +/// +/// let not_formatted = format_if!(false, "Vague error", "Error code {:?}", { +/// // Note that the argument is not evaluated. +/// panic!("oops"); +/// }); +/// +/// assert_eq!(¬_formatted[..], "Vague error"); +/// if let Owned(_) = not_formatted { +/// panic!("Wrong!") +/// } +/// # } +/// ``` +#[macro_export] +macro_rules! format_if { + ($enabled:expr, $borrowed:expr, $fmt:expr, $($args:expr),*) => { + if $enabled { + ::std::borrow::Cow::Owned(format!($fmt, $($args),*)) as ::std::borrow::Cow<str> + } else { + ::std::borrow::Cow::Borrowed($borrowed) + } + } +} diff --git a/vendor/mac/src/inspect.rs b/vendor/mac/src/inspect.rs new file mode 100644 index 000000000..4fd8ce2ce --- /dev/null +++ b/vendor/mac/src/inspect.rs @@ -0,0 +1,93 @@ +//! Inspect Macros + +/// Evaluates an expression, prints a stringified version of the expression +/// along with the evaluated value, and then returns that value. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// +/// # fn main() { +/// fn lcm_2_to_4() -> u32 { +/// let mut i = 1; +/// loop { +/// if inspect!(i % 2, i % 3, i % 4) == (0, 0, 0) { +/// return inspect!("done: i = " => i); +/// } +/// i += 1; +/// } +/// } +/// assert_eq!(lcm_2_to_4(), 12); +/// # } +/// ``` +/// +/// Returns `12`, and prints the following to stdout: +/// +/// ```ignore +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 1) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 2) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 3) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 0) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 1) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 2) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 1, 3) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 2, 0) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 0, 1) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 1, 2) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (1, 2, 3) +/// src/inspect.rs:94 - (i % 2, i % 3, i % 4) = (0, 0, 0) +/// src/inspect.rs:95 - done: i = 12 +/// ``` + +#[macro_export] +macro_rules! inspect { + ($prefix:expr => $expr:expr) => {{ + let val = $expr; + println!("{}:{} - {}{:?}", file!(), line!(), $prefix, val); + val + }}; + ($expr:expr) => { + inspect!(concat!(stringify!($expr), " = ") => $expr) + }; + ($prefix:expr => $($expr:expr),+) => { + inspect!($prefix => ($($expr),+)) + }; + ($($expr:expr),+) => { + inspect!(($($expr),+)) + }; +} + +#[test] +fn test_inspect() { + assert_eq!(inspect!("foo"), "foo"); + assert_eq!(inspect!("" => "foo"), "foo"); + assert_eq!(inspect!(1 + 2, 2 + 3, 3 + 4), (3, 5, 7)); + assert_eq!(inspect!("" => 1 + 2, 2 + 3, 3 + 4), (3, 5, 7)); + + fn fib(n: u64) -> u64 { + inspect!("fib :: n = " => n); + inspect! { "ret = " => match n { + 0 | 1 => n, + n => fib(n-1) + fib(n-2) + }} + } + + fn fib_iter(n: u64) -> u64 { + inspect!("fib_iter :: n = " => n); + let (mut a, mut b) = (0, 1); + for _ in 0..n { + inspect!(a, b); + let tmp = b; + b += a; + a = tmp; + } + inspect!("ret = " => a) + } + + assert_eq!(fib(4), 3); + assert_eq!(fib_iter(7), 13); + + // Uncomment the following to see the output in `cargo test`. + // panic!() +} diff --git a/vendor/mac/src/lib.rs b/vendor/mac/src/lib.rs new file mode 100644 index 000000000..9287f32bb --- /dev/null +++ b/vendor/mac/src/lib.rs @@ -0,0 +1,71 @@ +#![cfg_attr(test, deny(warnings))] +#![deny(missing_docs)] + +//! # mac +//! +//! A collection of great and ubiqutitous macros. +//! + +pub mod test; +pub mod mem; +pub mod format; +pub mod syntax_ext; +pub mod matches; +pub mod inspect; +pub mod cfg; + +/// Unwraps an `Option` or returns from the function with the specified return +/// value. +/// +/// Can be used on `Result`s by first calling `.ok()` or `.err()` on them. +/// +/// # Examples +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// fn take_pair<I:Iterator>(iter: &mut I) -> Option<(<I as Iterator>::Item, <I as Iterator>::Item)> { +/// let first = unwrap_or_return!(iter.next(), None); +/// Some((first, unwrap_or_return!(iter.next(), None))) +/// } +/// # fn main() { } +/// ``` +#[macro_export] +macro_rules! unwrap_or_return { + ($e:expr, $r:expr) => (match $e { Some(e) => e, None => return $r, }) +} + +/// Do-while loop. +/// +/// # Examples +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// # fn main() { +/// let mut i = 0; +/// let mut n = 0; +/// +/// do_while!({ +/// n += i; +/// i += 1; +/// } while i < 5); +/// +/// assert_eq!(n, 10); +/// # } +/// ``` +/// +/// The loop always executes at least once. +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// # fn main() { +/// let mut ran = false; +/// do_while!({ ran = true } while false); +/// assert!(ran); +/// # } +/// ``` +#[macro_export] +macro_rules! do_while { + ($body:block while $condition:expr) => { + while { $body; $condition } { } + } +} diff --git a/vendor/mac/src/matches.rs b/vendor/mac/src/matches.rs new file mode 100644 index 000000000..a788fe478 --- /dev/null +++ b/vendor/mac/src/matches.rs @@ -0,0 +1,44 @@ +//! Pattern Matching macros. + +/// Returns true if an expression matches a pattern. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// +/// # fn main() { +/// assert!(matches!(2, 1 | 2 | 3)); +/// assert!(matches!('x', 'a' ... 'z')); +/// assert!(!matches!(Some(1), None)); +/// assert!(matches!(Some(42), Some(n) if n == 42)); +/// # } +/// ``` +#[macro_export] +macro_rules! matches { + ($expr:expr, $($pat:tt)+) => { + _tt_as_expr_hack! { + match $expr { + $($pat)+ => true, + _ => false + } + } + } +} + +/// Work around "error: unexpected token: `an interpolated tt`", whatever that +/// means. (Probably rust-lang/rust#22819.) +#[doc(hidden)] +#[macro_export] +macro_rules! _tt_as_expr_hack { + ($value:expr) => ($value) +} + +#[test] +fn test_matches() { + let foo = Some("-12"); + assert!(matches!(foo, Some(bar) if + matches!(bar.as_bytes()[0], b'+' | b'-') && + matches!(bar.as_bytes()[1], b'0'... b'9') + )); +} diff --git a/vendor/mac/src/mem.rs b/vendor/mac/src/mem.rs new file mode 100644 index 000000000..49cf5f1b1 --- /dev/null +++ b/vendor/mac/src/mem.rs @@ -0,0 +1,44 @@ +//! Macros for low-level memory manipulation. + +/// Make a tuple of the addresses of some of a struct's fields. +/// +/// This is useful when you are transmuting between struct types +/// and would like an additional dynamic check that the layouts +/// match. It's difficult to make such an assertion statically +/// in Rust at present. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// use std::mem; +/// +/// # fn main() { +/// struct Foo { x: i32, y: i32 } +/// struct Bar { x: u32, y: u32 } +/// +/// let foo = Foo { x: 3, y: 4 }; +/// let old_addrs = addrs_of!(foo => x, y); +/// +/// let bar = unsafe { +/// mem::transmute::<&Foo, &Bar>(&foo) +/// }; +/// let new_addrs = addrs_of!(bar => x, y); +/// assert_eq!(old_addrs, new_addrs); +/// +/// assert_eq!(bar.x, 3); +/// assert_eq!(bar.y, 4); +/// # } +/// ``` +#[macro_export] +macro_rules! addrs_of { + ($obj:expr => $($field:ident),+) => { + ( // make a tuple + $( + unsafe { + ::std::mem::transmute::<_, usize>(&$obj.$field) + } + ),+ + ) + } +} diff --git a/vendor/mac/src/syntax_ext.rs b/vendor/mac/src/syntax_ext.rs new file mode 100644 index 000000000..ab7e82bb2 --- /dev/null +++ b/vendor/mac/src/syntax_ext.rs @@ -0,0 +1,31 @@ +//! Macros useful when writing procedural syntax extensions. +//! +//! The macros themselves are ordinary `macro_rules!` macros. + +/// Call `span_err` on an `ExtCtxt` and return `DummyResult::any`. +#[macro_export] +macro_rules! ext_bail { + ($cx:expr, $sp:expr, $msg:expr) => {{ + $cx.span_err($sp, $msg); + return ::syntax::ext::base::DummyResult::any($sp); + }} +} + +/// `ext_bail!` if the condition `$e` is true. +#[macro_export] +macro_rules! ext_bail_if { + ($e:expr, $cx:expr, $sp:expr, $msg:expr) => {{ + if $e { ext_bail!($cx, $sp, $msg) } + }} +} + +/// Unwrap the `Option` `$e`, or `ext_bail!`. +#[macro_export] +macro_rules! ext_expect { + ($cx:expr, $sp:expr, $e:expr, $msg:expr) => {{ + match $e { + Some(x) => x, + None => ext_bail!($cx, $sp, $msg), + } + }} +} diff --git a/vendor/mac/src/test.rs b/vendor/mac/src/test.rs new file mode 100644 index 000000000..1e9858c27 --- /dev/null +++ b/vendor/mac/src/test.rs @@ -0,0 +1,24 @@ +//! Macros for writing test suites. + +/// Generate a test function `$name` which asserts that `$left` and `$right` +/// are equal. +/// +/// # Example +/// +/// ``` +/// # #[macro_use] extern crate mac; +/// mod test { +/// # // doesn't actually run the test :/ +/// test_eq!(two_and_two_is_four, 2 + 2, 4); +/// } +/// # fn main() { } +/// ``` +#[macro_export] +macro_rules! test_eq { + ($name:ident, $left:expr, $right:expr) => { + #[test] + fn $name() { + assert_eq!($left, $right); + } + } +} |