mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Initial more implementation
This commit is contained in:
parent
ae0e1c4768
commit
7d77b9720d
6 changed files with 140 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,5 +6,6 @@ target/
|
||||||
*~
|
*~
|
||||||
.*.swp
|
.*.swp
|
||||||
.*.swo
|
.*.swo
|
||||||
|
.idea
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
lib*.a
|
lib*.a
|
||||||
|
|
|
@ -63,6 +63,7 @@ generic = [
|
||||||
"ls",
|
"ls",
|
||||||
"mkdir",
|
"mkdir",
|
||||||
"mktemp",
|
"mktemp",
|
||||||
|
"more",
|
||||||
"nl",
|
"nl",
|
||||||
"nproc",
|
"nproc",
|
||||||
"od",
|
"od",
|
||||||
|
@ -144,6 +145,7 @@ mkdir = { optional=true, path="src/mkdir" }
|
||||||
mkfifo = { optional=true, path="src/mkfifo" }
|
mkfifo = { optional=true, path="src/mkfifo" }
|
||||||
mknod = { optional=true, path="src/mknod" }
|
mknod = { optional=true, path="src/mknod" }
|
||||||
mktemp = { optional=true, path="src/mktemp" }
|
mktemp = { optional=true, path="src/mktemp" }
|
||||||
|
more = { optional=true, path="src/more" }
|
||||||
mv = { optional=true, path="src/mv" }
|
mv = { optional=true, path="src/mv" }
|
||||||
nice = { optional=true, path="src/nice" }
|
nice = { optional=true, path="src/nice" }
|
||||||
nl = { optional=true, path="src/nl" }
|
nl = { optional=true, path="src/nl" }
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -66,6 +66,7 @@ PROGS := \
|
||||||
ls \
|
ls \
|
||||||
mkdir \
|
mkdir \
|
||||||
mktemp \
|
mktemp \
|
||||||
|
more \
|
||||||
nl \
|
nl \
|
||||||
nproc \
|
nproc \
|
||||||
od \
|
od \
|
||||||
|
|
18
src/more/Cargo.toml
Normal file
18
src/more/Cargo.toml
Normal 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
5
src/more/main.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
extern crate uu_more;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
std::process::exit(uu_more::uumain(std::env::args().collect()));
|
||||||
|
}
|
113
src/more/more.rs
Normal file
113
src/more/more.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#![crate_name = "uu_more"]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the uutils coreutils package.
|
||||||
|
*
|
||||||
|
* (c) Jordy Dickinson <jordy.dickinson@gmail.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, 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<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 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!("");
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue