diff options
| author | bors <bors@rust-lang.org> | 2014-05-06 12:41:55 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-06 12:41:55 -0700 |
| commit | cf6857b9e9427f14d383ae2924555bedc251fa02 (patch) | |
| tree | 045b617609058f5042495fd4172b2f2924179360 /src/libstd | |
| parent | 1f6db7f4f6399628eaaca5d38cc5fb38e71b4c23 (diff) | |
| parent | 8d1d7d9b5f3920d70b1edcc258a86106527e83f7 (diff) | |
| download | rust-cf6857b9e9427f14d383ae2924555bedc251fa02.tar.gz rust-cf6857b9e9427f14d383ae2924555bedc251fa02.zip | |
auto merge of #13897 : aturon/rust/issue-6085, r=bjz
The `std::bitflags::bitflags!` macro did not provide support for
adding attributes to the generates structure, due to limitations in
the parser for macros. This patch works around the parser limitations
by requiring a `flags` keyword in the `bitflags!` invocations:
bitflags!(
#[deriving(Hash)]
#[doc="Three flags"]
flags Flags: u32 {
FlagA = 0x00000001,
FlagB = 0x00000010,
FlagC = 0x00000100
}
)
The intent of `std::bitflags` is to allow building type-safe wrappers
around C-style flags APIs. But in addition to construction these flags
from the Rust side, we need a way to convert them from the C
side. This patch adds a `from_bits` function, which is unsafe since
the bits in question may not represent a valid combination of flags.
Finally, this patch changes `std::io::FilePermissions` from an exposed
`u32` representation to a typesafe representation (that only allows valid
flag combinations) using the `std::bitflags`.
Closes #6085.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/bitflags.rs | 71 | ||||
| -rw-r--r-- | src/libstd/io/fs.rs | 6 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 71 |
3 files changed, 87 insertions, 61 deletions
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs index bf12dd2d94a..5737bc772df 100644 --- a/src/libstd/bitflags.rs +++ b/src/libstd/bitflags.rs @@ -17,14 +17,16 @@ //! # Example //! //! ~~~rust -//! bitflags!(Flags: u32 { -//! FlagA = 0x00000001, -//! FlagB = 0x00000010, -//! FlagC = 0x00000100, -//! FlagABC = FlagA.bits -//! | FlagB.bits -//! | FlagC.bits -//! }) +//! 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; @@ -40,10 +42,12 @@ //! ~~~rust //! use std::fmt; //! -//! bitflags!(Flags: u32 { -//! FlagA = 0x00000001, -//! FlagB = 0x00000010 -//! }) +//! bitflags!( +//! flags Flags: u32 { +//! static FlagA = 0x00000001, +//! static FlagB = 0x00000010 +//! } +//! ) //! //! impl Flags { //! pub fn clear(&mut self) { @@ -66,10 +70,16 @@ //! } //! ~~~ //! +//! # Attributes +//! +//! Attributes can be attached to the generated `struct` by placing them +//! before the `flags` keyword. +//! //! # Derived traits //! -//! The `Eq`, `TotalEq`, and `Clone` traits are automatically derived for the -//! `struct` using the `deriving` attribute. +//! The `Eq` 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 //! @@ -91,17 +101,20 @@ //! - `insert`: inserts the specified flags in-place //! - `remove`: removes the specified flags in-place +#![macro_escape] + #[macro_export] macro_rules! bitflags( - ($BitFlags:ident: $T:ty { - $($Flag:ident = $value:expr),+ + ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { + $($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+ }) => ( #[deriving(Eq, TotalEq, Clone)] + $(#[$attr])* pub struct $BitFlags { bits: $T, } - $(pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+ + $($(#[$Flag_attr])* pub static $Flag: $BitFlags = $BitFlags { bits: $value };)+ impl $BitFlags { /// Returns an empty set of flags. @@ -114,6 +127,12 @@ macro_rules! bitflags( self.bits } + /// Convert from underlying bit representation. Unsafe because the + /// bits are not guaranteed to represent valid flags. + pub unsafe fn from_bits(bits: $T) -> $BitFlags { + $BitFlags { bits: bits } + } + /// Returns `true` if no flags are currently stored. pub fn is_empty(&self) -> bool { *self == $BitFlags::empty() @@ -170,14 +189,16 @@ macro_rules! bitflags( mod tests { use ops::{BitOr, BitAnd, Sub}; - bitflags!(Flags: u32 { - FlagA = 0x00000001, - FlagB = 0x00000010, - FlagC = 0x00000100, - FlagABC = FlagA.bits - | FlagB.bits - | FlagC.bits - }) + bitflags!( + flags Flags: u32 { + static FlagA = 0x00000001, + static FlagB = 0x00000010, + static FlagC = 0x00000100, + static FlagABC = FlagA.bits + | FlagB.bits + | FlagC.bits + } + ) #[test] fn test_bits(){ diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index cd304250b19..6d48b9eee35 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -1119,7 +1119,7 @@ mod test { check!(File::create(&input)); check!(chmod(&input, io::UserRead)); check!(copy(&input, &out)); - assert!(check!(out.stat()).perm & io::UserWrite == 0); + assert!(!check!(out.stat()).perm.intersects(io::UserWrite)); check!(chmod(&input, io::UserFile)); check!(chmod(&out, io::UserFile)); @@ -1193,9 +1193,9 @@ mod test { let file = tmpdir.join("in.txt"); check!(File::create(&file)); - assert!(check!(stat(&file)).perm & io::UserWrite == io::UserWrite); + assert!(check!(stat(&file)).perm.contains(io::UserWrite)); check!(chmod(&file, io::UserRead)); - assert!(check!(stat(&file)).perm & io::UserWrite == 0); + assert!(!check!(stat(&file)).perm.contains(io::UserWrite)); match chmod(&tmpdir.join("foo"), io::UserRWX) { Ok(..) => fail!("wanted a failure"), diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index d948738ac56..ff276d02028 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -224,6 +224,7 @@ use fmt; use int; use iter::Iterator; use libc; +use ops::{BitOr, BitAnd, Sub}; use os; use option::{Option, Some, None}; use path::Path; @@ -1558,36 +1559,40 @@ pub struct UnstableFileStat { pub gen: u64, } -/// A set of permissions for a file or directory is represented by a set of -/// flags which are or'd together. -pub type FilePermission = u32; - -// Each permission bit -pub static UserRead: FilePermission = 0x100; -pub static UserWrite: FilePermission = 0x080; -pub static UserExecute: FilePermission = 0x040; -pub static GroupRead: FilePermission = 0x020; -pub static GroupWrite: FilePermission = 0x010; -pub static GroupExecute: FilePermission = 0x008; -pub static OtherRead: FilePermission = 0x004; -pub static OtherWrite: FilePermission = 0x002; -pub static OtherExecute: FilePermission = 0x001; - -// Common combinations of these bits -pub static UserRWX: FilePermission = UserRead | UserWrite | UserExecute; -pub static GroupRWX: FilePermission = GroupRead | GroupWrite | GroupExecute; -pub static OtherRWX: FilePermission = OtherRead | OtherWrite | OtherExecute; - -/// A set of permissions for user owned files, this is equivalent to 0644 on -/// unix-like systems. -pub static UserFile: FilePermission = UserRead | UserWrite | GroupRead | OtherRead; -/// A set of permissions for user owned directories, this is equivalent to 0755 -/// on unix-like systems. -pub static UserDir: FilePermission = UserRWX | GroupRead | GroupExecute | - OtherRead | OtherExecute; -/// A set of permissions for user owned executables, this is equivalent to 0755 -/// on unix-like systems. -pub static UserExec: FilePermission = UserDir; - -/// A mask for all possible permission bits -pub static AllPermissions: FilePermission = 0x1ff; +bitflags!( + #[doc="A set of permissions for a file or directory is represented +by a set of flags which are or'd together."] + #[deriving(Hash)] + #[deriving(Show)] + flags FilePermission: u32 { + static UserRead = 0o400, + static UserWrite = 0o200, + static UserExecute = 0o100, + static GroupRead = 0o040, + static GroupWrite = 0o020, + static GroupExecute = 0o010, + static OtherRead = 0o004, + static OtherWrite = 0o002, + static OtherExecute = 0o001, + + static UserRWX = UserRead.bits | UserWrite.bits | UserExecute.bits, + 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."] + static UserFile = UserRead.bits | UserWrite.bits | GroupRead.bits | OtherRead.bits, + + #[doc="Permissions for user owned directories, equivalent to 0755 on +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."] + static UserExec = UserDir.bits, + + #[doc="All possible permissions enabled."] + static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits + } +) |
