forked from bonsai/harakit
		
	getopt.rs(3): fixed pointer shenanigans
This commit is contained in:
		
							parent
							
								
									88b0d55440
								
							
						
					
					
						commit
						bb2c63bfaf
					
				@ -16,7 +16,7 @@
 | 
			
		||||
 * along with this program. If not, see https://www.gnu.org/licenses/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
use std::ffi::{ c_int, c_char, CString };
 | 
			
		||||
use std::ffi::{ c_int, c_char, CString, CStr };
 | 
			
		||||
 | 
			
		||||
pub struct Opt {
 | 
			
		||||
	pub arg: Option<String>,
 | 
			
		||||
@ -35,20 +35,22 @@ pub trait GetOpt {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl GetOpt for Vec<String> {
 | 
			
		||||
	fn getopt(&self, optstring: &str) -> Option<Result<Opt, OptError>> {
 | 
			
		||||
		let argv = self
 | 
			
		||||
    fn getopt(&self, optstring: &str) -> Option<Result<Opt, OptError>> {
 | 
			
		||||
        let c_strings: Vec<_> = self
 | 
			
		||||
			.iter()
 | 
			
		||||
			.cloned()
 | 
			
		||||
			.map(CString::new)
 | 
			
		||||
			.map(Result::unwrap)
 | 
			
		||||
			.map(|x| x.as_ptr() as c_char)
 | 
			
		||||
			.collect::<Vec<c_char>>()
 | 
			
		||||
			.as_ptr() as *const *mut c_char;
 | 
			
		||||
		let opts = CString::new(optstring).unwrap().into_raw();
 | 
			
		||||
		let len = self.len() as c_int;
 | 
			
		||||
			.collect();
 | 
			
		||||
 | 
			
		||||
		unsafe {
 | 
			
		||||
			let a = match getopt(len, argv, opts) {
 | 
			
		||||
        let argv: Vec<_> = c_strings.iter().map(|x| x.as_ptr()).collect();
 | 
			
		||||
        let argv_ptr = argv.as_ptr() as *const *mut c_char;
 | 
			
		||||
        let optstring_c = CString::new(optstring).unwrap();
 | 
			
		||||
        let opts = optstring_c.into_raw();
 | 
			
		||||
        let len = self.len() as c_int;
 | 
			
		||||
 | 
			
		||||
        unsafe {
 | 
			
		||||
            let a = match getopt(len, argv_ptr, opts) {
 | 
			
		||||
				/* From getopt(3p):
 | 
			
		||||
				 *
 | 
			
		||||
				 * The getopt() function shall return the next option character
 | 
			
		||||
@ -65,11 +67,11 @@ impl GetOpt for Vec<String> {
 | 
			
		||||
				 *
 | 
			
		||||
				 * Otherwise, getopt() shall return -1 when all command line
 | 
			
		||||
				 * options are parsed. */
 | 
			
		||||
				58 => { // ASCII value for ':'
 | 
			
		||||
                58 => { /* ASCII value for ':' */
 | 
			
		||||
					return Some(Err(OptError::MissingArg));
 | 
			
		||||
				},
 | 
			
		||||
				63 => { // ASCII value for '?'
 | 
			
		||||
					return Some(Err(OptError::UnknownOpt));
 | 
			
		||||
                63 => { /* ASCII value for '?' */
 | 
			
		||||
					return Some(Err(OptError::UnknownOpt))
 | 
			
		||||
				},
 | 
			
		||||
				/* From getopt(3p):
 | 
			
		||||
				 *
 | 
			
		||||
@ -84,18 +86,17 @@ impl GetOpt for Vec<String> {
 | 
			
		||||
				 * argv[optind]   points to the string "--"
 | 
			
		||||
				 *
 | 
			
		||||
				 * getopt() shall return -1 after incrementing optind. */
 | 
			
		||||
				-1 => return None,
 | 
			
		||||
				a => a.to_string(),
 | 
			
		||||
			};
 | 
			
		||||
                -1 => return None,
 | 
			
		||||
                _ => CStr::from_ptr(optarg).to_string_lossy().into_owned(),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
			Some(Ok(Opt { arg: Some(a), ind: optind, opt: optopt }))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
            Some(Ok(Opt { arg: Some(a), ind: optind, opt: optopt }))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* binding to getopt(3p) */
 | 
			
		||||
extern "C" {
 | 
			
		||||
	static mut _optarg: *mut c_char;
 | 
			
		||||
	static mut optarg: *mut c_char;
 | 
			
		||||
	static mut _opterr: c_int;
 | 
			
		||||
	static mut optind: c_int;
 | 
			
		||||
	static mut optopt: c_int;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user