1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #978 from vegichan/master

Implement more - initial draft
This commit is contained in:
Nathan Ross 2016-08-23 07:26:33 -04:00 committed by GitHub
commit e8338ca175
7 changed files with 139 additions and 0 deletions

1
.gitignore vendored
View file

@ -6,5 +6,6 @@ target/
*~
.*.swp
.*.swo
.idea
Cargo.lock
lib*.a

View file

@ -21,6 +21,7 @@ unix = [
"logname",
"mkfifo",
"mknod",
"more",
"mv",
"nice",
"nohup",
@ -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" }

View file

@ -66,6 +66,7 @@ PROGS := \
ls \
mkdir \
mktemp \
more \
nl \
nproc \
od \

View file

@ -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

18
src/more/Cargo.toml Normal file
View file

@ -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"

5
src/more/main.rs Normal file
View file

@ -0,0 +1,5 @@
extern crate uu_more;
fn main() {
std::process::exit(uu_more::uumain(std::env::args().collect()));
}

111
src/more/more.rs Normal file
View file

@ -0,0 +1,111 @@
#![crate_name = "uu_more"]
/*
* This file is part of the uutils coreutils package.
*
* (c) Martin Kysel <code@martinkysel.com>
*
* 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, Write, Read};
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<String>) -> 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 files = matches.free;
let mut f = File::open(files.first().unwrap()).unwrap();
let mut buffer = [0; 1024];
let mut term = termios::tcgetattr(0).unwrap();
// 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() {
match byte.unwrap() {
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!("");
}