From a5a9c91cb6f18159e39c87143ece06a4ceb8d7df Mon Sep 17 00:00:00 2001 From: emma Date: Tue, 4 Jun 2024 14:28:19 -0600 Subject: [PATCH] getopt.rs(3): optind support --- src/getopt.rs | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/getopt.rs b/src/getopt.rs index b146400..79879df 100644 --- a/src/getopt.rs +++ b/src/getopt.rs @@ -18,6 +18,21 @@ use std::ffi::{ c_int, c_char, CString, CStr }; + +/* binding to getopt(3p) */ +extern "C" { + static mut optarg: *mut c_char; + static mut _opterr: c_int; + static mut optind: c_int; + static mut optopt: c_int; + + fn getopt( + ___argc: c_int, + ___argv: *const *mut c_char, + __shortopts: *const c_char, + ) -> c_int; +} + pub struct Opt { pub arg: Option, pub ind: i32, @@ -50,7 +65,7 @@ impl GetOpt for Vec { let opts = CString::new(optstring).unwrap().into_raw(); let len = self.len() as c_int; - unsafe { // TODO: enable optind modification + unsafe { match getopt(len, argv_ptr, opts) { /* From getopt(3p): * @@ -103,16 +118,24 @@ impl GetOpt for Vec { } } } -/* binding to getopt(3p) */ -extern "C" { - static mut optarg: *mut c_char; - static mut _opterr: c_int; - static mut optind: c_int; - static mut optopt: c_int; - fn getopt( - ___argc: c_int, - ___argv: *const *mut c_char, - __shortopts: *const c_char, - ) -> c_int; -} +/* From getopt(3p): + * + * The variable optind is the index of the next element of the argv[] + * vector to be processed. It shall be initialized to 1 by the system, and + * getopt() shall update it when it finishes with each element of argv[]. + * If the application sets optind to zero before calling getopt(), the + * behavior is unspecified. When an element of argv[] contains multiple + * option characters, it is unspecified how getopt() determines which + * options have already been processed. + * + * This API can be utilized using unsafe blocks and dereferencing: + * + * use getopt::OPTIND; + * + * unsafe { while *OPTIND < 5 { + * println!("{}", *OPTIND); // 1..4 + * *OPTIND += 1; + * }} + */ +pub static mut OPTIND: *mut i32 = unsafe { std::ptr::addr_of_mut!(optind) };