1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

fix build infrastructure ; modernize library use

This patch begins the work of modernizing uutils to work with 1.0-ish
Rust. In particular, it

1. Updates to the latest submodules.

2. Convert mkmain.rs, mkuutils.rs, and src/uutils/uutils.rs
   to new slice syntax and use of new io, fs, and path APIs.

3. Convert src/common/util.rs to new io, fs, and path APIs.

4. Convert fmt to use new APIs.
This commit is contained in:
kwantam 2015-04-16 00:59:33 -04:00
parent e526de0079
commit ecf248c5e3
13 changed files with 102 additions and 109 deletions

2
.gitmodules vendored
View file

@ -1,6 +1,6 @@
[submodule "deps/rust-crypto"]
path = deps/rust-crypto
url = git://github.com/DaGenix/rust-crypto.git
url = https://github.com/DaGenix/rust-crypto
[submodule "deps/time"]
path = deps/time
url = https://github.com/rust-lang/time

View file

@ -266,6 +266,3 @@ path = "whoami/whoami.rs"
[[bin]]
name = "yes"
path = "yes/yes.rs"
[dependencies.rust-crypto]
git = "https://github.com/dagenix/rust-crypto"

View file

@ -259,7 +259,7 @@ $(BUILDDIR)/stdbuf: $(BUILDDIR)/libstdbuf.$(DYLIB_EXT)
$(BUILDDIR)/.rust-crypto: | $(BUILDDIR)
cd $(BASEDIR)/deps/rust-crypto && $(CARGO) build --release
cp -r $(BASEDIR)/deps/rust-crypto/target/release/deps/librand*.rlib $(BUILDDIR)/librand.rlib
cp -r $(BASEDIR)/deps/rust-crypto/target/release/deps/librustc-serialize*.rlib $(BUILDDIR)/librustc-serialize.rlib
cp -r $(BASEDIR)/deps/rust-crypto/target/release/deps/librustc_serialize*.rlib $(BUILDDIR)/librustc-serialize.rlib
cp -r $(BASEDIR)/deps/rust-crypto/target/release/deps/libtime*.rlib $(BUILDDIR)/libtime.rlib
cp -r $(BASEDIR)/deps/rust-crypto/target/release/deps/liblibc*.rlib $(BUILDDIR)/liblibc.rlib
cp -r $(BASEDIR)/deps/rust-crypto/target/release/libcrypto*.rlib $(BUILDDIR)/libcrypto.rlib

2
deps/regex vendored

@ -1 +1 @@
Subproject commit b8cc898f17442e5769cbce081d884e47d28c54e5
Subproject commit 399758aeae3dcab382b0af5fa9964c1e32066dda

2
deps/rust-crypto vendored

@ -1 +1 @@
Subproject commit e2ba6ea926782278222558557d3d87221b87c740
Subproject commit 5571cb41690b9cee12025192393ea7df0eddc21b

2
deps/time vendored

@ -1 +1 @@
Subproject commit e216d0de7377a1ae5c8617f6e1a9f60dc61d7ec7
Subproject commit a7869dcee07de6df4e81b48bdfe137c70c153643

View file

@ -1,11 +1,11 @@
#![feature(core, exit_status, old_io, old_path)]
#![feature(exit_status)]
use std::env;
use std::old_io::{File, Truncate, ReadWrite};
use std::old_path::Path;
use std::io::Write;
use std::fs::File;
static TEMPLATE: &'static str = "\
#![feature(exit_status)]
extern crate \"@UTIL_CRATE@\" as uu@UTIL_CRATE@;
extern crate @UTIL_CRATE@ as uu@UTIL_CRATE@;
use std::env;
use uu@UTIL_CRATE@::uumain;
@ -23,14 +23,15 @@ fn main() {
return;
}
let crat = args[1].as_slice();
let outfile = args[2].as_slice();
let crat = &args[1][..];
let outfile = &args[2][..];
let main = TEMPLATE.replace("@UTIL_CRATE@", crat);
let mut out = File::open_mode(&Path::new(outfile), Truncate, ReadWrite);
match out.write_all(main.as_bytes()) {
match File::create(outfile) {
Ok(mut out) => match out.write_all(main.as_bytes()) {
Err(e) => panic!("{}", e),
_ => (),
},
Err(e) => panic!("{}", e),
_ => (),
}
}

View file

