mm(1): treats trailing arguments as optargs for the last opt

This commit is contained in:
dtb 2024-07-14 18:34:08 -06:00 committed by emma
parent 20692d581a
commit 8dc763f05e
Signed by untrusted user: emma
GPG Key ID: 06FA419A1698C270

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media> * Copyright (c) 2024 Emma Tebibyte <emma@tebibyte.media>
* Copyright (c) 2024 DTB <trinity@trinity.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
* *
* This program is free software: you can redistribute it and/or modify it under * This program is free software: you can redistribute it and/or modify it under
@ -32,6 +33,8 @@ use getopt::GetOpt;
use strerror::StrError; use strerror::StrError;
use sysexits::{ EX_IOERR, EX_USAGE }; use sysexits::{ EX_IOERR, EX_USAGE };
enum ArgMode{ In, Out }
fn main() -> ExitCode { fn main() -> ExitCode {
let argv = args().collect::<Vec<_>>(); let argv = args().collect::<Vec<_>>();
let usage = format!("Usage: {} [-aetu] [-i input] [-o output]", argv[0]); let usage = format!("Usage: {} [-aetu] [-i input] [-o output]", argv[0]);
@ -42,6 +45,8 @@ fn main() -> ExitCode {
let mut u = false; /* unbuffer i/o */ let mut u = false; /* unbuffer i/o */
let mut ins = Vec::new(); /* initial input file path vector */ let mut ins = Vec::new(); /* initial input file path vector */
let mut outs = Vec::new(); /* initial output file path vector */ let mut outs = Vec::new(); /* initial output file path vector */
let mut mode: Option<ArgMode> = None; /* mode for positional arguments */
let mut optind = 0;
while let Some(opt) = argv.getopt("aei:o:tu") { while let Some(opt) = argv.getopt("aei:o:tu") {
match opt.opt() { match opt.opt() {
@ -49,19 +54,33 @@ fn main() -> ExitCode {
Ok("e") => e = true, Ok("e") => e = true,
Ok("u") => u = true, Ok("u") => u = true,
Ok("t") => t = false, Ok("t") => t = false,
Ok("i") => { /* add input */ Ok("i") => { /* add inputs */
let input = opt.arg().unwrap(); let input = opt.arg().unwrap();
ins.push(input); ins.push(input);
mode = Some(ArgMode::In);
}, },
Ok("o") => { /* add output */ Ok("o") => { /* add output */
let output = opt.arg().unwrap(); let output = opt.arg().unwrap();
outs.push(output); outs.push(output);
mode = Some(ArgMode::Out);
}, },
Err(_) | Ok(_) => { Err(_) | Ok(_) => {
eprintln!("{}", usage); eprintln!("{}", usage);
return ExitCode::from(EX_USAGE as u8); return ExitCode::from(EX_USAGE as u8);
}, },
}; };
optind = opt.ind();
}
let remaining = argv.iter().skip(optind);
if let Some(m) = mode {
for arg in remaining {
match m {
ArgMode::In => ins.push(arg.to_string()),
ArgMode::Out => outs.push(arg.to_string()),
};
}
} }
/* use stdin if no inputs are specified */ /* use stdin if no inputs are specified */