diff --git a/src/unistd/src/getopt.rs b/src/unistd/src/getopt.rs index 40560fae2b04fc014f78d0fb3cb8a15f039a183f..0f8e538f20e34798ceb0ae56d066d121ae9aa2fa 100644 --- a/src/unistd/src/getopt.rs +++ b/src/unistd/src/getopt.rs @@ -6,19 +6,23 @@ use super::stdio; use super::string; use core::ptr; +#[allow(non_upper_case_globals)] #[no_mangle] pub static mut optarg: *mut c_char = ptr::null_mut(); +#[allow(non_upper_case_globals)] #[no_mangle] pub static mut optind: c_int = 1; +#[allow(non_upper_case_globals)] #[no_mangle] pub static mut opterr: c_int = 1; +#[allow(non_upper_case_globals)] #[no_mangle] pub static mut optopt: c_int = -1; -static mut current_opt: *mut c_char = ptr::null_mut(); +static mut CURRENT_OPT: *mut c_char = ptr::null_mut(); #[no_mangle] pub unsafe extern "C" fn getopt( @@ -26,24 +30,27 @@ pub unsafe extern "C" fn getopt( argv: *const *mut c_char, optstring: *const c_char, ) -> c_int { - if current_opt == ptr::null_mut() || *current_opt == 0 { - let current_arg = *argv.offset(optind as isize); - // XXX: is argc check needed? - if optind > argc || current_arg == ptr::null_mut() || *current_arg != b'-' as c_char - || string::strcmp(current_arg, b"-\0".as_ptr() as _) == 0 - { - -1 - } else if string::strcmp(current_arg, b"--\0".as_ptr() as _) == 0 { - optind += 1; + if CURRENT_OPT == ptr::null_mut() || *CURRENT_OPT == 0 { + if optind >= argc { -1 } else { - // remove the '-' - let current_arg = current_arg.offset(1); + let current_arg = *argv.offset(optind as isize); + if current_arg == ptr::null_mut() || *current_arg != b'-' as c_char + || string::strcmp(current_arg, b"-\0".as_ptr() as _) == 0 + { + -1 + } else if string::strcmp(current_arg, b"--\0".as_ptr() as _) == 0 { + optind += 1; + -1 + } else { + // remove the '-' + let current_arg = current_arg.offset(1); - parse_arg(argc, argv, current_arg, optstring) + parse_arg(argc, argv, current_arg, optstring) + } } } else { - parse_arg(argc, argv, current_opt, optstring) + parse_arg(argc, argv, CURRENT_OPT, optstring) } } @@ -54,8 +61,8 @@ unsafe fn parse_arg( optstring: *const c_char, ) -> c_int { let update_current_opt = || { - current_opt = current_arg.offset(1); - if *current_opt == 0 { + CURRENT_OPT = current_arg.offset(1); + if *CURRENT_OPT == 0 { optind += 1; } }; @@ -75,11 +82,11 @@ unsafe fn parse_arg( *current_arg as c_int } Some(GetoptOption::OptArg) => { - current_opt = b"\0".as_ptr() as _; + CURRENT_OPT = b"\0".as_ptr() as _; if *current_arg.offset(1) == 0 { optind += 2; if optind > argc { - current_opt = ptr::null_mut(); + CURRENT_OPT = ptr::null_mut(); optopt = *current_arg as c_int; let errch = if *optstring == b':' as c_char { diff --git a/tests/expected/unistd/getopt.stdout b/tests/expected/unistd/getopt.stdout index c48147eb6f44e62c92864a7db327ea145eb489e5..aba2d44d3f96b0bbb82a1412c44b20ab8680d624 100644 --- a/tests/expected/unistd/getopt.stdout +++ b/tests/expected/unistd/getopt.stdout @@ -34,3 +34,9 @@ errflg: 0 ifile: ofile: arg result: 0 +bflg: 0 +aflg: 0 +errflg: 0 +ifile: +ofile: +result: 0 diff --git a/tests/unistd/getopt.c b/tests/unistd/getopt.c index f8e95ac95555b6aee839281c8d0f246a2a45d94b..b1eb262556ab9ab09f1377ce99fda9e9d5ee6246 100644 --- a/tests/unistd/getopt.c +++ b/tests/unistd/getopt.c @@ -11,7 +11,7 @@ printf("result: %d\n", runner(sizeof(args_arr) / sizeof(args_arr[0]), args_arr)); \ } -int runner(int argc, const char *argv[]) { +int runner(int argc, char *argv[]) { int c; int bflg = 0, aflg = 0, errflg = 0; char *ifile = ""; @@ -65,4 +65,5 @@ int main(int argc, const char *argv[]) { RUN("test", "-a", "-o", "arg", "--", "path", "path"); RUN("test", "-a", "-oarg", "path", "path"); RUN("test", "-aoarg", "path", "path"); + RUN("test"); }