From 7d77b9720da95dc1a44e86ae50d1891fd63244fe Mon Sep 17 00:00:00 2001 From: Martin Kysel Date: Wed, 17 Aug 2016 20:41:34 +0100 Subject: [PATCH 1/4] Initial more implementation --- .gitignore | 1 + Cargo.toml | 2 + Makefile | 1 + src/more/Cargo.toml | 18 +++++++ src/more/main.rs | 5 ++ src/more/more.rs | 113 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 140 insertions(+) create mode 100644 src/more/Cargo.toml create mode 100644 src/more/main.rs create mode 100644 src/more/more.rs diff --git a/.gitignore b/.gitignore index c08be9d2b..07a32c65b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,6 @@ target/ *~ .*.swp .*.swo +.idea Cargo.lock lib*.a diff --git a/Cargo.toml b/Cargo.toml index 426f08b45..3ce10523b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ generic = [ "ls", "mkdir", "mktemp", + "more", "nl", "nproc", "od", @@ -144,6 +145,7 @@ mkdir = { optional=true, path="src/mkdir" } mkfifo = { optional=true, path="src/mkfifo" } mknod = { optional=true, path="src/mknod" } mktemp = { optional=true, path="src/mktemp" } +more = { optional=true, path="src/more" } mv = { optional=true, path="src/mv" } nice = { optional=true, path="src/nice" } nl = { optional=true, path="src/nl" } diff --git a/Makefile b/Makefile index 98c34f4b7..73004a18e 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ PROGS := \ ls \ mkdir \ mktemp \ + more \ nl \ nproc \ od \ diff --git a/src/more/Cargo.toml b/src/more/Cargo.toml new file mode 100644 index 000000000..88e88d39c --- /dev/null +++ b/src/more/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "more" +version = "0.0.1" +authors = [] + +[lib] +name = "uu_more" +path = "more.rs" + +[dependencies] +getopts = "*" +libc = "*" +nix = "*" +uucore = { path="../uucore" } + +[[bin]] +name = "more" +path = "main.rs" diff --git a/src/more/main.rs b/src/more/main.rs new file mode 100644 index 000000000..b67081dd0 --- /dev/null +++ b/src/more/main.rs @@ -0,0 +1,5 @@ +extern crate uu_more; + +fn main() { + std::process::exit(uu_more::uumain(std::env::args().collect())); +} diff --git a/src/more/more.rs b/src/more/more.rs new file mode 100644 index 000000000..bae650abd --- /dev/null +++ b/src/more/more.rs @@ -0,0 +1,113 @@ +#![crate_name = "uu_more"] + +/* + * This file is part of the uutils coreutils package. + * + * (c) Jordy Dickinson + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +extern crate getopts; + +#[macro_use] +extern crate uucore; + +use getopts::Options; +use std::io::{stdout, stdin, stderr, Write, Read, Result}; +use std::fs::File; + +extern crate nix; +use nix::sys::termios; + +#[derive(Clone, Eq, PartialEq)] +pub enum Mode { + More, + Help, + Version, +} + +static NAME: &'static str = "more"; +static VERSION: &'static str = env!("CARGO_PKG_VERSION"); + +pub fn uumain(args: Vec) -> i32 { + let mut opts = Options::new(); + + opts.optflag("h", "help", "display this help and exit"); + opts.optflag("v", "version", "output version information and exit"); + + let matches = match opts.parse(&args[1..]) { + Ok(m) => m, + Err(e) => { + show_error!("{}", e); + panic!() + }, + }; + let usage = opts.usage("more TARGET."); + let mode = if matches.opt_present("version") { + Mode::Version + } else if matches.opt_present("help") { + Mode::Help + } else { + Mode::More + }; + + match mode { + Mode::More => more(matches), + Mode::Help => help(&usage), + Mode::Version => version(), + } + + 0 +} + +fn version() { + println!("{} {}", NAME, VERSION); +} + +fn help(usage: &str) { + let msg = format!("{0} {1}\n\n\ + Usage: {0} TARGET\n \ + \n\ + {2}", NAME, VERSION, usage); + println!("{}", msg); +} + +fn more(matches: getopts::Matches) { + let mut files = matches.free; + let mut f = File::open(files.first().unwrap()).unwrap(); + let mut buffer = [0; 1024]; + + let saved_term = termios::tcgetattr(0).unwrap(); + let mut term = saved_term; + // Unset canonical mode, so we get characters immediately + term.c_lflag.remove(termios::ICANON); + // Disable local echo + term.c_lflag.remove(termios::ECHO); + termios::tcsetattr(0, termios::TCSADRAIN, &term).unwrap(); + + let mut end = false; + while let Ok(sz) = f.read(&mut buffer) { + if sz == 0 { break; } + stdout().write(&buffer[0..sz]).unwrap(); + for byte in std::io::stdin().bytes() { + let byte = byte.unwrap(); + match byte { + b' ' => break, + b'q' | 27 => { + end = true; + break; + }, + _ => () + } + } + + if end { break;} + } + + term.c_lflag.insert(termios::ICANON); + term.c_lflag.insert(termios::ECHO); + termios::tcsetattr(0, termios::TCSADRAIN, &term).unwrap(); + println!(""); +} From c522a62232b79ac2ad9c322272abd5d711dbd0a7 Mon Sep 17 00:00:00 2001 From: Martin Kysel Date: Wed, 17 Aug 2016 20:45:27 +0100 Subject: [PATCH 2/4] update documentation --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f82914b83..7257f21dd 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,7 @@ To do * [x] mknod * [x] mktemp * [x] mv +* [ ] more (in progress, needs lots of work) * [x] nice * [x] nl * [x] nohup From a90aec3f1bdd9380eb71342ab2104947bc641b05 Mon Sep 17 00:00:00 2001 From: Martin Kysel Date: Tue, 23 Aug 2016 10:50:45 +0100 Subject: [PATCH 3/4] add author name --- src/more/more.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/more/more.rs b/src/more/more.rs index bae650abd..39a87cc35 100644 --- a/src/more/more.rs +++ b/src/more/more.rs @@ -3,7 +3,7 @@ /* * This file is part of the uutils coreutils package. * - * (c) Jordy Dickinson + * (c) Martin Kysel * * For the full copyright and license information, please view the LICENSE file * that was distributed with this source code. From 23bab3df6988ea8afba34ea149b3b808a99bbdc2 Mon Sep 17 00:00:00 2001 From: Martin Kysel Date: Tue, 23 Aug 2016 11:40:09 +0100 Subject: [PATCH 4/4] moved more to unix utils, minor review updates --- Cargo.toml | 2 +- src/more/more.rs | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3ce10523b..95ea8df4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ unix = [ "logname", "mkfifo", "mknod", + "more", "mv", "nice", "nohup", @@ -63,7 +64,6 @@ generic = [ "ls", "mkdir", "mktemp", - "more", "nl", "nproc", "od", diff --git a/src/more/more.rs b/src/more/more.rs index 39a87cc35..094894cbf 100644 --- a/src/more/more.rs +++ b/src/more/more.rs @@ -15,7 +15,7 @@ extern crate getopts; extern crate uucore; use getopts::Options; -use std::io::{stdout, stdin, stderr, Write, Read, Result}; +use std::io::{stdout, Write, Read}; use std::fs::File; extern crate nix; @@ -75,12 +75,11 @@ fn help(usage: &str) { } fn more(matches: getopts::Matches) { - let mut files = matches.free; + let files = matches.free; let mut f = File::open(files.first().unwrap()).unwrap(); let mut buffer = [0; 1024]; - let saved_term = termios::tcgetattr(0).unwrap(); - let mut term = saved_term; + let mut term = termios::tcgetattr(0).unwrap(); // Unset canonical mode, so we get characters immediately term.c_lflag.remove(termios::ICANON); // Disable local echo @@ -92,8 +91,7 @@ fn more(matches: getopts::Matches) { if sz == 0 { break; } stdout().write(&buffer[0..sz]).unwrap(); for byte in std::io::stdin().bytes() { - let byte = byte.unwrap(); - match byte { + match byte.unwrap() { b' ' => break, b'q' | 27 => { end = true;