Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions library/std/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ use crate::ops::{self, Deref};
use crate::rc::Rc;
use crate::str::FromStr;
use crate::sync::Arc;
use crate::sys::path::{HAS_PREFIXES, MAIN_SEP_STR, is_sep_byte, is_verbatim_sep, parse_prefix};
use crate::sys::path::{HAS_PREFIXES, is_sep_byte, is_verbatim_sep, parse_prefix};
use crate::{cmp, fmt, fs, io, sys};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -266,22 +266,33 @@ impl<'a> Prefix<'a> {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_separator(c: char) -> bool {
#[rustc_const_unstable(feature = "const_path_separators", issue = "153106")]
pub const fn is_separator(c: char) -> bool {
c.is_ascii() && is_sep_byte(c as u8)
}

/// The primary separator of path components for the current platform.
///
/// For example, `/` on Unix and `\` on Windows.
/// All path separators recognized on the current platform, represented as [`char`]s; for example,
/// this is `&['/'][..]` on Unix and `&['\\', '/'][..]` on Windows. The [primary
/// separator](MAIN_SEPARATOR) is always element 0 of the slice.
#[unstable(feature = "const_path_separators", issue = "153106")]
pub const SEPARATORS: &[char] = crate::sys::path::SEPARATORS;

/// All path separators recognized on the current platform, represented as [`&str`]s; for example,
/// this is `&["/"][..]` on Unix and `&["\\", "/"][..]` on Windows. The [primary
/// separator](MAIN_SEPARATOR_STR) is always element 0 of the slice.
#[unstable(feature = "const_path_separators", issue = "153106")]
pub const SEPARATORS_STR: &[&str] = crate::sys::path::SEPARATORS_STR;

/// The primary separator of path components for the current platform, represented as a [`char`];
/// for example, this is `'/'` on Unix and `'\\'` on Windows.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "path_main_separator")]
pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
pub const MAIN_SEPARATOR: char = SEPARATORS[0];

/// The primary separator of path components for the current platform.
///
/// For example, `/` on Unix and `\` on Windows.
/// The primary separator of path components for the current platform, represented as a [`&str`];
/// for example, this is `"/"` on Unix and `"\\"` on Windows.
#[stable(feature = "main_separator_str", since = "1.68.0")]
pub const MAIN_SEPARATOR_STR: &str = crate::sys::path::MAIN_SEP_STR;
pub const MAIN_SEPARATOR_STR: &str = SEPARATORS_STR[0];

////////////////////////////////////////////////////////////////////////////////
// Misc helpers
Expand Down Expand Up @@ -562,7 +573,7 @@ impl<'a> Component<'a> {
pub fn as_os_str(self) -> &'a OsStr {
match self {
Component::Prefix(p) => p.as_os_str(),
Component::RootDir => OsStr::new(MAIN_SEP_STR),
Component::RootDir => OsStr::new(MAIN_SEPARATOR_STR),
Component::CurDir => OsStr::new("."),
Component::ParentDir => OsStr::new(".."),
Component::Normal(path) => path,
Expand Down Expand Up @@ -1379,7 +1390,7 @@ impl PathBuf {

for c in buf {
if need_sep && c != Component::RootDir {
res.push(MAIN_SEP_STR);
res.push(MAIN_SEPARATOR_STR);
}
res.push(c.as_os_str());

Expand All @@ -1402,7 +1413,7 @@ impl PathBuf {

// `path` is a pure relative path
} else if need_sep {
self.inner.push(MAIN_SEP_STR);
self.inner.push(MAIN_SEPARATOR_STR);
}

self.inner.push(path);
Expand Down
11 changes: 3 additions & 8 deletions library/std/src/sys/path/cygwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,20 @@ use crate::sys::cvt;
use crate::sys::helpers::run_path_with_cstr;
use crate::{io, ptr};

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/' || b == b'\\'
}
path_separator_bytes!(b'/', b'\\');

/// Cygwin always prefers `/` over `\`, and it always converts all `/` to `\`
/// internally when calling Win32 APIs. Therefore, the server component of path
/// `\\?\UNC\localhost/share` is `localhost/share` on Win32, but `localhost`
/// on Cygwin.
#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'/' || b == b'\\'
pub const fn is_verbatim_sep(b: u8) -> bool {
is_sep_byte(b)
}

pub use super::windows_prefix::parse_prefix;

pub const HAS_PREFIXES: bool = true;
pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';

unsafe extern "C" {
// Doc: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
Expand Down
19 changes: 19 additions & 0 deletions library/std/src/sys/path/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
// There's a lot of necessary redundancy in separator definition. Consolidated into a macro to
// prevent transcription errors.
macro_rules! path_separator_bytes {
($($sep:literal),+) => (
pub const SEPARATORS: &[char] = &[$($sep as char,)+];
pub const SEPARATORS_STR: &[&str] = &[$(
match str::from_utf8(&[$sep]) {
Ok(s) => s,
Err(_) => panic!("path_separator_bytes must be ASCII bytes"),
}
),+];

#[inline]
pub const fn is_sep_byte(b: u8) -> bool {
$(b == $sep) ||+
}
)
}

cfg_select! {
target_os = "windows" => {
mod windows;
Expand Down
11 changes: 3 additions & 8 deletions library/std/src/sys/path/sgx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,18 @@ use crate::io;
use crate::path::{Path, PathBuf, Prefix};
use crate::sys::unsupported;

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/'
}
path_separator_bytes!(b'/');

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'/'
pub const fn is_verbatim_sep(b: u8) -> bool {
is_sep_byte(b)
}

pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
None
}

pub const HAS_PREFIXES: bool = false;
pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';

pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
unsupported()
Expand Down
13 changes: 4 additions & 9 deletions library/std/src/sys/path/uefi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,21 @@ use crate::path::{Path, PathBuf, Prefix};
use crate::sys::pal::helpers;
use crate::sys::unsupported_err;

path_separator_bytes!(b'\\');

const FORWARD_SLASH: u8 = b'/';
const COLON: u8 = b':';

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'\\'
}

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'\\'
pub const fn is_verbatim_sep(b: u8) -> bool {
is_sep_byte(b)
}

pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
None
}

pub const HAS_PREFIXES: bool = true;
pub const MAIN_SEP_STR: &str = "\\";
pub const MAIN_SEP: char = '\\';

/// UEFI paths can be of 4 types:
///
Expand Down
11 changes: 3 additions & 8 deletions library/std/src/sys/path/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ use crate::ffi::OsStr;
use crate::path::{Path, PathBuf, Prefix};
use crate::{env, io};

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/'
}
path_separator_bytes!(b'/');

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'/'
pub const fn is_verbatim_sep(b: u8) -> bool {
is_sep_byte(b)
}

#[inline]
Expand All @@ -18,8 +15,6 @@ pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
}

pub const HAS_PREFIXES: bool = false;
pub const MAIN_SEP_STR: &str = "/";
pub const MAIN_SEP: char = '/';

/// Make a POSIX path absolute without changing its semantics.
pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
Expand Down
11 changes: 3 additions & 8 deletions library/std/src/sys/path/unsupported_backslash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@ use crate::io;
use crate::path::{Path, PathBuf, Prefix};
use crate::sys::unsupported;

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'\\'
}
path_separator_bytes!(b'\\');

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'\\'
pub const fn is_verbatim_sep(b: u8) -> bool {
is_sep_byte(b)
}

pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
None
}

pub const HAS_PREFIXES: bool = true;
pub const MAIN_SEP_STR: &str = "\\";
pub const MAIN_SEP: char = '\\';

pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
unsupported()
Expand Down
11 changes: 3 additions & 8 deletions library/std/src/sys/path/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ mod tests;

pub use super::windows_prefix::parse_prefix;

path_separator_bytes!(b'\\', b'/');

pub const HAS_PREFIXES: bool = true;
pub const MAIN_SEP_STR: &str = "\\";
pub const MAIN_SEP: char = '\\';

/// A null terminated wide string.
#[repr(transparent)]
Expand Down Expand Up @@ -48,12 +48,7 @@ pub fn with_native_path<T>(path: &Path, f: &dyn Fn(&WCStr) -> io::Result<T>) ->
}

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/' || b == b'\\'
}

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
pub const fn is_verbatim_sep(b: u8) -> bool {
b == b'\\'
}

Expand Down
Loading