From f13086f4571e13f712b9606fddbee47f40c40842 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 18 Jan 2014 09:17:44 -0800 Subject: [PATCH] Expose platform independent path separators --- src/libstd/path/mod.rs | 14 +++++++++++ src/libstd/path/posix.rs | 40 ++++++++++++++++--------------- src/libstd/path/windows.rs | 49 +++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index 56e86afaaef12..253d99c11ebac 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -117,6 +117,20 @@ pub use StrComponents = self::windows::StrComponents; #[cfg(windows)] pub use RevStrComponents = self::windows::RevStrComponents; +/// Alias for the platform-native separator character. +#[cfg(unix)] +pub use SEP = self::posix::SEP; +/// Alias for the platform-native separator byte. +#[cfg(windows)] +pub use SEP = self::windows::SEP; + +/// Alias for the platform-native separator character. +#[cfg(unix)] +pub use SEP_BYTE = self::posix::SEP_BYTE; +/// Alias for the platform-native separator byte. +#[cfg(windows)] +pub use SEP_BYTE = self::windows::SEP_BYTE; + /// Typedef for the platform-native separator char func #[cfg(unix)] pub use is_sep = self::posix::is_sep; diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 0a93f385a0632..b228dc7f1ffbd 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -45,19 +45,21 @@ pub struct Path { } /// The standard path separator character -pub static sep: char = '/'; -static sep_byte: u8 = sep as u8; +pub static SEP: char = '/'; + +/// The standard path separator byte +pub static SEP_BYTE: u8 = SEP as u8; /// Returns whether the given byte is a path separator #[inline] pub fn is_sep_byte(u: &u8) -> bool { - *u as char == sep + *u as char == SEP } /// Returns whether the given char is a path separator #[inline] pub fn is_sep(c: char) -> bool { - c == sep + c == SEP } impl Eq for Path { @@ -115,7 +117,7 @@ impl GenericPathUnsafe for Path { unsafe fn new_unchecked(path: T) -> Path { let path = Path::normalize(path.container_as_bytes()); assert!(!path.is_empty()); - let idx = path.rposition_elem(&sep_byte); + let idx = path.rposition_elem(&SEP_BYTE); Path{ repr: path, sepidx: idx } } @@ -125,7 +127,7 @@ impl GenericPathUnsafe for Path { None if bytes!("..") == self.repr => { let mut v = vec::with_capacity(3 + filename.len()); v.push_all(dot_dot_static); - v.push(sep_byte); + v.push(SEP_BYTE); v.push_all(filename); self.repr = Path::normalize(v); } @@ -135,7 +137,7 @@ impl GenericPathUnsafe for Path { Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => { let mut v = vec::with_capacity(self.repr.len() + 1 + filename.len()); v.push_all(self.repr); - v.push(sep_byte); + v.push(SEP_BYTE); v.push_all(filename); self.repr = Path::normalize(v); } @@ -146,22 +148,22 @@ impl GenericPathUnsafe for Path { self.repr = Path::normalize(v); } } - self.sepidx = self.repr.rposition_elem(&sep_byte); + self.sepidx = self.repr.rposition_elem(&SEP_BYTE); } unsafe fn push_unchecked(&mut self, path: T) { let path = path.container_as_bytes(); if !path.is_empty() { - if path[0] == sep_byte { + if path[0] == SEP_BYTE { self.repr = Path::normalize(path); } else { let mut v = vec::with_capacity(self.repr.len() + path.len() + 1); v.push_all(self.repr); - v.push(sep_byte); + v.push(SEP_BYTE); v.push_all(path); self.repr = Path::normalize(v); } - self.sepidx = self.repr.rposition_elem(&sep_byte); + self.sepidx = self.repr.rposition_elem(&SEP_BYTE); } } } @@ -211,7 +213,7 @@ impl GenericPath for Path { } else { self.repr.truncate(idx); } - self.sepidx = self.repr.rposition_elem(&sep_byte); + self.sepidx = self.repr.rposition_elem(&SEP_BYTE); true } } @@ -227,7 +229,7 @@ impl GenericPath for Path { #[inline] fn is_absolute(&self) -> bool { - self.repr[0] == sep_byte + self.repr[0] == SEP_BYTE } fn is_ancestor_of(&self, other: &Path) -> bool { @@ -291,7 +293,7 @@ impl GenericPath for Path { } } } - Some(Path::new(comps.connect_vec(&sep_byte))) + Some(Path::new(comps.connect_vec(&SEP_BYTE))) } } @@ -333,14 +335,14 @@ impl Path { fn normalize+CopyableVector>(v: V) -> ~[u8] { // borrowck is being very picky let val = { - let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == sep_byte; + let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE; let v_ = if is_abs { v.as_slice().slice_from(1) } else { v.as_slice() }; let comps = normalize_helper(v_, is_abs); match comps { None => None, Some(comps) => { if is_abs && comps.is_empty() { - Some(~[sep_byte]) + Some(~[SEP_BYTE]) } else { let n = if is_abs { comps.len() } else { comps.len() - 1} + comps.iter().map(|v| v.len()).sum(); @@ -353,7 +355,7 @@ impl Path { } } for comp in it { - v.push(sep_byte); + v.push(SEP_BYTE); v.push_all(comp); } Some(v) @@ -372,7 +374,7 @@ impl Path { /// /a/b/c and a/b/c yield the same set of components. /// A path of "/" yields no components. A path of "." yields one component. pub fn components<'a>(&'a self) -> Components<'a> { - let v = if self.repr[0] == sep_byte { + let v = if self.repr[0] == SEP_BYTE { self.repr.slice_from(1) } else { self.repr.as_slice() }; let mut ret = v.split(is_sep_byte); @@ -386,7 +388,7 @@ impl Path { /// Returns an iterator that yields each component of the path in reverse. /// See components() for details. pub fn rev_components<'a>(&'a self) -> RevComponents<'a> { - let v = if self.repr[0] == sep_byte { + let v = if self.repr[0] == SEP_BYTE { self.repr.slice_from(1) } else { self.repr.as_slice() }; let mut ret = v.rsplit(is_sep_byte); diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index a529aaf0a247b..86a9d2235d05f 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -183,7 +183,7 @@ impl GenericPathUnsafe for Path { None if ".." == self.repr => { let mut s = str::with_capacity(3 + filename.len()); s.push_str(".."); - s.push_char(sep); + s.push_char(SEP); s.push_str(filename); self.update_normalized(s); } @@ -193,7 +193,7 @@ impl GenericPathUnsafe for Path { Some((_,idxa,end)) if self.repr.slice(idxa,end) == ".." => { let mut s = str::with_capacity(end + 1 + filename.len()); s.push_str(self.repr.slice_to(end)); - s.push_char(sep); + s.push_char(SEP); s.push_str(filename); self.update_normalized(s); } @@ -206,7 +206,7 @@ impl GenericPathUnsafe for Path { Some((idxb,_,_)) => { let mut s = str::with_capacity(idxb + 1 + filename.len()); s.push_str(self.repr.slice_to(idxb)); - s.push_char(sep); + s.push_char(SEP); s.push_str(filename); self.update_normalized(s); } @@ -264,8 +264,8 @@ impl GenericPathUnsafe for Path { // if me is "C:" we don't want to add a path separator match me.prefix { Some(DiskPrefix) if me.repr.len() == plen => (), - _ if !(me.repr.len() > plen && me.repr[me.repr.len()-1] == sep as u8) => { - s.push_char(sep); + _ if !(me.repr.len() > plen && me.repr[me.repr.len()-1] == SEP_BYTE) => { + s.push_char(SEP); } _ => () } @@ -460,7 +460,7 @@ impl GenericPath for Path { match self.prefix { Some(DiskPrefix) => { let rest = self.repr.slice_from(self.prefix_len()); - rest.len() > 0 && rest[0] == sep as u8 + rest.len() > 0 && rest[0] == SEP_BYTE } Some(_) => true, None => false @@ -501,7 +501,7 @@ impl GenericPath for Path { fn path_relative_from(&self, base: &Path) -> Option { fn comp_requires_verbatim(s: &str) -> bool { - s == "." || s == ".." || s.contains_char(sep2) + s == "." || s == ".." || s.contains_char(SEP2) } if !self.equiv_prefix(base) { @@ -619,14 +619,14 @@ impl Path { let s = match self.prefix { Some(_) => { let plen = self.prefix_len(); - if self.repr.len() > plen && self.repr[plen] == sep as u8 { + if self.repr.len() > plen && self.repr[plen] == SEP_BYTE { self.repr.slice_from(plen+1) } else { self.repr.slice_from(plen) } } - None if self.repr[0] == sep as u8 => self.repr.slice_from(1), + None if self.repr[0] == SEP_BYTE => self.repr.slice_from(1), None => self.repr.as_slice() }; - let ret = s.split_terminator(sep).map(Some); + let ret = s.split_terminator(SEP).map(Some); ret } @@ -703,7 +703,7 @@ impl Path { Some(VerbatimUNCPrefix(x, 0)) if s.len() == 8 + x => { // the server component has no trailing '\' let mut s = s.into_owned(); - s.push_char(sep); + s.push_char(SEP); Some(s) } _ => None @@ -739,7 +739,7 @@ impl Path { if is_abs { // normalize C:/ to C:\ unsafe { - str::raw::as_owned_vec(&mut s)[2] = sep as u8; + str::raw::as_owned_vec(&mut s)[2] = SEP_BYTE; } } Some(s) @@ -761,7 +761,7 @@ impl Path { } } } else if is_abs && comps.is_empty() { - Some(str::from_char(sep)) + Some(str::from_char(SEP)) } else { let prefix_ = s.slice_to(prefix_len(prefix)); let n = prefix_.len() + @@ -781,7 +781,7 @@ impl Path { Some(UNCPrefix(a,b)) => { s.push_str("\\\\"); s.push_str(prefix_.slice(2, a+2)); - s.push_char(sep); + s.push_char(SEP); s.push_str(prefix_.slice(3+a, 3+a+b)); } Some(_) => s.push_str(prefix_), @@ -795,7 +795,7 @@ impl Path { } } for comp in it { - s.push_char(sep); + s.push_char(SEP); s.push_str(comp); } Some(s) @@ -837,7 +837,7 @@ impl Path { fn has_nonsemantic_trailing_slash(&self) -> bool { is_verbatim(self) && self.repr.len() > self.prefix_len()+1 && - self.repr[self.repr.len()-1] == sep as u8 + self.repr[self.repr.len()-1] == SEP_BYTE } fn update_normalized(&mut self, s: S) { @@ -877,36 +877,41 @@ pub fn is_verbatim(path: &Path) -> bool { } /// The standard path separator character -pub static sep: char = '\\'; +pub static SEP: char = '\\'; +/// The standard path separator byte +pub static SEP_BYTE: u8 = SEP as u8; + +/// The alternative path separator character +pub static SEP2: char = '/'; /// The alternative path separator character -pub static sep2: char = '/'; +pub static SEP2_BYTE: u8 = SEP2 as u8; /// Returns whether the given char is a path separator. /// Allows both the primary separator '\' and the alternative separator '/'. #[inline] pub fn is_sep(c: char) -> bool { - c == sep || c == sep2 + c == SEP || c == SEP2 } /// Returns whether the given char is a path separator. /// Only allows the primary separator '\'; use is_sep to allow '/'. #[inline] pub fn is_sep_verbatim(c: char) -> bool { - c == sep + c == SEP } /// Returns whether the given byte is a path separator. /// Allows both the primary separator '\' and the alternative separator '/'. #[inline] pub fn is_sep_byte(u: &u8) -> bool { - *u as char == sep || *u as char == sep2 + *u == SEP_BYTE || *u == SEP2_BYTE } /// Returns whether the given byte is a path separator. /// Only allows the primary separator '\'; use is_sep_byte to allow '/'. #[inline] pub fn is_sep_byte_verbatim(u: &u8) -> bool { - *u as char == sep + *u == SEP_BYTE } /// Prefix types for Path