mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 04:27:45 +00:00
commit
22093d1e5a
1 changed files with 49 additions and 41 deletions
|
@ -1,5 +1,5 @@
|
||||||
#![crate_name = "comm"]
|
#![crate_name = "comm"]
|
||||||
#![feature(collections, core, old_io, old_path, rustc_private)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
|
@ -13,10 +13,9 @@
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::old_io::{BufferedReader, IoResult, print};
|
use std::io::{self, stdin, Stdin, BufReader, BufRead, Read};
|
||||||
use std::old_io::fs::File;
|
use std::fs::File;
|
||||||
use std::old_io::stdio::{stdin, StdinReader};
|
use std::path::Path;
|
||||||
use std::old_path::Path;
|
|
||||||
|
|
||||||
static NAME : &'static str = "comm";
|
static NAME : &'static str = "comm";
|
||||||
static VERSION : &'static str = "1.0.0";
|
static VERSION : &'static str = "1.0.0";
|
||||||
|
@ -29,81 +28,90 @@ fn mkdelim(col: usize, opts: &getopts::Matches) -> String {
|
||||||
};
|
};
|
||||||
|
|
||||||
if col > 1 && !opts.opt_present("1") {
|
if col > 1 && !opts.opt_present("1") {
|
||||||
s.push_str(delim.as_slice());
|
s.push_str(delim.as_ref());
|
||||||
}
|
}
|
||||||
if col > 2 && !opts.opt_present("2") {
|
if col > 2 && !opts.opt_present("2") {
|
||||||
s.push_str(delim.as_slice());
|
s.push_str(delim.as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_nl(line: String) -> String {
|
fn ensure_nl(line: &mut String) {
|
||||||
match line.as_slice().chars().last() {
|
match line.chars().last() {
|
||||||
Some('\n') => line,
|
Some('\n') => (),
|
||||||
_ => line + "\n",
|
_ => line.push_str("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LineReader {
|
enum LineReader {
|
||||||
Stdin(StdinReader),
|
Stdin(Stdin),
|
||||||
FileIn(BufferedReader<File>)
|
FileIn(BufReader<File>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineReader {
|
impl LineReader {
|
||||||
fn read_line(&mut self) -> IoResult<String> {
|
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||||
match self {
|
match self {
|
||||||
&mut LineReader::Stdin(ref mut r) => r.read_line(),
|
&mut LineReader::Stdin(ref mut r) => r.read_line(buf),
|
||||||
&mut LineReader::FileIn(ref mut r) => r.read_line(),
|
&mut LineReader::FileIn(ref mut r) => r.read_line(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) {
|
fn comm(a: &mut LineReader, b: &mut LineReader, opts: &getopts::Matches) {
|
||||||
|
|
||||||
let delim : Vec<String> = range(0, 4).map(|col| mkdelim(col, opts)).collect();
|
let delim : Vec<String> = (0 .. 4).map(|col| mkdelim(col, opts)).collect();
|
||||||
|
|
||||||
let mut ra = a.read_line();
|
let mut ra = &mut String::new();
|
||||||
let mut rb = b.read_line();
|
let mut na = a.read_line(ra);
|
||||||
|
let mut rb = &mut String::new();
|
||||||
|
let mut nb = b.read_line(rb);
|
||||||
|
|
||||||
while ra.is_ok() || rb.is_ok() {
|
while na.is_ok() || nb.is_ok() {
|
||||||
let ord = match (ra.clone(), rb.clone()) {
|
let ord = match (na.is_ok(), nb.is_ok()) {
|
||||||
(Err(_), Ok(_)) => Ordering::Greater,
|
(false, true) => Ordering::Greater,
|
||||||
(Ok(_) , Err(_)) => Ordering::Less,
|
(true , false) => Ordering::Less,
|
||||||
(Ok(s0), Ok(s1)) => s0.cmp(&s1),
|
(true , true) => match(&na, &nb) {
|
||||||
|
(&Ok(0), _) => Ordering::Greater,
|
||||||
|
(_, &Ok(0)) => Ordering::Less,
|
||||||
|
_ => ra.cmp(&rb),
|
||||||
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match ord {
|
match ord {
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
if !opts.opt_present("1") {
|
if !opts.opt_present("1") {
|
||||||
print!("{}{}", delim[1], ra.map(ensure_nl).unwrap());
|
ensure_nl(ra);
|
||||||
|
print!("{}{}", delim[1], ra);
|
||||||
}
|
}
|
||||||
ra = a.read_line();
|
na = a.read_line(ra);
|
||||||
}
|
},
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
if !opts.opt_present("2") {
|
if !opts.opt_present("2") {
|
||||||
print!("{}{}", delim[2], rb.map(ensure_nl).unwrap());
|
ensure_nl(rb);
|
||||||
|
print!("{}{}", delim[2], rb);
|
||||||
}
|
}
|
||||||
rb = b.read_line();
|
nb = b.read_line(rb);
|
||||||
}
|
},
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
if !opts.opt_present("3") {
|
if !opts.opt_present("3") {
|
||||||
print!("{}{}", delim[3], ra.map(ensure_nl).unwrap());
|
ensure_nl(ra);
|
||||||
|
print!("{}{}", delim[3], ra);
|
||||||
}
|
}
|
||||||
ra = a.read_line();
|
na = a.read_line(ra);
|
||||||
rb = b.read_line();
|
nb = b.read_line(rb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_file(name: &str) -> IoResult<LineReader> {
|
fn open_file(name: &str) -> io::Result<LineReader> {
|
||||||
match name {
|
match name {
|
||||||
"-" => Ok(LineReader::Stdin(stdin())),
|
"-" => Ok(LineReader::Stdin(stdin())),
|
||||||
_ => {
|
_ => {
|
||||||
let f = try!(std::old_io::File::open(&Path::new(name)));
|
let f = try!(File::open(&Path::new(name)));
|
||||||
Ok(LineReader::FileIn(BufferedReader::new(f)))
|
Ok(LineReader::FileIn(BufReader::new(f)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,7 +126,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
getopts::optflag("V", "version", "output version information and exit"),
|
getopts::optflag("V", "version", "output version information and exit"),
|
||||||
];
|
];
|
||||||
|
|
||||||
let matches = match getopts::getopts(args.tail(), &opts) {
|
let matches = match getopts::getopts(&args[1..], &opts) {
|
||||||
Ok(m) => m,
|
Ok(m) => m,
|
||||||
Err(err) => panic!("{}", err),
|
Err(err) => panic!("{}", err),
|
||||||
};
|
};
|
||||||
|
@ -134,7 +142,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
println!("Usage:");
|
println!("Usage:");
|
||||||
println!(" {} [OPTIONS] FILE1 FILE2", NAME);
|
println!(" {} [OPTIONS] FILE1 FILE2", NAME);
|
||||||
println!("");
|
println!("");
|
||||||
print(getopts::usage("Compare sorted files line by line.", opts.as_slice()).as_slice());
|
print!("{}", getopts::usage("Compare sorted files line by line.", opts.as_ref()));
|
||||||
if matches.free.len() != 2 {
|
if matches.free.len() != 2 {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -142,8 +150,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let mut f1 = open_file(matches.free[0].as_slice()).unwrap();
|
let mut f1 = open_file(matches.free[0].as_ref()).unwrap();
|
||||||
let mut f2 = open_file(matches.free[1].as_slice()).unwrap();
|
let mut f2 = open_file(matches.free[1].as_ref()).unwrap();
|
||||||
|
|
||||||
comm(&mut f1, &mut f2, &matches);
|
comm(&mut f1, &mut f2, &matches);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue