From 7eda8bb721bab2ec4c00517a2eadd07f0a5ddac8 Mon Sep 17 00:00:00 2001 From: emma Date: Wed, 27 Dec 2023 15:44:19 -0700 Subject: [PATCH] fop(1): working prototype --- GNUmakefile | 3 +++ src/fop.rs | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/fop.rs diff --git a/GNUmakefile b/GNUmakefile index ca38f5c..35da1d9 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -60,6 +60,9 @@ test: build false: src/false.rs build_dir $(RUSTC) $(RUSTCFLAGS) -o build/bin/false src/false.rs +fop: src/fop.rs build_dir + $(RUSTC) $(RUSTCFLAGS) -o build/bin/fop src/fop.rs + intcmp: src/intcmp.c build_dir $(CC) $(CFLAGS) -o build/bin/intcmp src/intcmp.c diff --git a/src/fop.rs b/src/fop.rs new file mode 100644 index 0000000..9c25463 --- /dev/null +++ b/src/fop.rs @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Emma Tebibyte + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +use std::{ + env::args, + io::{ Read, stdin, Write }, + process::{ Command, exit, Stdio }, +}; + +fn main() { + let argv = args().collect::>(); + + let index = match argv.get(1) { + Some(i) => { + i.parse::().unwrap_or_else(|_| { + eprintln!("{}: {}: Not an integer.", argv[0], i); + exit(1); + }) + }, + None => { + eprintln!("Usage: {} index command args...", argv[0]); + exit(1); + }, + }; + + let mut buf = String::new(); + stdin().read_to_string(&mut buf).unwrap(); + let mut fields = buf.split('␞').collect::>(); + + argv.get(2).unwrap_or_else(|| { + eprintln!("Usage: {} index command args...", argv[0]); + exit(1); + }); + + let opts = argv.iter().clone().skip(3).collect::>(); + + let mut spawned = Command::new(argv.get(2).unwrap()) + .args(opts) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + let field = fields.get(index).unwrap_or_else(|| { + eprintln!("{}: {}: No such index in input.", argv[0], index.to_string()); + exit(1); + }); + + if let Some(mut child_stdin) = spawned.stdin.take() { + child_stdin.write_all(field.as_bytes()).unwrap(); + drop(child_stdin); + } + + let output = spawned.wait_with_output().unwrap(); + + let new_field = String::from_utf8(output.stdout).unwrap(); + + fields[index] = &new_field; + + print!("{}", fields.join("␞")); +}