mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Merge pull request #234 from polyphemus/cut
Implement cut - implement #165
This commit is contained in:
@@ -31,6 +31,10 @@ path = "comm/comm.rs"
|
||||
name = "cp"
|
||||
path = "cp/cp.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "cut"
|
||||
path = "cut/cut.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "dirname"
|
||||
path = "dirname/dirname.rs"
|
||||
|
||||
@@ -114,7 +114,6 @@ To do
|
||||
- copy
|
||||
- cp (not much done)
|
||||
- csplit
|
||||
- cut
|
||||
- date
|
||||
- dd
|
||||
- df
|
||||
|
||||
+528
File diff suppressed because it is too large
Load Diff
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* This file is part of the uutils coreutils package.
|
||||
*
|
||||
* (c) Rolf Morel <rolfmorel@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use std;
|
||||
|
||||
#[deriving(PartialEq,Eq,PartialOrd,Ord,Show)]
|
||||
pub struct Range {
|
||||
pub low: uint,
|
||||
pub high: uint,
|
||||
}
|
||||
|
||||
impl std::from_str::FromStr for Range {
|
||||
fn from_str(s: &str) -> Option<Range> {
|
||||
use std::uint::MAX;
|
||||
|
||||
let mut parts = s.splitn('-', 1);
|
||||
|
||||
match (parts.next(), parts.next()) {
|
||||
(Some(nm), None) => {
|
||||
from_str::<uint>(nm).filtered(|nm| *nm > 0)
|
||||
.map(|nm| Range { low: nm, high: nm })
|
||||
}
|
||||
(Some(n), Some(m)) if m.len() == 0 => {
|
||||
from_str::<uint>(n).filtered(|low| *low > 0)
|
||||
.map(|low| Range { low: low, high: MAX })
|
||||
}
|
||||
(Some(n), Some(m)) if n.len() == 0 => {
|
||||
from_str::<uint>(m).filtered(|high| *high >= 1)
|
||||
.map(|high| Range { low: 1, high: high })
|
||||
}
|
||||
(Some(n), Some(m)) => {
|
||||
match (from_str::<uint>(n), from_str::<uint>(m)) {
|
||||
(Some(low), Some(high)) if low > 0 && low <= high => {
|
||||
Some(Range { low: low, high: high })
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Range {
|
||||
pub fn from_list(list: &str) -> Result<Vec<Range>, String> {
|
||||
use std::cmp::max;
|
||||
|
||||
let mut ranges = vec!();
|
||||
|
||||
for item in list.split(',') {
|
||||
match from_str::<Range>(item) {
|
||||
Some(range_item) => ranges.push(range_item),
|
||||
None => return Err(format!("range '{}' was invalid", item))
|
||||
}
|
||||
}
|
||||
|
||||
ranges.sort();
|
||||
|
||||
// merge overlapping ranges
|
||||
for i in range(0, ranges.len()) {
|
||||
let j = i + 1;
|
||||
|
||||
while j < ranges.len() && ranges.get(j).low <= ranges.get(i).high {
|
||||
let j_high = ranges.remove(j).unwrap().high;
|
||||
ranges.get_mut(i).high = max(ranges.get(i).high, j_high);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ranges)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn complement(ranges: &Vec<Range>) -> Vec<Range> {
|
||||
use std::uint;
|
||||
|
||||
let mut complements = Vec::with_capacity(ranges.len() + 1);
|
||||
|
||||
if ranges.len() > 0 && ranges.get(0).low > 1 {
|
||||
complements.push(Range { low: 1, high: ranges.get(0).low - 1 });
|
||||
}
|
||||
|
||||
let mut ranges_iter = ranges.iter().peekable();
|
||||
loop {
|
||||
match (ranges_iter.next(), ranges_iter.peek()) {
|
||||
(Some(left), Some(right)) => {
|
||||
if left.high + 1 != right.low {
|
||||
complements.push(Range {
|
||||
low: left.high + 1,
|
||||
high: right.low - 1
|
||||
});
|
||||
}
|
||||
}
|
||||
(Some(last), None) => {
|
||||
if last.high < uint::MAX {
|
||||
complements.push(Range {
|
||||
low: last.high + 1,
|
||||
high: uint::MAX
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => break
|
||||
}
|
||||
}
|
||||
|
||||
complements
|
||||
}
|
||||
@@ -18,6 +18,7 @@ extern crate chroot;
|
||||
extern crate cksum;
|
||||
extern crate comm;
|
||||
extern crate cp;
|
||||
extern crate cut;
|
||||
extern crate dirname;
|
||||
extern crate du;
|
||||
extern crate echo;
|
||||
@@ -80,6 +81,7 @@ fn util_map() -> HashMap<&str, fn(Vec<String>) -> int> {
|
||||
map.insert("cksum", cksum::uumain);
|
||||
map.insert("comm", comm::uumain);
|
||||
map.insert("cp", cp::uumain);
|
||||
map.insert("cut", cut::uumain);
|
||||
map.insert("dirname", dirname::uumain);
|
||||
map.insert("du", du::uumain);
|
||||
map.insert("echo", echo::uumain);
|
||||
|
||||
Reference in New Issue
Block a user