Skip to content

Commit e6457bb

Browse files
committed
std: Move platform specific path code into sys
1 parent df9fa1a commit e6457bb

File tree

5 files changed

+141
-126
lines changed

5 files changed

+141
-126
lines changed

src/libstd/path.rs

Lines changed: 2 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ use ops::{self, Deref};
113113

114114
use ffi::{OsStr, OsString};
115115

116-
use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
116+
use sys::path::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
117117

118118
////////////////////////////////////////////////////////////////////////////////
119119
// GENERAL NOTES
@@ -125,130 +125,6 @@ use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
125125
// OsStr APIs for parsing, but it will take a while for those to become
126126
// available.
127127

128-
////////////////////////////////////////////////////////////////////////////////
129-
// Platform-specific definitions
130-
////////////////////////////////////////////////////////////////////////////////
131-
132-
// The following modules give the most basic tools for parsing paths on various
133-
// platforms. The bulk of the code is devoted to parsing prefixes on Windows.
134-
135-
#[cfg(unix)]
136-
mod platform {
137-
use super::Prefix;
138-
use ffi::OsStr;
139-
140-
#[inline]
141-
pub fn is_sep_byte(b: u8) -> bool {
142-
b == b'/'
143-
}
144-
145-
#[inline]
146-
pub fn is_verbatim_sep(b: u8) -> bool {
147-
b == b'/'
148-
}
149-
150-
pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
151-
None
152-
}
153-
154-
pub const MAIN_SEP_STR: &'static str = "/";
155-
pub const MAIN_SEP: char = '/';
156-
}
157-
158-
#[cfg(windows)]
159-
mod platform {
160-
use ascii::*;
161-
162-
use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix};
163-
use ffi::OsStr;
164-
165-
#[inline]
166-
pub fn is_sep_byte(b: u8) -> bool {
167-
b == b'/' || b == b'\\'
168-
}
169-
170-
#[inline]
171-
pub fn is_verbatim_sep(b: u8) -> bool {
172-
b == b'\\'
173-
}
174-
175-
pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
176-
use super::Prefix::*;
177-
unsafe {
178-
// The unsafety here stems from converting between &OsStr and &[u8]
179-
// and back. This is safe to do because (1) we only look at ASCII
180-
// contents of the encoding and (2) new &OsStr values are produced
181-
// only from ASCII-bounded slices of existing &OsStr values.
182-
let mut path = os_str_as_u8_slice(path);
183-
184-
if path.starts_with(br"\\") {
185-
// \\
186-
path = &path[2..];
187-
if path.starts_with(br"?\") {
188-
// \\?\
189-
path = &path[2..];
190-
if path.starts_with(br"UNC\") {
191-
// \\?\UNC\server\share
192-
path = &path[4..];
193-
let (server, share) = match parse_two_comps(path, is_verbatim_sep) {
194-
Some((server, share)) =>
195-
(u8_slice_as_os_str(server), u8_slice_as_os_str(share)),
196-
None => (u8_slice_as_os_str(path), u8_slice_as_os_str(&[])),
197-
};
198-
return Some(VerbatimUNC(server, share));
199-
} else {
200-
// \\?\path
201-
let idx = path.iter().position(|&b| b == b'\\');
202-
if idx == Some(2) && path[1] == b':' {
203-
let c = path[0];
204-
if c.is_ascii() && (c as char).is_alphabetic() {
205-
// \\?\C:\ path
206-
return Some(VerbatimDisk(c.to_ascii_uppercase()));
207-
}
208-
}
209-
let slice = &path[..idx.unwrap_or(path.len())];
210-
return Some(Verbatim(u8_slice_as_os_str(slice)));
211-
}
212-
} else if path.starts_with(b".\\") {
213-
// \\.\path
214-
path = &path[2..];
215-
let pos = path.iter().position(|&b| b == b'\\');
216-
let slice = &path[..pos.unwrap_or(path.len())];
217-
return Some(DeviceNS(u8_slice_as_os_str(slice)));
218-
}
219-
match parse_two_comps(path, is_sep_byte) {
220-
Some((server, share)) if !server.is_empty() && !share.is_empty() => {
221-
// \\server\share
222-
return Some(UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share)));
223-
}
224-
_ => (),
225-
}
226-
} else if path.get(1) == Some(& b':') {
227-
// C:
228-
let c = path[0];
229-
if c.is_ascii() && (c as char).is_alphabetic() {
230-
return Some(Disk(c.to_ascii_uppercase()));
231-
}
232-
}
233-
return None;
234-
}
235-
236-
fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> {
237-
let first = match path.iter().position(|x| f(*x)) {
238-
None => return None,
239-
Some(x) => &path[..x],
240-
};
241-
path = &path[(first.len() + 1)..];
242-
let idx = path.iter().position(|x| f(*x));
243-
let second = &path[..idx.unwrap_or(path.len())];
244-
Some((first, second))
245-
}
246-
}
247-
248-
pub const MAIN_SEP_STR: &'static str = "\\";
249-
pub const MAIN_SEP: char = '\\';
250-
}
251-
252128
////////////////////////////////////////////////////////////////////////////////
253129
// Windows Prefixes
254130
////////////////////////////////////////////////////////////////////////////////
@@ -373,7 +249,7 @@ pub fn is_separator(c: char) -> bool {
373249

374250
/// The primary separator for the current platform
375251
#[stable(feature = "rust1", since = "1.0.0")]
376-
pub const MAIN_SEPARATOR: char = platform::MAIN_SEP;
252+
pub const MAIN_SEPARATOR: char = ::sys::path::MAIN_SEP;
377253

378254
////////////////////////////////////////////////////////////////////////////////
379255
// Misc helpers

src/libstd/sys/unix/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub mod mutex;
4141
pub mod net;
4242
pub mod os;
4343
pub mod os_str;
44+
pub mod path;
4445
pub mod pipe;
4546
pub mod process;
4647
pub mod rand;

src/libstd/sys/unix/path.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use path::Prefix;
12+
use ffi::OsStr;
13+
14+
#[inline]
15+
pub fn is_sep_byte(b: u8) -> bool {
16+
b == b'/'
17+
}
18+
19+
#[inline]
20+
pub fn is_verbatim_sep(b: u8) -> bool {
21+
b == b'/'
22+
}
23+
24+
pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
25+
None
26+
}
27+
28+
pub const MAIN_SEP_STR: &'static str = "/";
29+
pub const MAIN_SEP: char = '/';

