From e4e823a3092822358de0fbafaefe49924391ed82 Mon Sep 17 00:00:00 2001 From: emma Date: Sat, 13 Jul 2024 18:03:49 -0600 Subject: [PATCH] fop(1): adds more comments --- src/fop.rs | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/fop.rs b/src/fop.rs index 91c8a72..061815e 100644 --- a/src/fop.rs +++ b/src/fop.rs @@ -32,8 +32,8 @@ use sysexits::{ EX_DATAERR, EX_IOERR, EX_UNAVAILABLE, EX_USAGE }; fn main() { let argv = args().collect::>(); - let mut d = '\u{1E}'.to_string(); - let mut index_arg = 0; + let mut d = '\u{1E}'.to_string(); /* ASCII record separator */ + let mut optind = 0; let usage = format!( "Usage: {} [-d delimiter] index command [args...]", @@ -43,10 +43,9 @@ fn main() { while let Some(opt) = argv.getopt("d:") { match opt.opt() { Ok(_) => { - /* unwrap because Err(OptError::MissingArg) will be returned if - * opt.arg() is None */ + /* delimiter */ d = opt.arg().unwrap(); - index_arg = opt.ind(); + optind = opt.ind(); }, Err(_) => { eprintln!("{}", usage); @@ -55,38 +54,46 @@ fn main() { }; } - let command_arg = index_arg as usize + 1; + /* index of the argv[0] for the operator command */ + let command_arg = optind as usize + 1; - argv.get(command_arg).unwrap_or_else(|| { + /* argv[0] of the operator command */ + let operator = argv.get(command_arg).unwrap_or_else(|| { eprintln!("{}", usage); exit(EX_USAGE); }); - let index = argv[index_arg].parse::().unwrap_or_else(|e| { + /* parse the specified index as a number we can use */ + let index = argv[optind].parse::().unwrap_or_else(|e| { eprintln!("{}: {}: {}", argv[0], argv[1], e); exit(EX_DATAERR); }); let mut buf = String::new(); let _ = stdin().read_to_string(&mut buf); + + /* split the buffer by the delimiter (by default, '\u{1E}') */ let mut fields = buf.split(&d).collect::>(); + /* collect arguments for the operator command */ let opts = argv .iter() .clone() - .skip(command_arg + 1) + .skip(command_arg + 1) /* skip the command name */ .collect::>(); - let mut spawned = Command::new(argv.get(command_arg).unwrap()) - .args(opts) + /* spawn the command to operate on the field */ + let mut spawned = Command::new(operator) + .args(opts) /* spawn with the specified arguments */ .stdin(Stdio::piped()) - .stdout(Stdio::piped()) + .stdout(Stdio::piped()) /* piped stdout to handle output ourselves */ .spawn() .unwrap_or_else( |e| { eprintln!("{}: {}: {}", argv[0], argv[command_arg], e.strerror()); exit(EX_UNAVAILABLE); }); + /* get field we want to pipe into spawned program */ let field = fields.get(index).unwrap_or_else(|| { eprintln!( "{}: {}: No such index in input", @@ -96,9 +103,10 @@ fn main() { exit(EX_DATAERR); }); + /* get the stdin of the newly spawned program and feed it the field val */ if let Some(mut child_stdin) = spawned.stdin.take() { let _ = child_stdin.write_all(field.as_bytes()); - drop(child_stdin); + drop(child_stdin); /* stay safe! drop your children! */ } let output = spawned.wait_with_output().unwrap_or_else(|e| { @@ -106,17 +114,22 @@ fn main() { exit(EX_IOERR); }); + /* get the output with which the original field will be replaced */ let mut replace = output.stdout.clone(); + /* as long as it’s not a newline, set the replacement to the output */ if replace.pop() != Some(b'\n') { replace = output.stdout; } + /* convert the output of the program to UTF-8 */ let new_field = String::from_utf8(replace).unwrap_or_else(|e| { eprintln!("{}: {}: {}", argv[0], argv[command_arg], e); exit(EX_IOERR); }); + /* store the new field in the old fields vector */ fields[index] = &new_field; + /* fop it */ stdout().write_all( fields.join(&d.to_string()).as_bytes() ).unwrap_or_else(|e| {