diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 4403280efc11b..cb6f88f1cd907 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -18,8 +18,8 @@ use crate::ffi::{OsStr, OsString}; use crate::fmt; use crate::io; use crate::path::{Path, PathBuf}; -use crate::sys; use crate::sys::os as os_imp; +use crate::sys_common; /// Returns the current working directory as a [`PathBuf`]. /// @@ -705,7 +705,7 @@ pub struct Args { /// [`env::args_os()`]: args_os #[stable(feature = "env", since = "1.0.0")] pub struct ArgsOs { - inner: sys::args::Args, + inner: sys_common::args::Args, } /// Returns the arguments that this program was started with (normally passed @@ -777,7 +777,7 @@ pub fn args() -> Args { /// ``` #[stable(feature = "env", since = "1.0.0")] pub fn args_os() -> ArgsOs { - ArgsOs { inner: sys::args::args() } + ArgsOs { inner: sys_common::args::Args::get() } } #[stable(feature = "env_unimpl_send_sync", since = "1.26.0")] diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index 1c7e1dd8d5778..524e3465cd333 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,94 +1,39 @@ -use crate::ffi::OsString; -use crate::fmt; -use crate::vec; +use crate::ffi::{CStr, OsString}; +use crate::os::unix::ffi::OsStringExt; +use crate::ptr; +use crate::sys_common::mutex::StaticMutex; +use crate::vec::IntoIter; + +static mut ARGC: isize = 0; +static mut ARGV: *const *const u8 = ptr::null(); +static LOCK: StaticMutex = StaticMutex::new(); /// One-time global initialization. pub unsafe fn init(argc: isize, argv: *const *const u8) { - imp::init(argc, argv) + let _guard = LOCK.lock(); + ARGC = argc; + ARGV = argv; } /// One-time global cleanup. pub unsafe fn cleanup() { - imp::cleanup() + let _guard = LOCK.lock(); + ARGC = 0; + ARGV = ptr::null(); } /// Returns the command line arguments pub fn args() -> Args { - imp::args() -} - -pub struct Args { - iter: vec::IntoIter, -} - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.iter.as_slice().fmt(f) - } -} - -impl !Send for Args {} -impl !Sync for Args {} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.iter.len() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} - -mod imp { - use super::Args; - use crate::ffi::{CStr, OsString}; - use crate::os::unix::ffi::OsStringExt; - use crate::ptr; - - use crate::sys_common::mutex::StaticMutex; - - static mut ARGC: isize = 0; - static mut ARGV: *const *const u8 = ptr::null(); - static LOCK: StaticMutex = StaticMutex::new(); - - pub unsafe fn init(argc: isize, argv: *const *const u8) { + unsafe { let _guard = LOCK.lock(); - ARGC = argc; - ARGV = argv; - } - - pub unsafe fn cleanup() { - let _guard = LOCK.lock(); - ARGC = 0; - ARGV = ptr::null(); - } - - pub fn args() -> Args { - Args { iter: clone().into_iter() } - } - - fn clone() -> Vec { - unsafe { - let _guard = LOCK.lock(); - (0..ARGC) - .map(|i| { - let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8); - OsStringExt::from_vec(cstr.to_bytes().to_vec()) - }) - .collect() - } + (0..ARGC) + .map(|i| { + let cstr = CStr::from_ptr(*ARGV.offset(i) as *const i8); + OsStringExt::from_vec(cstr.to_bytes().to_vec()) + }) + .collect::>() + .into_iter() } } + +pub type Args = IntoIter; diff --git a/library/std/src/sys/sgx/args.rs b/library/std/src/sys/sgx/args.rs index ef4176c4ac0f0..0e90088cf0e43 100644 --- a/library/std/src/sys/sgx/args.rs +++ b/library/std/src/sys/sgx/args.rs @@ -1,10 +1,9 @@ use super::abi::usercalls::{alloc, raw::ByteBuffer}; use crate::ffi::OsString; -use crate::fmt; -use crate::slice; use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::os_str::Buf; use crate::sys_common::FromInner; +use crate::vec::IntoIter; #[cfg_attr(test, linkage = "available_externally")] #[export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE"] @@ -25,35 +24,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) { pub fn args() -> Args { let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() }; - if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) } + if let Some(args) = args { args.clone().into_iter() } else { Vec::new().into_iter() } } -pub struct Args(slice::Iter<'static, OsString>); - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.as_slice().fmt(f) - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - self.0.next().cloned() - } - fn size_hint(&self) -> (usize, Option) { - self.0.size_hint() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.0.len() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - self.0.next_back().cloned() - } -} +pub type Args = IntoIter; diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index fc423e393d4a4..ed0cfa46781fc 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -6,8 +6,7 @@ #![allow(dead_code)] // runtime init functions not used during testing use crate::ffi::OsString; -use crate::fmt; -use crate::vec; +use crate::vec::IntoIter; /// One-time global initialization. pub unsafe fn init(argc: isize, argv: *const *const u8) { @@ -24,40 +23,7 @@ pub fn args() -> Args { imp::args() } -pub struct Args { - iter: vec::IntoIter, -} - -impl !Send for Args {} -impl !Sync for Args {} - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.iter.as_slice().fmt(f) - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.iter.len() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} +pub type Args = IntoIter; #[cfg(any( target_os = "linux", @@ -134,7 +100,7 @@ mod imp { } pub fn args() -> Args { - Args { iter: clone().into_iter() } + clone().into_iter() } fn clone() -> Vec { @@ -180,7 +146,7 @@ mod imp { }) .collect::>() }; - Args { iter: vec.into_iter() } + vec.into_iter() } // As _NSGetArgc and _NSGetArgv aren't mentioned in iOS docs @@ -247,6 +213,6 @@ mod imp { } } - Args { iter: res.into_iter() } + res.into_iter() } } diff --git a/library/std/src/sys/unsupported/args.rs b/library/std/src/sys/unsupported/args.rs index a2d75a6197633..a6504845fc97e 100644 --- a/library/std/src/sys/unsupported/args.rs +++ b/library/std/src/sys/unsupported/args.rs @@ -1,36 +1,8 @@ use crate::ffi::OsString; -use crate::fmt; +use crate::vec::IntoIter; -pub struct Args {} +pub type Args = IntoIter; pub fn args() -> Args { - Args {} -} - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_list().finish() - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - None - } - fn size_hint(&self) -> (usize, Option) { - (0, Some(0)) - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - 0 - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - None - } + Vec::new().into_iter() } diff --git a/library/std/src/sys/wasi/args.rs b/library/std/src/sys/wasi/args.rs index c42c310e3a254..e2cc858613575 100644 --- a/library/std/src/sys/wasi/args.rs +++ b/library/std/src/sys/wasi/args.rs @@ -1,20 +1,14 @@ #![deny(unsafe_op_in_unsafe_fn)] use crate::ffi::{CStr, OsStr, OsString}; -use crate::fmt; use crate::os::wasi::ffi::OsStrExt; -use crate::vec; +use crate::vec::IntoIter; -pub struct Args { - iter: vec::IntoIter, -} - -impl !Send for Args {} -impl !Sync for Args {} +pub type Args = IntoIter; /// Returns the command line arguments pub fn args() -> Args { - Args { iter: maybe_args().unwrap_or(Vec::new()).into_iter() } + maybe_args().unwrap_or(Vec::new()).into_iter() } fn maybe_args() -> Option> { @@ -32,31 +26,3 @@ fn maybe_args() -> Option> { Some(ret) } } - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.iter.as_slice().fmt(f) - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - self.iter.next() - } - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.iter.len() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - self.iter.next_back() - } -} diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index f1264130faf7a..9d54bf659c66e 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -4,13 +4,12 @@ mod tests; use crate::ffi::OsString; -use crate::fmt; use crate::os::windows::prelude::*; use crate::path::PathBuf; use crate::slice; use crate::sys::c; use crate::sys::windows::os::current_exe; -use crate::vec; +use crate::vec::IntoIter; use core::iter; @@ -21,7 +20,7 @@ pub fn args() -> Args { current_exe().map(PathBuf::into_os_string).unwrap_or_else(|_| OsString::new()) }); - Args { parsed_args_list: parsed_args_list.into_iter() } + parsed_args_list.into_iter() } } @@ -156,34 +155,4 @@ unsafe fn parse_lp_cmd_line OsString>( ret_val } -pub struct Args { - parsed_args_list: vec::IntoIter, -} - -impl fmt::Debug for Args { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.parsed_args_list.as_slice().fmt(f) - } -} - -impl Iterator for Args { - type Item = OsString; - fn next(&mut self) -> Option { - self.parsed_args_list.next() - } - fn size_hint(&self) -> (usize, Option) { - self.parsed_args_list.size_hint() - } -} - -impl DoubleEndedIterator for Args { - fn next_back(&mut self) -> Option { - self.parsed_args_list.next_back() - } -} - -impl ExactSizeIterator for Args { - fn len(&self) -> usize { - self.parsed_args_list.len() - } -} +pub type Args = IntoIter; diff --git a/library/std/src/sys_common/args.rs b/library/std/src/sys_common/args.rs new file mode 100644 index 0000000000000..a4c19983981ef --- /dev/null +++ b/library/std/src/sys_common/args.rs @@ -0,0 +1,50 @@ +use crate::convert::AsRef; +use crate::ffi::OsString; +use crate::fmt; +use crate::sys::args as sys; + +pub struct Args(sys::Args); + +impl !Send for Args {} +impl !Sync for Args {} + +impl Args { + pub fn get() -> Args { + Args(sys::args()) + } +} + +impl fmt::Debug for Args { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let args = &AsRef::<[OsString]>::as_ref(self); + args.fmt(f) + } +} + +impl AsRef<[OsString]> for Args { + fn as_ref(&self) -> &[OsString] { + self.0.as_ref() + } +} + +impl Iterator for Args { + type Item = OsString; + fn next(&mut self) -> Option { + self.0.next() + } + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl ExactSizeIterator for Args { + fn len(&self) -> usize { + self.0.len() + } +} + +impl DoubleEndedIterator for Args { + fn next_back(&mut self) -> Option { + self.0.next_back() + } +} diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 1a9caa22c9243..a37d9aae1b6a0 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -20,6 +20,7 @@ #[cfg(test)] mod tests; +pub mod args; pub mod backtrace; pub mod bytestring; pub mod condvar;