diff options
Diffstat (limited to 'library/std/src/sys/windows/os.rs')
-rw-r--r-- | library/std/src/sys/windows/os.rs | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs index d7adeb266..58afca088 100644 --- a/library/std/src/sys/windows/os.rs +++ b/library/std/src/sys/windows/os.rs @@ -25,10 +25,6 @@ pub fn errno() -> i32 { /// Gets a detailed string description for the given error number. pub fn error_string(mut errnum: i32) -> String { - // This value is calculated from the macro - // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT) - let langId = 0x0800 as c::DWORD; - let mut buf = [0 as c::WCHAR; 2048]; unsafe { @@ -56,13 +52,13 @@ pub fn error_string(mut errnum: i32) -> String { flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS, module, errnum as c::DWORD, - langId, + 0, buf.as_mut_ptr(), buf.len() as c::DWORD, ptr::null(), ) as usize; if res == 0 { - // Sometimes FormatMessageW can fail e.g., system doesn't like langId, + // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, let fm_err = errno(); return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); } @@ -85,25 +81,69 @@ pub fn error_string(mut errnum: i32) -> String { pub struct Env { base: c::LPWCH, - cur: c::LPWCH, + iter: EnvIterator, +} + +// FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt. +pub struct EnvStrDebug<'a> { + iter: &'a EnvIterator, +} + +impl fmt::Debug for EnvStrDebug<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { iter } = self; + let iter: EnvIterator = (*iter).clone(); + let mut list = f.debug_list(); + for (a, b) in iter { + list.entry(&(a.to_str().unwrap(), b.to_str().unwrap())); + } + list.finish() + } +} + +impl Env { + pub fn str_debug(&self) -> impl fmt::Debug + '_ { + let Self { base: _, iter } = self; + EnvStrDebug { iter } + } +} + +impl fmt::Debug for Env { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { base: _, iter } = self; + f.debug_list().entries(iter.clone()).finish() + } } impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { + let Self { base: _, iter } = self; + iter.next() + } +} + +#[derive(Clone)] +struct EnvIterator(c::LPWCH); + +impl Iterator for EnvIterator { + type Item = (OsString, OsString); + + fn next(&mut self) -> Option<(OsString, OsString)> { + let Self(cur) = self; loop { unsafe { - if *self.cur == 0 { + if **cur == 0 { return None; } - let p = self.cur as *const u16; + let p = *cur as *const u16; let mut len = 0; while *p.add(len) != 0 { len += 1; } let s = slice::from_raw_parts(p, len); - self.cur = self.cur.add(len + 1); + *cur = cur.add(len + 1); // Windows allows environment variables to start with an equals // symbol (in any other position, this is the separator between @@ -137,7 +177,7 @@ pub fn env() -> Env { if ch.is_null() { panic!("failure getting env string from OS: {}", io::Error::last_os_error()); } - Env { base: ch, cur: ch } + Env { base: ch, iter: EnvIterator(ch) } } } |