#[cfg(windows)]
extern crate glob;
#[cfg(any(test,windows))]
mod parser;
#[cfg(windows)]
mod argsiter;
#[cfg(windows)]
pub use argsiter::*;
#[cfg(any(test,windows))]
mod globiter;
#[cfg(any(test,windows))]
pub use globiter::*;
#[cfg(not(windows))]
pub type Args = std::env::Args;
#[cfg(not(windows))]
pub fn args() -> Args {
std::env::args()
}
#[cfg(windows)]
pub fn args() -> Args {
Args {
args: globs(),
current_arg_globs: None,
}
}
#[cfg(windows)]
#[inline]
pub fn globs() -> Option<GlobArgs<'static>> {
raw_command_line().map(|cmd| GlobArgs::new(cmd))
}
#[cfg(windows)]
extern "C" {
fn GetCommandLineW() -> *const u16;
}
#[cfg(windows)]
fn raw_command_line() -> Option<&'static [u16]> {
unsafe {
let line_ptr = GetCommandLineW();
if line_ptr.is_null() {
return None;
}
let mut len = 0;
while *line_ptr.offset(len as isize) != 0 {
len += 1;
}
Some(std::slice::from_raw_parts(line_ptr, len))
}
}
#[cfg(test)]
fn parsed(s: &str) -> String {
let t: Vec<_> = s.encode_utf16().collect();
let args: Vec<_> = GlobArgs::new(&t)
.map(|s| s.to_string_lossy().to_string())
.collect();
args.join(";")
}
#[test]
#[cfg(windows)]
fn test_actual_args() {
assert!(globs().expect("args found").count() >= 1);
}
#[test]
fn test_parse_1() {
assert_eq!(r#"漢字"#, parsed("漢字"));
assert_eq!(r#"漢字"#, parsed("\"漢字\""));
assert_eq!(r#"漢\字"#, parsed("\"漢\\字\""));
assert_eq!(r#"unquoted"#, parsed("unquoted"));
assert_eq!(r#"*"#, parsed("*"));
assert_eq!(r#"?"#, parsed("?"));
assert_eq!(r#"quoted"#, parsed("\"quoted\""));
assert_eq!(r#"[*]"#, parsed("\"*\""));
assert_eq!(r#"[?]"#, parsed("\"?\""));
assert_eq!(r#"[]]"#, parsed("\"]\""));
assert_eq!(r#"quo"ted"#, parsed(r#" "quo\"ted" "#)); assert_eq!(r#"quo"ted? "#, parsed(r#" "quo""ted?" "#)); assert_eq!(r#"unquo"ted"#, parsed(r#" unquo\"ted "#)); assert_eq!(r#"unquoted?"#, parsed(r#" unquo""ted? "#)); assert_eq!(r#"""#, parsed(r#""""""#)); assert_eq!(r#"""#, parsed(r#"""""""#));
assert_eq!(r#""""#, parsed(r#""""""""#));
assert_eq!(r#""""#, parsed(r#"""""""""#)); assert_eq!(r#""""#, parsed(r#""""""""""#));
assert_eq!(r#"""""#, parsed(r#"""""""""""#));
assert_eq!(r#"\\server\share\path with spaces"#, parsed(r#""\\server\share\path with spaces""#)); assert_eq!("aba", parsed(r#""a"b"a""#)); assert_eq!("abac", parsed(r#""a"b"a"c"#)); assert_eq!("c*a[*]b*a[*]c*", parsed(r#"c*"a*"b*"a*"c*"#)); assert_eq!(r#"\\"#, parsed(r#"\\\\""#));
assert_eq!(r#"?\\?"#, parsed(r#"?\\\\"?"#)); assert_eq!(r#"\""#, parsed(r#"\\\""#));
assert_eq!(r#"\"[a-z]"#, parsed(r#"\\\"[a-z]"#));
assert_eq!(" ", parsed(r#"" "#)); assert_eq!("", parsed(r#""""#));
assert_eq!(r#"[a-c][d-z]"#, parsed(r#"[a-c]""[d-z]"#));
assert_eq!(r#"[[]a-c[]]"[d-z]"#, parsed(r#""[a-c]""[d-z]""#));
assert_eq!("", parsed(r#"""#));
assert_eq!("x", parsed(r#"x""#));
assert_eq!(r#"\"#, parsed(r"\"));
assert_eq!(r#"\\"#, parsed(r"\\"));
assert_eq!(r#"\\\"#, parsed(r"\\\"));
assert_eq!(r#"\\\\"#, parsed(r"\\\\"));
assert_eq!(r#"\\a"#, parsed(r#"\\\\"a"#));
assert_eq!(r#"\\a"#, parsed(r#"\\\\"a""#));
assert_eq!(r#"¥¥"#, parsed(r#"¥¥""#)); }
#[test]
fn test_parse_multi() {
assert_eq!(r#"unquoted;quoted"#, parsed("unquoted \"quoted\""));
assert_eq!(r#"quo"ted;quo"ted "#, parsed(r#" "quo\"ted" "quo""ted" "#));
assert_eq!(r#"unquo"ted;""#, parsed(r#" unquo\"ted """"""#));
assert_eq!(r#"a;a"#, parsed(r#"a"" a"#));
assert_eq!(r#"a";a"#, parsed(r#"a""" a"#));
assert_eq!(r#"\\;\""#, parsed(r#"\\\\" \\\" "#));
assert_eq!("x; ", parsed(r#" x " "#));
}