src/libstd/sys/windows/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub mod mutex;
2929
pub mod net;
3030
pub mod os;
3131
pub mod os_str;
32+
pub mod path;
3233
pub mod pipe;
3334
pub mod process;
3435
pub mod rand;

src/libstd/sys/windows/path.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use ascii::*;
12+
13+
use path::Prefix;
14+
use ffi::OsStr;
15+
use mem;
16+
17+
fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
18+
unsafe { mem::transmute(s) }
19+
}
20+
unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
21+
mem::transmute(s)
22+
}
23+
24+
#[inline]
25+
pub fn is_sep_byte(b: u8) -> bool {
26+
b == b'/' || b == b'\\'
27+
}
28+
29+
#[inline]
30+
pub fn is_verbatim_sep(b: u8) -> bool {
31+
b == b'\\'
32+
}
33+
34+
pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
35+
use path::Prefix::*;
36+
unsafe {
37+
// The unsafety here stems from converting between &OsStr and &[u8]
38+
// and back. This is safe to do because (1) we only look at ASCII
39+
// contents of the encoding and (2) new &OsStr values are produced
40+
// only from ASCII-bounded slices of existing &OsStr values.
41+
let mut path = os_str_as_u8_slice(path);
42+
43+
if path.starts_with(br"\\") {
44+
// \\
45+
path = &path[2..];
46+
if path.starts_with(br"?\") {
47+
// \\?\
48+
path = &path[2..];
49+
if path.starts_with(br"UNC\") {
50+
// \\?\UNC\server\share
51+
path = &path[4..];
52+
let (server, share) = match parse_two_comps(path, is_verbatim_sep) {
53+
Some((server, share)) =>
54+
(u8_slice_as_os_str(server), u8_slice_as_os_str(share)),
55+
None => (u8_slice_as_os_str(path), u8_slice_as_os_str(&[])),
56+
};
57+
return Some(VerbatimUNC(server, share));
58+
} else {
59+
// \\?\path
60+
let idx = path.iter().position(|&b| b == b'\\');
61+
if idx == Some(2) && path[1] == b':' {
62+
let c = path[0];
63+
if c.is_ascii() && (c as char).is_alphabetic() {
64+
// \\?\C:\ path
65+
return Some(VerbatimDisk(c.to_ascii_uppercase()));
66+
}
67+
}
68+
let slice = &path[..idx.unwrap_or(path.len())];
69+
return Some(Verbatim(u8_slice_as_os_str(slice)));
70+
}
71+
} else if path.starts_with(b".\\") {
72+
// \\.\path
73+
path = &path[2..];
74+
let pos = path.iter().position(|&b| b == b'\\');
75+
let slice = &path[..pos.unwrap_or(path.len())];
76+
return Some(DeviceNS(u8_slice_as_os_str(slice)));
77+
}
78+
match parse_two_comps(path, is_sep_byte) {
79+
Some((server, share)) if !server.is_empty() && !share.is_empty() => {
80+
// \\server\share
81+
return Some(UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share)));
82+
}
83+
_ => (),
84+
}
85+
} else if path.get(1) == Some(& b':') {
86+
// C:
87+
let c = path[0];
88+
if c.is_ascii() && (c as char).is_alphabetic() {
89+
return Some(Disk(c.to_ascii_uppercase()));
90+
}
91+
}
92+
return None;
93+
}
94+
95+
fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> {
96+
let first = match path.iter().position(|x| f(*x)) {
97+
None => return None,
98+
Some(x) => &path[..x],
99+
};
100+
path = &path[(first.len() + 1)..];
101+
let idx = path.iter().position(|x| f(*x));
102+
let second = &path[..idx.unwrap_or(path.len())];
103+
Some((first, second))
104+
}
105+
}
106+
107+
pub const MAIN_SEP_STR: &'static str = "\\";
108+
pub const MAIN_SEP: char = '\\';

0 commit comments

Comments
 (0)