use assert_matches::assert_matches;
use bash_builtins::{BuiltinOptions, Error};
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
#[cfg(unix)]
#[test]
fn parse_options() {
#[derive(BuiltinOptions, Debug)]
enum Opt<'a> {
#[opt = 'a']
A,
#[opt = 'b']
B(i64),
#[opt = 'c']
C(&'a str),
#[opt = 'd']
D(&'a std::path::Path),
#[opt = 'e']
E(String),
#[opt = 'f']
F(Option<&'a str>),
#[opt = 'g']
G(std::path::PathBuf),
}
assert_eq!(Opt::options(), b"ab:c:d:e:f;g:\0");
assert_matches!(
Opt::from_option(
b'c' as _,
Some(CStr::from_bytes_with_nul(b"0123\0").unwrap())
),
Ok(Opt::C("0123"))
);
assert_eq!(SH_NEEDARG_CALLS.swap(0, SeqCst), 0);
assert_eq!(BUILTIN_USAGE_CALLS.swap(0, SeqCst), 0);
assert_matches!(Opt::from_option(b'z' as _, None), Err(Error::Usage));
assert_eq!(SH_NEEDARG_CALLS.swap(0, SeqCst), 0);
assert_eq!(BUILTIN_USAGE_CALLS.swap(0, SeqCst), 1);
assert_matches!(Opt::from_option(b'e' as _, None), Err(Error::Usage));
assert_eq!(SH_NEEDARG_CALLS.swap(0, SeqCst), 1);
assert_eq!(BUILTIN_USAGE_CALLS.swap(0, SeqCst), 0);
assert_matches!(Opt::from_option(b'f' as _, None), Ok(Opt::F(None)));
assert_eq!(SH_NEEDARG_CALLS.swap(0, SeqCst), 0);
assert_eq!(BUILTIN_USAGE_CALLS.swap(0, SeqCst), 0);
assert_matches!(
Opt::from_option(
b'f' as _,
Some(CStr::from_bytes_with_nul(b"abc\0").unwrap())
),
Ok(Opt::F(Some("abc")))
);
assert_eq!(SH_NEEDARG_CALLS.swap(0, SeqCst), 0);
assert_eq!(BUILTIN_USAGE_CALLS.swap(0, SeqCst), 0);
}
static SH_NEEDARG_CALLS: AtomicUsize = AtomicUsize::new(0);
static BUILTIN_USAGE_CALLS: AtomicUsize = AtomicUsize::new(0);
#[no_mangle]
extern "C" fn builtin_error(_: *const c_char) {}
#[no_mangle]
extern "C" fn builtin_warning(_: *const c_char) {}
#[no_mangle]
extern "C" fn builtin_usage() {
BUILTIN_USAGE_CALLS.fetch_add(1, SeqCst);
}
#[no_mangle]
extern "C" fn builtin_help() {}
#[no_mangle]
extern "C" fn sh_needarg(_: *const c_char) {
SH_NEEDARG_CALLS.fetch_add(1, SeqCst);
}
#[no_mangle]
static mut list_opttype: c_int = 0;
#[no_mangle]
static mut list_optopt: c_int = 0;