Skip to content

Commit c3e8823

Browse files
committed
---
yaml --- r: 145943 b: refs/heads/try2 c: 179f50f h: refs/heads/master i: 145941: 0935e87 145939: 527c194 145935: 1bf2620 v: v3
1 parent e9b33a8 commit c3e8823

File tree

4 files changed

+153
-19
lines changed

4 files changed

+153
-19
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: 56b96a3bfcbb37856c333a0042c365c314a54e6a
8+
refs/heads/try2: 179f50f7c8a4071eb4e28e5b812106d6a3c148c7
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libstd/path2/mod.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -540,13 +540,13 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
540540
}
541541
/// Pops the last path component off of `self` and returns it.
542542
/// If `self` represents the root of the file hierarchy, None is returned.
543-
fn pop_opt(&mut self) -> Option<~[u8]>;
543+
fn pop(&mut self) -> Option<~[u8]>;
544544
/// Pops the last path component off of `self` and returns it as a string, if possible.
545545
/// `self` will still be modified even if None is returned.
546-
/// See `pop_opt` for details.
546+
/// See `pop` for details.
547547
#[inline]
548-
fn pop_opt_str(&mut self) -> Option<~str> {
549-
self.pop_opt().and_then(|v| str::from_utf8_owned_opt(v))
548+
fn pop_str(&mut self) -> Option<~str> {
549+
self.pop().and_then(|v| str::from_utf8_owned_opt(v))
550550
}
551551

552552
/// Returns a new Path constructed by joining `self` with the given path (as a byte vector).
@@ -593,6 +593,21 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
593593
/// If `self` is absolute and `base` is relative, or on Windows if both
594594
/// paths refer to separate drives, an absolute path is returned.
595595
fn path_relative_from(&self, base: &Self) -> Option<Self>;
596+
597+
/// Executes a callback with the receiver and every parent
598+
fn each_parent(&self, f: &fn(&Self) -> bool) -> bool {
599+
let mut p = self.clone();
600+
loop {
601+
if !f(&p) {
602+
return false;
603+
}
604+
let f = p.pop();
605+
if f.is_none() || bytes!("..") == f.unwrap() {
606+
break;
607+
}
608+
}
609+
true
610+
}
596611
}
597612

598613
/// A trait that represents the unsafe operations on GenericPaths

branches/try2/src/libstd/path2/posix.rs

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ impl GenericPath for Path {
196196
}
197197
}
198198

