From 49f3f0ea32e534499f7f56ab04a1b8ce877b0e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ci=C4=99=C5=BCarkiewicz?= Date: Wed, 19 Mar 2014 11:38:11 -0700 Subject: [PATCH] Fix compilation for latest rustc. Some warning are still there. (cherry picked from commit 5c690b33d60725d8ef90c8531adf832f9afd27a8) Conflicts: cp/cp.rs --- base64/base64.rs | 2 + cp/cp.rs | 178 +++++++++++++++++++++++++++++++++++++++++++++++ tee/tee.rs | 3 + 3 files changed, 183 insertions(+) create mode 100644 cp/cp.rs diff --git a/base64/base64.rs b/base64/base64.rs index a05c9c520..b5315c9af 100644 --- a/base64/base64.rs +++ b/base64/base64.rs @@ -9,10 +9,12 @@ * that was distributed with this source code. */ +#[feature(phase)]; #[feature(macro_rules)]; extern crate serialize; extern crate getopts; +#[phase(syntax, link)] extern crate log; use std::char; use std::io::{println, File, stdin, stdout}; diff --git a/cp/cp.rs b/cp/cp.rs new file mode 100644 index 000000000..f61bd99b8 --- /dev/null +++ b/cp/cp.rs @@ -0,0 +1,178 @@ +#[crate_id(name="cp", vers="1.0.0", author="Jordy Dickinson")]; +#[feature(macro_rules)]; +#[feature(phase)]; + +/* + * This file is part of the uutils coreutils package. + * + * (c) Jordy Dickinson + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +extern crate getopts; +#[phase(syntax, link)] extern crate log; + +use std::os; +use std::io; +use std::io::fs; + +use getopts::{ + getopts, + optflag, + usage, +}; + +#[deriving(Eq)] +pub enum Mode { + Copy, + Help, + Version, +} + +fn main() { + let args = os::args(); + let opts = ~[ + optflag("h", "help", "display this help and exit"), + optflag("", "version", "output version information and exit"), + ]; + let matches = match getopts(args.tail(), opts) { + Ok(m) => m, + Err(e) => { + error!("error: {:s}", e.to_err_msg()); + fail!() + }, + }; + + let progname = args[0].clone(); + let usage = usage("Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.", opts); + let mode = if matches.opt_present("version") { + Version + } else if matches.opt_present("help") { + Help + } else { + Copy + }; + + match mode { + Copy => copy(matches), + Help => help(progname, usage), + Version => version(), + } +} + +fn version() { + println!("cp 1.0.0"); +} + +fn help(progname: &str, usage: &str) { + let msg = format!("Usage: {0} SOURCE DEST\n \ + or: {0} SOURCE... DIRECTORY\n \ + or: {0} -t DIRECTORY SOURCE\n\ + \n\ + {1}", progname, usage); + println!("{}", msg); +} + +fn copy(matches: getopts::Matches) { + let sources = if matches.free.len() < 1 { + error!("error: Missing SOURCE argument. Try --help."); + fail!() + } else { + // All but the last argument: + matches.free.slice(0, matches.free.len() - 2) + .map(|arg| ~Path::new(arg.clone())) + }; + let dest = if matches.free.len() < 2 { + error!("error: Missing DEST argument. Try --help."); + fail!() + } else { + // Only the last argument: + ~Path::new(matches.free[matches.free.len() - 1].clone()) + }; + + assert!(sources.len() >= 1); + + if sources.len() == 1 { + let source = sources[0].clone(); + let same_file = match paths_refer_to_same_file(source, dest) { + Ok(b) => b, + Err(e) => if e.kind == io::FileNotFound { + false + } else { + error!("error: {:s}", e.to_str()); + fail!() + } + }; + + if same_file { + error!("error: \"{:s}\" and \"{:s}\" are the same file", + source.display().to_str(), + dest.display().to_str()); + fail!(); + } + + let io_result = fs::copy(source, dest); + + if io_result.is_err() { + let err = io_result.unwrap_err(); + error!("error: {:s}", err.to_str()); + fail!(); + } + } else { + if fs::stat(dest).unwrap().kind != io::TypeDirectory { + error!("error: TARGET must be a directory"); + fail!(); + } + + for source in sources.iter() { + if fs::stat(*source).unwrap().kind != io::TypeFile { + error!("error: \"{:s}\" is not a file", source.display().to_str()); + continue; + } + + let mut full_dest = dest.clone(); + + full_dest.push(source.filename_str().unwrap()); + + println!("{:s}", full_dest.display().to_str()); + + let io_result = fs::copy(*source, full_dest); + + if io_result.is_err() { + let err = io_result.unwrap_err(); + error!("error: {:s}", err.to_str()); + fail!() + } + } + } +} + +pub fn paths_refer_to_same_file(p1: &Path, p2: &Path) -> io::IoResult { + let mut raw_p1 = ~p1.clone(); + let mut raw_p2 = ~p2.clone(); + + let p1_lstat = match fs::lstat(raw_p1) { + Ok(stat) => stat, + Err(e) => return Err(e), + }; + + let p2_lstat = match fs::lstat(raw_p2) { + Ok(stat) => stat, + Err(e) => return Err(e), + }; + + // We have to take symlinks and relative paths into account. + if p1_lstat.kind == io::TypeSymlink { + raw_p1 = ~fs::readlink(raw_p1).unwrap(); + } + raw_p1 = ~os::make_absolute(raw_p1); + + if p2_lstat.kind == io::TypeSymlink { + raw_p2 = ~fs::readlink(raw_p2).unwrap(); + } + raw_p2 = ~os::make_absolute(raw_p2); + + Ok(raw_p1 == raw_p2) +} diff --git a/tee/tee.rs b/tee/tee.rs index 43cf53894..16ab9fabe 100644 --- a/tee/tee.rs +++ b/tee/tee.rs @@ -1,5 +1,7 @@ #[crate_id(name="tee", vers="1.0.0", author="Aleksander Bielawski")]; #[license="MIT"]; +#[feature(phase)]; +#[feature(macro_rules)]; /* * This file is part of the uutils coreutils package. @@ -11,6 +13,7 @@ */ extern crate getopts; +#[phase(syntax, link)] extern crate log; use std::io::{println, stdin, stdout, Append, File, Truncate, Write}; use std::io::{IoResult};