From f3f038c8566560e7367e0615d17ba104b71f6d8a Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 4 Sep 2014 15:16:04 +1000 Subject: [PATCH 1/4] Allow trailing commas in bitflags! macro --- src/libstd/bitflags.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index d231189aede..aebbd487a76 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -24,7 +24,7 @@ //! static FlagC = 0x00000100, //! static FlagABC = FlagA.bits //! | FlagB.bits -//! | FlagC.bits +//! | FlagC.bits, //! } //! ) //! @@ -46,7 +46,7 @@ //! bitflags!( //! flags Flags: u32 { //! static FlagA = 0x00000001, -//! static FlagB = 0x00000010 +//! static FlagB = 0x00000010, //! } //! ) //! @@ -215,7 +215,17 @@ macro_rules! bitflags( $BitFlags { bits: !self.bits } & $BitFlags::all() } } - ) + ); + ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+, + }) => ( + bitflags!( + $(#[$attr])* + flags $BitFlags: u32 { + $($(#[$Flag_attr])* static $Flag = $value),+ + } + ) + ); ) #[cfg(test)] @@ -231,7 +241,7 @@ mod tests { static FlagC = 0x00000100, static FlagABC = FlagA.bits | FlagB.bits - | FlagC.bits + | FlagC.bits, } ) From ca60b743d7755f486158318212d33f0cc99a81ed Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 4 Sep 2014 15:22:16 +1000 Subject: [PATCH 2/4] Test attributes --- src/libstd/bitflags.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index aebbd487a76..e7139c2ffdf 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -235,10 +235,18 @@ mod tests { use ops::{BitOr, BitAnd, Sub, Not}; bitflags!( + #[doc = "> The first principle is that you must not fool yourself — and"] + #[doc = "> you are the easiest person to fool."] + #[doc = "> "] + #[doc = "> - Richard Feynman"] flags Flags: u32 { static FlagA = 0x00000001, + #[doc = " macros are way better at generating code than trans is"] static FlagB = 0x00000010, static FlagC = 0x00000100, + #[doc = "* cmr bed"] + #[doc = "* strcat table"] + #[doc = " wait what?"] static FlagABC = FlagA.bits | FlagB.bits | FlagC.bits, From ff72583891f67b9d739b76e914519631413ee56c Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 4 Sep 2014 15:25:22 +1000 Subject: [PATCH 3/4] Attach documentation to the bitflags! macro itself This is in consistent with the style demonstrated in the std::macros module. --- src/libstd/bitflags.rs | 195 +++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 97 deletions(-) diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index e7139c2ffdf..f540398fcaa 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -8,106 +8,107 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! The `bitflags!` macro generates a `struct` that holds a set of C-style -//! bitmask flags. It is useful for creating typesafe wrappers for C APIs. -//! -//! The flags should only be defined for integer types, otherwise unexpected -//! type errors may occur at compile time. -//! -//! # Example -//! -//! ~~~rust -//! bitflags!( -//! flags Flags: u32 { -//! static FlagA = 0x00000001, -//! static FlagB = 0x00000010, -//! static FlagC = 0x00000100, -//! static FlagABC = FlagA.bits -//! | FlagB.bits -//! | FlagC.bits, -//! } -//! ) -//! -//! fn main() { -//! let e1 = FlagA | FlagC; -//! let e2 = FlagB | FlagC; -//! assert!((e1 | e2) == FlagABC); // union -//! assert!((e1 & e2) == FlagC); // intersection -//! assert!((e1 - e2) == FlagA); // set difference -//! assert!(!e2 == FlagA); // set complement -//! } -//! ~~~ -//! -//! The generated `struct`s can also be extended with type and trait implementations: -//! -//! ~~~rust -//! use std::fmt; -//! -//! bitflags!( -//! flags Flags: u32 { -//! static FlagA = 0x00000001, -//! static FlagB = 0x00000010, -//! } -//! ) -//! -//! impl Flags { -//! pub fn clear(&mut self) { -//! self.bits = 0; // The `bits` field can be accessed from within the -//! // same module where the `bitflags!` macro was invoked. -//! } -//! } -//! -//! impl fmt::Show for Flags { -//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -//! write!(f, "hi!") -//! } -//! } -//! -//! fn main() { -//! let mut flags = FlagA | FlagB; -//! flags.clear(); -//! assert!(flags.is_empty()); -//! assert_eq!(format!("{}", flags).as_slice(), "hi!"); -//! } -//! ~~~ -//! -//! # Attributes -//! -//! Attributes can be attached to the generated `struct` by placing them -//! before the `flags` keyword. -//! -//! # Derived traits -//! -//! The `PartialEq` and `Clone` traits are automatically derived for the `struct` using -//! the `deriving` attribute. Additional traits can be derived by providing an -//! explicit `deriving` attribute on `flags`. -//! -//! # Operators -//! -//! The following operator traits are implemented for the generated `struct`: -//! -//! - `BitOr`: union -//! - `BitAnd`: intersection -//! - `Sub`: set difference -//! - `Not`: set complement -//! -//! # Methods -//! -//! The following methods are defined for the generated `struct`: -//! -//! - `empty`: an empty set of flags -//! - `all`: the set of all flags -//! - `bits`: the raw value of the flags currently stored -//! - `is_empty`: `true` if no flags are currently stored -//! - `is_all`: `true` if all flags are currently set -//! - `intersects`: `true` if there are flags common to both `self` and `other` -//! - `contains`: `true` all of the flags in `other` are contained within `self` -//! - `insert`: inserts the specified flags in-place -//! - `remove`: removes the specified flags in-place - #![experimental] #![macro_escape] +//! A typesafe bitmask flag generator. + +/// The `bitflags!` macro generates a `struct` that holds a set of C-style +/// bitmask flags. It is useful for creating typesafe wrappers for C APIs. +/// +/// The flags should only be defined for integer types, otherwise unexpected +/// type errors may occur at compile time. +/// +/// # Example +/// +/// ~~~rust +/// bitflags!( +/// flags Flags: u32 { +/// static FlagA = 0x00000001, +/// static FlagB = 0x00000010, +/// static FlagC = 0x00000100, +/// static FlagABC = FlagA.bits +/// | FlagB.bits +/// | FlagC.bits, +/// } +/// ) +/// +/// fn main() { +/// let e1 = FlagA | FlagC; +/// let e2 = FlagB | FlagC; +/// assert!((e1 | e2) == FlagABC); // union +/// assert!((e1 & e2) == FlagC); // intersection +/// assert!((e1 - e2) == FlagA); // set difference +/// assert!(!e2 == FlagA); // set complement +/// } +/// ~~~ +/// +/// The generated `struct`s can also be extended with type and trait implementations: +/// +/// ~~~rust +/// use std::fmt; +/// +/// bitflags!( +/// flags Flags: u32 { +/// static FlagA = 0x00000001, +/// static FlagB = 0x00000010, +/// } +/// ) +/// +/// impl Flags { +/// pub fn clear(&mut self) { +/// self.bits = 0; // The `bits` field can be accessed from within the +/// // same module where the `bitflags!` macro was invoked. +/// } +/// } +/// +/// impl fmt::Show for Flags { +/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +/// write!(f, "hi!") +/// } +/// } +/// +/// fn main() { +/// let mut flags = FlagA | FlagB; +/// flags.clear(); +/// assert!(flags.is_empty()); +/// assert_eq!(format!("{}", flags).as_slice(), "hi!"); +/// } +/// ~~~ +/// +/// # Attributes +/// +/// Attributes can be attached to the generated `struct` by placing them +/// before the `flags` keyword. +/// +/// # Derived traits +/// +/// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using +/// the `deriving` attribute. Additional traits can be derived by providing an +/// explicit `deriving` attribute on `flags`. +/// +/// # Operators +/// +/// The following operator traits are implemented for the generated `struct`: +/// +/// - `BitOr`: union +/// - `BitAnd`: intersection +/// - `Sub`: set difference +/// - `Not`: set complement +/// +/// # Methods +/// +/// The following methods are defined for the generated `struct`: +/// +/// - `empty`: an empty set of flags +/// - `all`: the set of all flags +/// - `bits`: the raw value of the flags currently stored +/// - `is_empty`: `true` if no flags are currently stored +/// - `is_all`: `true` if all flags are currently set +/// - `intersects`: `true` if there are flags common to both `self` and `other` +/// - `contains`: `true` all of the flags in `other` are contained within `self` +/// - `insert`: inserts the specified flags in-place +/// - `remove`: removes the specified flags in-place #[macro_export] macro_rules! bitflags( ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { From ef354d850e516e7005da050f0b5b8d3a5c2d7f45 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 4 Sep 2014 16:35:06 +1000 Subject: [PATCH 4/4] Use {} for bitflags! definition and invocations This looks nicer because it reflects Rust's other syntactic structures. --- src/libstd/bitflags.rs | 28 ++++++++++++++-------------- src/libstd/io/mod.rs | 24 ++++++++++++------------ src/libstd/lib.rs | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index f540398fcaa..3d1bc20cca4 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -22,7 +22,7 @@ /// # Example /// /// ~~~rust -/// bitflags!( +/// bitflags! { /// flags Flags: u32 { /// static FlagA = 0x00000001, /// static FlagB = 0x00000010, @@ -31,7 +31,7 @@ /// | FlagB.bits /// | FlagC.bits, /// } -/// ) +/// } /// /// fn main() { /// let e1 = FlagA | FlagC; @@ -48,12 +48,12 @@ /// ~~~rust /// use std::fmt; /// -/// bitflags!( +/// bitflags! { /// flags Flags: u32 { /// static FlagA = 0x00000001, /// static FlagB = 0x00000010, /// } -/// ) +/// } /// /// impl Flags { /// pub fn clear(&mut self) { @@ -110,10 +110,10 @@ /// - `insert`: inserts the specified flags in-place /// - `remove`: removes the specified flags in-place #[macro_export] -macro_rules! bitflags( +macro_rules! bitflags { ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+ - }) => ( + }) => { #[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)] $(#[$attr])* pub struct $BitFlags { @@ -216,18 +216,18 @@ macro_rules! bitflags( $BitFlags { bits: !self.bits } & $BitFlags::all() } } - ); + }; ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+, - }) => ( - bitflags!( + }) => { + bitflags! { $(#[$attr])* flags $BitFlags: u32 { $($(#[$Flag_attr])* static $Flag = $value),+ } - ) - ); -) + } + }; +} #[cfg(test)] mod tests { @@ -235,7 +235,7 @@ mod tests { use option::{Some, None}; use ops::{BitOr, BitAnd, Sub, Not}; - bitflags!( + bitflags! { #[doc = "> The first principle is that you must not fool yourself — and"] #[doc = "> you are the easiest person to fool."] #[doc = "> "] @@ -252,7 +252,7 @@ mod tests { | FlagB.bits | FlagC.bits, } - ) + } #[test] fn test_bits(){ diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index c7996c549f4..804d6c79d23 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1794,9 +1794,9 @@ pub struct UnstableFileStat { pub gen: u64, } -bitflags!( - #[doc="A set of permissions for a file or directory is represented -by a set of flags which are or'd together."] +bitflags! { + #[doc = "A set of permissions for a file or directory is represented"] + #[doc = "by a set of flags which are or'd together."] flags FilePermission: u32 { static UserRead = 0o400, static UserWrite = 0o200, @@ -1812,23 +1812,23 @@ by a set of flags which are or'd together."] static GroupRWX = GroupRead.bits | GroupWrite.bits | GroupExecute.bits, static OtherRWX = OtherRead.bits | OtherWrite.bits | OtherExecute.bits, - #[doc="Permissions for user owned files, equivalent to 0644 on -unix-like systems."] + #[doc = "Permissions for user owned files, equivalent to 0644 on"] + #[doc = "unix-like systems."] static UserFile = UserRead.bits | UserWrite.bits | GroupRead.bits | OtherRead.bits, - #[doc="Permissions for user owned directories, equivalent to 0755 on -unix-like systems."] + #[doc = "Permissions for user owned directories, equivalent to 0755 on"] + #[doc = "unix-like systems."] static UserDir = UserRWX.bits | GroupRead.bits | GroupExecute.bits | OtherRead.bits | OtherExecute.bits, - #[doc="Permissions for user owned executables, equivalent to 0755 -on unix-like systems."] + #[doc = "Permissions for user owned executables, equivalent to 0755"] + #[doc = "on unix-like systems."] static UserExec = UserDir.bits, - #[doc="All possible permissions enabled."] - static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits + #[doc = "All possible permissions enabled."] + static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits, } -) +} impl Default for FilePermission { #[inline] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7fed4c94164..443b5713665 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -281,7 +281,7 @@ mod std { pub use fmt; // used for any formatting strings pub use io; // used for println!() pub use local_data; // used for local_data_key!() - pub use option; // used for bitflags!() + pub use option; // used for bitflags!{} pub use rt; // used for fail!() pub use vec; // used for vec![]