199-
fn pop_opt(&mut self) -> Option<~[u8]> {
199+
fn pop(&mut self) -> Option<~[u8]> {
200200
match self.sepidx {
201201
None if bytes!(".") == self.repr => None,
202202
None => {
@@ -400,7 +400,7 @@ fn normalize_helper<'a>(v: &'a [u8], is_abs: bool) -> Option<~[&'a [u8]]> {
400400
else if comp == bytes!("..") {
401401
if is_abs && comps.is_empty() { changed = true }
402402
else if comps.len() == n_up { comps.push(dot_dot_static); n_up += 1 }
403-
else { comps.pop_opt(); changed = true }
403+
else { comps.pop(); changed = true }
404404
} else { comps.push(comp) }
405405
}
406406
if changed {
@@ -861,23 +861,23 @@ mod tests {
861861
(s: $path:expr, $left:expr, $right:expr) => (
862862
{
863863
let mut p = Path::from_str($path);
864-
let file = p.pop_opt_str();
864+
let file = p.pop_str();
865865
assert_eq!(p.as_str(), Some($left));
866866
assert_eq!(file.map(|s| s.as_slice()), $right);
867867
}
868868
);
869869
(v: [$($path:expr),+], [$($left:expr),+], Some($($right:expr),+)) => (
870870
{
871871
let mut p = Path::from_vec(b!($($path),+));
872-
let file = p.pop_opt();
872+
let file = p.pop();
873873
assert_eq!(p.as_vec(), b!($($left),+));
874874
assert_eq!(file.map(|v| v.as_slice()), Some(b!($($right),+)));
875875
}
876876
);
877877
(v: [$($path:expr),+], [$($left:expr),+], None) => (
878878
{
879879
let mut p = Path::from_vec(b!($($path),+));
880-
let file = p.pop_opt();
880+
let file = p.pop();
881881
assert_eq!(p.as_vec(), b!($($left),+));
882882
assert_eq!(file, None);
883883
}
@@ -899,8 +899,8 @@ mod tests {
899899
t!(s: "/a", "/", Some("a"));
900900
t!(s: "/", "/", None);
901901

902-
assert_eq!(Path::from_vec(b!("foo/bar", 0x80)).pop_opt_str(), None);
903-
assert_eq!(Path::from_vec(b!("foo", 0x80, "/bar")).pop_opt_str(), Some(~"bar"));
902+
assert_eq!(Path::from_vec(b!("foo/bar", 0x80)).pop_str(), None);
903+
assert_eq!(Path::from_vec(b!("foo", 0x80, "/bar")).pop_str(), Some(~"bar"));
904904
}
905905
906906
#[test]
@@ -1310,4 +1310,58 @@ mod tests {
13101310
t!(s: "../..", ["..", ".."]);
13111311
t!(s: "../../foo", ["..", "..", "foo"]);
13121312
}
1313+
1314+
#[test]
1315+
fn test_each_parent() {
1316+
assert!(Path::from_str("/foo/bar").each_parent(|_| true));
1317+
assert!(!Path::from_str("/foo/bar").each_parent(|_| false));
1318+
1319+
macro_rules! t(
1320+
(s: $path:expr, $exp:expr) => (
1321+
{
1322+
let path = Path::from_str($path);
1323+
let exp: &[&str] = $exp;
1324+
let mut comps = exp.iter().map(|&x|x);
1325+
do path.each_parent |p| {
1326+
let p = p.as_str();
1327+
assert!(p.is_some());
1328+
let e = comps.next();
1329+
assert!(e.is_some());
1330+
assert_eq!(p.unwrap(), e.unwrap());
1331+
true
1332+
};
1333+
assert!(comps.next().is_none());
1334+
}
1335+
);
1336+
(v: $path:expr, $exp:expr) => (
1337+
{
1338+
let path = Path::from_vec($path);
1339+
let exp: &[&[u8]] = $exp;
1340+
let mut comps = exp.iter().map(|&x|x);
1341+
do path.each_parent |p| {
1342+
let p = p.as_vec();
1343+
let e = comps.next();
1344+
assert!(e.is_some());
1345+
assert_eq!(p, e.unwrap());
1346+
true
1347+
};
1348+
assert!(comps.next().is_none());
1349+
}
1350+
)
1351+
)
1352+
1353+
t!(s: "/foo/bar", ["/foo/bar", "/foo", "/"]);
1354+
t!(s: "/foo/bar/baz", ["/foo/bar/baz", "/foo/bar", "/foo", "/"]);
1355+
t!(s: "/foo", ["/foo", "/"]);
1356+
t!(s: "/", ["/"]);
1357+
t!(s: "foo/bar/baz", ["foo/bar/baz", "foo/bar", "foo", "."]);
1358+
t!(s: "foo/bar", ["foo/bar", "foo", "."]);
1359+
t!(s: "foo", ["foo", "."]);
1360+
t!(s: ".", ["."]);
1361+
t!(s: "..", [".."]);
1362+
t!(s: "../../foo", ["../../foo", "../.."]);
1363+
1364+
t!(v: b!("foo/bar", 0x80), [b!("foo/bar", 0x80), b!("foo"), b!(".")]);
1365+
t!(v: b!(0xff, "/bar"), [b!(0xff, "/bar"), b!(0xff), b!(".")]);
1366+
}
13131367
}

branches/try2/src/libstd/path2/windows.rs

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -446,11 +446,11 @@ impl GenericPath for Path {
446446
}
447447

448448
#[inline]
449-
fn pop_opt(&mut self) -> Option<~[u8]> {
450-
self.pop_opt_str().map_move(|s| s.into_bytes())
449+
fn pop(&mut self) -> Option<~[u8]> {
450+
self.pop_str().map_move(|s| s.into_bytes())
451451
}
452452

453-
fn pop_opt_str(&mut self) -> Option<~str> {
453+
fn pop_str(&mut self) -> Option<~str> {
454454
match self.sepidx_or_prefix_len() {
455455
None if "." == self.repr => None,
456456
None => {
@@ -599,6 +599,21 @@ impl GenericPath for Path {
599599
Some(Path::from_str(comps.connect("\\")))
600600
}
601601
}
602+
603+
/// Executes a callback with the receiver and every parent
604+
fn each_parent(&self, f: &fn(&Path) -> bool) -> bool {
605+
let mut p = self.clone();
606+
loop {
607+
if !f(&p) {
608+
return false;
609+
}
610+
let f = p.pop();
611+
if f.is_none() || (!p.is_verbatim() && bytes!("..") == f.unwrap()) {
612+
break;
613+
}
614+
}
615+
true
616+
}
602617
}
603618

604619
impl Path {
@@ -1013,7 +1028,7 @@ fn normalize_helper<'a>(s: &'a str, prefix: Option<PathPrefix>) -> (bool,Option<
10131028
};
10141029
if (is_abs || has_abs_prefix) && comps.is_empty() { changed = true }
10151030
else if comps.len() == n_up { comps.push(".."); n_up += 1 }
1016-
else { comps.pop_opt(); changed = true }
1031+
else { comps.pop(); changed = true }
10171032
} else { comps.push(comp) }
10181033
}
10191034
if !changed && !prefix_is_verbatim(prefix) {
@@ -1654,7 +1669,7 @@ mod tests {
16541669
{
16551670
let pstr = $path;
16561671
let mut p = Path::from_str(pstr);
1657-
let file = p.pop_opt_str();
1672+
let file = p.pop_str();
16581673
let left = $left;
16591674
assert!(p.as_str() == Some(left),
16601675
"`%s`.pop() failed; expected remainder `%s`, found `%s`",
@@ -1668,15 +1683,15 @@ mod tests {
16681683
(v: [$($path:expr),+], [$($left:expr),+], Some($($right:expr),+)) => (
16691684
{
16701685
let mut p = Path::from_vec(b!($($path),+));
1671-
let file = p.pop_opt();
1686+
let file = p.pop();
16721687
assert_eq!(p.as_vec(), b!($($left),+));
16731688
assert_eq!(file.map(|v| v.as_slice()), Some(b!($($right),+)));
16741689
}
16751690
);
16761691
(v: [$($path:expr),+], [$($left:expr),+], None) => (
16771692
{
16781693
let mut p = Path::from_vec(b!($($path),+));
1679-
let file = p.pop_opt();
1694+
let file = p.pop();
16801695
assert_eq!(p.as_vec(), b!($($left),+));
16811696
assert_eq!(file, None);
16821697
}
@@ -2373,4 +2388,54 @@ mod tests {
23732388
t!(s: "\\\\.\\foo\\bar", ["bar"]);
23742389
t!(s: "\\\\.\\foo", []);
23752390
}
2391+
2392+
#[test]
2393+
fn test_each_parent() {
2394+
assert!(Path::from_str("/foo/bar").each_parent(|_| true));
2395+
assert!(!Path::from_str("/foo/bar").each_parent(|_| false));
2396+
2397+
macro_rules! t(
2398+
(s: $path:expr, $exp:expr) => (
2399+
{
2400+
let path = Path::from_str($path);
2401+
let exp: &[&str] = $exp;
2402+
let mut comps = exp.iter().map(|&x|x);
2403+
do path.each_parent |p| {
2404+
let p = p.as_str();
2405+
assert!(p.is_some());
2406+
let e = comps.next();
2407+
assert!(e.is_some());
2408+
assert_eq!(p.unwrap(), e.unwrap());
2409+
true
2410+
};
2411+
assert!(comps.next().is_none());
2412+
}
2413+
)
2414+
)
2415+
2416+
t!(s: "\\foo\\bar", ["\\foo\\bar", "\\foo", "\\"]);
2417+
t!(s: "\\foo\\bar\\baz", ["\\foo\\bar\\baz", "\\foo\\bar", "\\foo", "\\"]);
2418+
t!(s: "\\foo", ["\\foo", "\\"]);
2419+
t!(s: "\\", ["\\"]);
2420+
t!(s: "foo\\bar\\baz", ["foo\\bar\\baz", "foo\\bar", "foo", "."]);
2421+
t!(s: "foo\\bar", ["foo\\bar", "foo", "."]);
2422+
t!(s: "foo", ["foo", "."]);
2423+
t!(s: ".", ["."]);
2424+
t!(s: "..", [".."]);
2425+
t!(s: "..\\..\\foo", ["..\\..\\foo", "..\\.."]);
2426+
t!(s: "C:\\a\\b", ["C:\\a\\b", "C:\\a", "C:\\"]);
2427+
t!(s: "C:\\", ["C:\\"]);
2428+
t!(s: "C:a\\b", ["C:a\\b", "C:a", "C:"]);
2429+
t!(s: "C:", ["C:"]);
2430+
t!(s: "C:..\\..\\a", ["C:..\\..\\a", "C:..\\.."]);
2431+
t!(s: "C:..", ["C:.."]);
2432+
t!(s: "\\\\a\\b\\c", ["\\\\a\\b\\c", "\\\\a\\b"]);
2433+
t!(s: "\\\\a\\b", ["\\\\a\\b"]);
2434+
t!(s: "\\\\?\\a\\b\\c", ["\\\\?\\a\\b\\c", "\\\\?\\a\\b", "\\\\?\\a"]);
2435+
t!(s: "\\\\?\\C:\\a\\b", ["\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", "\\\\?\\C:\\"]);
2436+
t!(s: "\\\\?\\UNC\\a\\b\\c", ["\\\\?\\UNC\\a\\b\\c", "\\\\?\\UNC\\a\\b"]);
2437+
t!(s: "\\\\.\\a\\b\\c", ["\\\\.\\a\\b\\c", "\\\\.\\a\\b", "\\\\.\\a"]);
2438+
t!(s: "\\\\?\\a\\..\\b\\.\\c/d", ["\\\\?\\a\\..\\b\\.\\c/d", "\\\\?\\a\\..\\b\\.",
2439+
"\\\\?\\a\\..\\b", "\\\\?\\a\\..", "\\\\?\\a"]);
2440+
}
23762441
}

0 commit comments

Comments
 (0)