@ -1,8 +1,8 @@
#![feature(core, exit_status, old_io, old_path)]
#![feature(exit_status)]
use std::env;
use std::old_io::{File, Truncate, Write};
use std::old_path::Path;
use std::fs::File;
use std::io::{Read, Write};
fn main() {
let args : Vec<String> = env::args().collect();
@ -16,7 +16,7 @@ fn main() {
let mut util_map = String::new();
let mut hashsum = false;
for prog in args[2..].iter() {
match prog.as_slice() {
match &prog[..] {
"hashsum" | "md5sum" | "sha1sum" | "sha224sum" | "sha256sum" | "sha384sum" | "sha512sum" => {
if !hashsum {
crates.push_str("extern crate hashsum;\n");
@ -33,18 +33,22 @@ fn main() {
"true" => util_map.push_str("fn uutrue(_: Vec<String>) -> i32 { 0 }\nmap.insert(\"true\", uutrue);\n"),
"false" => util_map.push_str("fn uufalse(_: Vec<String>) -> i32 { 1 }\nmap.insert(\"false\", uufalse);\n"),
_ => {
crates.push_str(format!("extern crate \"{0}\" as uu{0};\n", prog).as_slice());
util_map.push_str(format!("map.insert(\"{prog}\", uu{prog}::uumain as fn(Vec<String>) -> i32);\n", prog = prog).as_slice());
crates.push_str(&(format!("extern crate {0} as uu{0};\n", prog))[..]);
util_map.push_str(&(format!("map.insert(\"{prog}\", uu{prog}::uumain as fn(Vec<String>) -> i32);\n", prog = prog))[..]);
}
}
}
let outfile = args[1].as_slice();
let outfile = &(args[1])[..];
// XXX: this all just assumes that the IO works correctly
let mut out = File::open_mode(&Path::new(outfile), Truncate, Write).unwrap();
let mut input = File::open(&Path::new("src/uutils/uutils.rs")).unwrap();
let main = input.read_to_string().unwrap().replace("@CRATES@", crates.as_slice()).replace("@UTIL_MAP@", util_map.as_slice());
let mut out = File::create(outfile).unwrap();
let mut input = File::open("src/uutils/uutils.rs").unwrap();
let mut template = String::new();
input.read_to_string(&mut template).unwrap();
let template = template;
let main = template.replace("@CRATES@", &crates[..]).replace("@UTIL_MAP@", &util_map[..]);
match out.write_all(main.as_bytes()) {
Err(e) => panic!("{}", e),
_ => (),

View file

@ -11,35 +11,35 @@ extern crate libc;
macro_rules! show_error(
($($args:tt)+) => ({
pipe_write!(&mut ::std::old_io::stderr(), "{}: error: ", ::NAME);
pipe_writeln!(&mut ::std::old_io::stderr(), $($args)+);
pipe_write!(&mut ::std::io::stderr(), "{}: error: ", ::NAME);
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
})
);
#[macro_export]
macro_rules! show_warning(
($($args:tt)+) => ({
pipe_write!(&mut ::std::old_io::stderr(), "{}: warning: ", ::NAME);
pipe_writeln!(&mut ::std::old_io::stderr(), $($args)+);
pipe_write!(&mut ::std::io::stderr(), "{}: warning: ", ::NAME);
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
})
);
#[macro_export]
macro_rules! show_info(
($($args:tt)+) => ({
pipe_write!(&mut ::std::old_io::stderr(), "{}: ", ::NAME);
pipe_writeln!(&mut ::std::old_io::stderr(), $($args)+);
pipe_write!(&mut ::std::io::stderr(), "{}: ", ::NAME);
pipe_writeln!(&mut ::std::io::stderr(), $($args)+);
})
);
#[macro_export]
macro_rules! eprint(
($($args:tt)+) => (pipe_write!(&mut ::std::old_io::stderr(), $($args)+))
($($args:tt)+) => (pipe_write!(&mut ::std::io::stderr(), $($args)+))
);
#[macro_export]
macro_rules! eprintln(
($($args:tt)+) => (pipe_writeln!(&mut ::std::old_io::stderr(), $($args)+))
($($args:tt)+) => (pipe_writeln!(&mut ::std::io::stderr(), $($args)+))
);
#[macro_export]
@ -85,10 +85,10 @@ macro_rules! return_if_err(
#[macro_export]
macro_rules! pipe_print(
($($args:tt)+) => (
match write!(&mut ::std::old_io::stdout(), $($args)+) {
match write!(&mut ::std::io::stdout(), $($args)+) {
Ok(_) => true,
Err(f) => {
if f.kind == ::std::old_io::BrokenPipe {
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
false
} else {
panic!("{}", f)
@ -101,10 +101,10 @@ macro_rules! pipe_print(
#[macro_export]
macro_rules! pipe_println(
($($args:tt)+) => (
match writeln!(&mut ::std::old_io::stdout(), $($args)+) {
match writeln!(&mut ::std::io::stdout(), $($args)+) {
Ok(_) => true,
Err(f) => {
if f.kind == ::std::old_io::BrokenPipe {
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
false
} else {
panic!("{}", f)
@ -120,7 +120,7 @@ macro_rules! pipe_write(
match write!($fd, $($args)+) {
Ok(_) => true,
Err(f) => {
if f.kind == ::std::old_io::BrokenPipe {
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
false
} else {
panic!("{}", f)
@ -136,7 +136,7 @@ macro_rules! pipe_writeln(
match writeln!($fd, $($args)+) {
Ok(_) => true,
Err(f) => {
if f.kind == ::std::old_io::BrokenPipe {
if f.kind() == ::std::io::ErrorKind::BrokenPipe {
false
} else {
panic!("{}", f)

View file

@ -1,5 +1,4 @@
#![crate_name = "fmt"]
#![allow(unstable)]
/*
* This file is part of `fmt` from the uutils coreutils package.
@ -10,15 +9,16 @@
* file that was distributed with this source code.
*/
#![feature(box_syntax)]
#![feature(box_syntax,core,rustc_private,collections,str_char,unicode,str_words)]
extern crate core;
extern crate getopts;
extern crate unicode;
use std::cmp;
use std::old_io::{BufferedReader, BufferedWriter, File, IoResult};
use std::old_io::stdio::{stdin_raw, stdout_raw};
use std::io::{Read, BufReader, BufWriter};
use std::fs::File;
use std::io::{stdin, stdout, Write};
use linebreak::break_lines;
use parasplit::ParagraphStream;
@ -41,7 +41,8 @@ mod parasplit;
static NAME: &'static str = "fmt";
static VERSION: &'static str = "0.0.3";
struct FmtOptions {
pub type FileOrStdReader = BufReader<Box<Read+'static>>;
pub struct FmtOptions {
crown : bool,
tagged : bool,
mail : bool,
@ -85,13 +86,13 @@ pub fn uumain(args: Vec<String>) -> i32 {
getopts::optflag("h", "help", "Display this help message and exit.")
];
let matches = match getopts::getopts(args.tail(), opts.as_slice()) {
let matches = match getopts::getopts(args.tail(), &opts[..]) {
Ok(m) => m,
Err(f) => crash!(1, "{}\nTry `{} --help' for more information.", f, args[0])
};
if matches.opt_present("h") {
print_usage(args[0].as_slice(), opts.as_slice(), "");
print_usage(&(args[0])[..], &opts[..], "");
}
if matches.opt_present("V") || matches.opt_present("h") {
@ -193,18 +194,20 @@ pub fn uumain(args: Vec<String>) -> i32 {
files.push("-".to_string());
}
let mut ostream = box BufferedWriter::new(stdout_raw()) as Box<Writer>;
let mut ostream = BufWriter::new(stdout());
for i in files.iter().map(|x| x.as_slice()) {
let mut fp =
match open_file(i) {
for i in files.iter().map(|x| &x[..]) {
let mut fp = match i {
"-" => BufReader::new(box stdin() as Box<Read+'static>),
_ => match File::open(i) {
Ok(f) => BufReader::new(box f as Box<Read+'static>),
Err(e) => {
show_warning!("{}: {}", i, e);
continue;
}
Ok(f) => f
};
let mut p_stream = ParagraphStream::new(&fmt_opts, &mut fp);
},
},
};
let p_stream = ParagraphStream::new(&fmt_opts, &mut fp);
for para_result in p_stream {
match para_result {
Err(s) => silent_unwrap!(ostream.write_all(s.as_bytes())),
@ -222,18 +225,3 @@ pub fn uumain(args: Vec<String>) -> i32 {
fn print_usage(arg0: &str, opts: &[getopts::OptGroup], errmsg: &str) {
println!("Usage: {} [OPTION]... [FILE]...\n\n{}{}", arg0, getopts::usage("Reformat paragraphs from input files (or stdin) to stdout.", opts), errmsg);
}
// uniform interface for opening files
// since we don't need seeking
type FileOrStdReader = BufferedReader<Box<Reader+'static>>;
fn open_file(filename: &str) -> IoResult<FileOrStdReader> {
if filename == "-" {
Ok(BufferedReader::new(box stdin_raw() as Box<Reader>))
} else {
match File::open(&Path::new(filename)) {
Ok(f) => Ok(BufferedReader::new(box f as Box<Reader>)),
Err(e) => return Err(e)
}
}
}

View file

@ -9,6 +9,7 @@
use FmtOptions;
use parasplit::{Paragraph, ParaWords, WordInfo};
use std::io::{Write, BufWriter, Stdout};
use std::num::{Float, Int, SignedInt};
use std::i64;
use std::cmp;
@ -20,7 +21,7 @@ struct BreakArgs<'a> {
indent_str : &'a str,
indent_len : usize,
uniform : bool,
ostream : &'a mut Box<Writer+'static>
ostream : &'a mut BufWriter<Stdout>
}
impl<'a> BreakArgs<'a> {
@ -38,9 +39,9 @@ impl<'a> BreakArgs<'a> {
}
}
pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut Box<Writer+'static>) {
pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut BufWriter<Stdout>) {
// indent
let p_indent = para.indent_str.as_slice();
let p_indent = &para.indent_str[..];
let p_indent_len = para.indent_len;
// words
@ -52,7 +53,7 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut Box<Writer
let (w, w_len) = match p_words_words.next() {
Some(winfo) => (winfo.word, winfo.word_nchars),
None => {
silent_unwrap!(ostream.write_char('\n'));
silent_unwrap!(ostream.write_all("\n".as_bytes()));
return;
}
};
@ -79,7 +80,7 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut Box<Writer
let mut break_args = BreakArgs {
opts : opts,
init_len : p_init_len,
indent_str : p_indent,
indent_str : &p_indent[..],
indent_len : p_indent_len,
uniform : uniform,
ostream : ostream
@ -96,7 +97,7 @@ pub fn break_lines(para: &Paragraph, opts: &FmtOptions, ostream: &mut Box<Writer
// maxlength would be exceeded, then print a linebreak and indent and continue.
fn break_simple<'a, T: Iterator<Item=&'a WordInfo<'a>>>(iter: T, args: &mut BreakArgs<'a>) {
iter.fold((args.init_len, false), |l, winfo| accum_words_simple(args, l, winfo));
silent_unwrap!(args.ostream.write_char('\n'));
silent_unwrap!(args.ostream.write_all("\n".as_bytes()));
}
#[inline(always)]
@ -131,7 +132,7 @@ fn break_knuth_plass<'a, T: Clone + Iterator<Item=&'a WordInfo<'a>>>(mut iter: T
write_newline(args.indent_str, args.ostream);
}
// at each breakpoint, keep emitting words until we find the word matching this breakpoint
for winfo in iter {
for winfo in &mut iter {
let (slen, word) = slice_if_fresh(fresh, winfo.word, winfo.word_start, args.uniform,
winfo.new_line, winfo.sentence_start, prev_punct);
fresh = false;
@ -170,7 +171,7 @@ fn break_knuth_plass<'a, T: Clone + Iterator<Item=&'a WordInfo<'a>>>(mut iter: T
fresh = false;
write_with_spaces(word, slen, args.ostream);
}
silent_unwrap!(args.ostream.write_char('\n'));
silent_unwrap!(args.ostream.write_all("\n".as_bytes()));
}
struct LineBreak<'a> {
@ -435,18 +436,18 @@ fn slice_if_fresh<'a>(fresh: bool, word: &'a str, start: usize, uniform: bool, n
// Write a newline and add the indent.
#[inline(always)]
fn write_newline(indent: &str, ostream: &mut Box<Writer>) {
silent_unwrap!(ostream.write_char('\n'));
fn write_newline(indent: &str, ostream: &mut BufWriter<Stdout>) {
silent_unwrap!(ostream.write_all("\n".as_bytes()));
silent_unwrap!(ostream.write_all(indent.as_bytes()));
}
// Write the word, along with slen spaces.
#[inline(always)]
fn write_with_spaces(word: &str, slen: usize, ostream: &mut Box<Writer>) {
fn write_with_spaces(word: &str, slen: usize, ostream: &mut BufWriter<Stdout>) {
if slen == 2 {
silent_unwrap!(ostream.write_all(" ".as_bytes()));
} else if slen == 1 {
silent_unwrap!(ostream.write_char(' '));
silent_unwrap!(ostream.write_all(" ".as_bytes()));
}
silent_unwrap!(ostream.write_all(word.as_bytes()));
}

View file

@ -8,7 +8,7 @@
*/
use core::iter::Peekable;
use std::old_io::Lines;
use std::io::{BufRead, Lines};
use std::slice::Iter;
use std::str::CharRange;
use unicode::str::UnicodeStr;
@ -69,11 +69,11 @@ struct FileLine {
// iterator that produces a stream of Lines from a file
pub struct FileLines<'a> {
opts : &'a FmtOptions,
lines : Lines<'a, FileOrStdReader>,
lines : Lines<&'a mut FileOrStdReader>,
}
impl<'a> FileLines<'a> {
fn new<'b>(opts: &'b FmtOptions, lines: Lines<'b, FileOrStdReader>) -> FileLines<'b> {
fn new<'b>(opts: &'b FmtOptions, lines: Lines<&'b mut FileOrStdReader>) -> FileLines<'b> {
FileLines { opts: opts, lines: lines }
}
@ -81,14 +81,14 @@ impl<'a> FileLines<'a> {
fn match_prefix(&self, line: &str) -> (bool, usize) {
if !self.opts.use_prefix { return (true, 0); }
FileLines::match_prefix_generic(self.opts.prefix.as_slice(), line, self.opts.xprefix)
FileLines::match_prefix_generic(&self.opts.prefix[..], line, self.opts.xprefix)
}
// returns true if this line should be formatted
fn match_anti_prefix(&self, line: &str) -> bool {
if !self.opts.use_anti_prefix { return true; }
match FileLines::match_prefix_generic(self.opts.anti_prefix.as_slice(), line, self.opts.xanti_prefix) {
match FileLines::match_prefix_generic(&self.opts.anti_prefix[..], line, self.opts.xanti_prefix) {
(true, _) => false,
(_ , _) => true
}
@ -156,16 +156,16 @@ impl<'a> Iterator for FileLines<'a> {
// emit a blank line
// Err(true) indicates that this was a linebreak,
// which is important to know when detecting mail headers
if n.as_slice().is_whitespace() {
if n.is_whitespace() {
return Some(Line::NoFormatLine("\n".to_string(), true));
}
// if this line does not match the prefix,
// emit the line unprocessed and iterate again
let (pmatch, poffset) = self.match_prefix(n.as_slice());
let (pmatch, poffset) = self.match_prefix(&n[..]);
if !pmatch {
return Some(Line::NoFormatLine(n, false));
} else if n.as_slice()[poffset + self.opts.prefix.len()..].is_whitespace() {
} else if n[poffset + self.opts.prefix.len()..].is_whitespace() {
// if the line matches the prefix, but is blank after,
// don't allow lines to be combined through it (that is,
// treat it like a blank line, except that since it's
@ -176,13 +176,13 @@ impl<'a> Iterator for FileLines<'a> {
// skip if this line matches the anti_prefix
// (NOTE definition of match_anti_prefix is TRUE if we should process)
if !self.match_anti_prefix(n.as_slice()) {
if !self.match_anti_prefix(&n[..]) {
return Some(Line::NoFormatLine(n, false));
}
// figure out the indent, prefix, and prefixindent ending points
let prefix_end = poffset + self.opts.prefix.len();
let (indent_end, prefix_len, indent_len) = self.compute_indent(n.as_slice(), prefix_end);
let (indent_end, prefix_len, indent_len) = self.compute_indent(&n[..], prefix_end);
Some(Line::FormatLine(FileLine {
line : n,
@ -233,7 +233,7 @@ impl<'a> ParagraphStream<'a> {
if line.indent_end > 0 {
false
} else {
let l_slice = line.line.as_slice();
let l_slice = &line.line[..];
if l_slice.starts_with("From ") {
true
} else {
@ -314,7 +314,7 @@ impl<'a> Iterator for ParagraphStream<'a> {
indent_len = 2;
} else {
if self.opts.crown || self.opts.tagged {
init_str.push_str(&fl.line.as_slice()[..fl.indent_end]);
init_str.push_str(&fl.line[..fl.indent_end]);
init_len = fl.indent_len;
init_end = fl.indent_end;
} else {
@ -324,7 +324,7 @@ impl<'a> Iterator for ParagraphStream<'a> {
// these will be overwritten in the 2nd line of crown or tagged mode, but
// we are not guaranteed to get to the 2nd line, e.g., if the next line
// is a NoFormatLine or None. Thus, we set sane defaults the 1st time around
indent_str.push_str(&fl.line.as_slice()[..fl.indent_end]);
indent_str.push_str(&fl.line[..fl.indent_end]);
indent_len = fl.indent_len;
indent_end = fl.indent_end;
@ -358,7 +358,7 @@ impl<'a> Iterator for ParagraphStream<'a> {
} else {
// this is part of the same paragraph, get the indent info from this line
indent_str.clear();
indent_str.push_str(&fl.line.as_slice()[..fl.indent_end]);
indent_str.push_str(&fl.line[..fl.indent_end]);
indent_len = fl.indent_len;
indent_end = fl.indent_end;
}
@ -415,7 +415,7 @@ impl<'a> ParaWords<'a> {
// no extra spacing for mail headers; always exactly 1 space
// safe to trim_left on every line of a mail header, since the
// first line is guaranteed not to have any spaces
self.words.extend(self.para.lines.iter().flat_map(|x| StrExt::words(x.as_slice())).map(|x| WordInfo {
self.words.extend(self.para.lines.iter().flat_map(|x| x.words()).map(|x| WordInfo {
word : x,
word_start : 0,
word_nchars : x.len(), // OK for mail headers; only ASCII allowed (unicode is escaped)
@ -430,17 +430,17 @@ impl<'a> ParaWords<'a> {
self.words.extend(
if self.opts.crown || self.opts.tagged {
// crown and tagged mode has the "init" in the first line, so slice from there
WordSplit::new(self.opts, &self.para.lines[0].as_slice()[self.para.init_end..])
WordSplit::new(self.opts, &self.para.lines[0][self.para.init_end..])
} else {
// otherwise we slice from the indent
WordSplit::new(self.opts, &self.para.lines[0].as_slice()[self.para.indent_end..])
WordSplit::new(self.opts, &self.para.lines[0][self.para.indent_end..])
});
if self.para.lines.len() > 1 {
let indent_end = self.para.indent_end;
let opts = self.opts;
self.words.extend(
self.para.lines.iter().skip(1).flat_map(|x| WordSplit::new(opts, &x.as_slice()[indent_end..])));
self.para.lines.iter().skip(1).flat_map(|x| WordSplit::new(opts, &x[indent_end..])));
}
}
}
@ -485,7 +485,7 @@ impl<'a> WordSplit<'a> {
impl<'a> WordSplit<'a> {
fn new<'b>(opts: &'b FmtOptions, string: &'b str) -> WordSplit<'b> {
// wordsplits *must* start at a non-whitespace character
let trim_string = StrExt::trim_left(string);
let trim_string = string.trim_left();
WordSplit { opts: opts, string: trim_string, length: string.len(), position: 0, prev_punct: false }
}

View file

@ -1,5 +1,5 @@
#![crate_name = "uutils"]
#![feature(core, exit_status, old_path, rustc_private)]
#![feature(exit_status, rustc_private)]
/*
* This file is part of the uutils coreutils package.
@ -16,6 +16,7 @@ extern crate getopts;
use std::env;
use std::collections::hash_map::HashMap;
use std::path::Path;
static NAME: &'static str = "uutils";
static VERSION: &'static str = "1.0.0";
@ -44,8 +45,9 @@ fn main() {
let mut args : Vec<String> = env::args().collect();
// try binary name as util name.
let binary = Path::new(args[0].as_slice());
let binary_as_util = binary.filename_str().unwrap();
let args0 = args[0].clone();
let binary = Path::new(&args0[..]);
let binary_as_util = binary.file_name().unwrap().to_str().unwrap();
match umap.get(binary_as_util) {
Some(&uumain) => {
@ -69,7 +71,7 @@ fn main() {
// try first arg as util name.
if args.len() >= 2 {
args.remove(0);
let util = args[0].as_slice();
let util = &args[0][..];
match umap.get(util) {
Some(&uumain) => {
@ -77,10 +79,10 @@ fn main() {
return
}
None => {
if args[0].as_slice() == "--help" {
if &args[0][..] == "--help" {
// see if they want help on a specific util
if args.len() >= 2 {
let util = args[1].as_slice();
let util = &args[1][..];
match umap.get(util) {
Some(&uumain) => {
env::set_exit_status(uumain(vec![util.to_string(), "--help".to_string()]));