remove cat warning, update makefile

This commit is contained in:
Nick Juszczak 2014-01-03 17:32:39 -06:00
parent d0c2896b16
commit fc1da5a691
4 changed files with 105 additions and 20 deletions

View file

@ -31,6 +31,7 @@ EXES := \
# Programs with usable tests
TEST_PROGS := \
cat \
mkdir \
TEST ?= $(TEST_PROGS)

View file

@ -86,6 +86,7 @@ pub enum NumberingMode {
}
static TAB: u8 = '\t' as u8;
#[allow(dead_code)]
static CR: u8 = '\r' as u8;
static LF: u8 = '\n' as u8;

View file

@ -1,6 +1,6 @@
#[crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")];
/*
/**
* This file is part of the uutils coreutils package.
*
* (c) Nicholas Juszczak <juszczakn@gmail.com>
@ -12,26 +12,29 @@
extern mod extra;
use std::os;
use std::io::stderr;
use std::io::{fs, result, stderr};
use std::num::strconv;
use extra::getopts::groups;
use std::io::fs;
static VERSION: &'static str = "1.0.0";
/**
* Handles option parsing
*/
fn main() {
let args: ~[~str] = os::args();
let opts: ~[groups::OptGroup] = ~[
// Linux-specific options
// groups::optflag("m", "mode", "set file mode"),
// Linux-specific options, not implemented
// groups::optflag("Z", "context", "set SELinux secutiry context" +
// " of each created directory to CTX"),
groups::optopt("m", "mode", "set file mode", "755"),
groups::optflag("p", "parents", "make parent directories as needed"),
groups::optflag("v", "verbose",
"print a message for each printed directory"),
groups::optflag("", "help", "display this help"),
groups::optflag("", "version", "display this version")
];
];
let matches = match groups::getopts(args.tail(), opts) {
Ok(m) => m,
@ -43,7 +46,7 @@ fn main() {
}
};
if matches.opt_present("help") {
if args.len() == 1 || matches.opt_present("help") {
print_help(opts);
return;
}
@ -51,10 +54,35 @@ fn main() {
println("mkdir v" + VERSION);
return;
}
let mut verbose_flag: bool = false;
if matches.opt_present("verbose") {
verbose_flag = true;
}
let mk_parents: bool = matches.opt_present("parents");
// Translate a ~str in octal form to u32, default to 755
// Not tested on Windows
let mode_match = matches.opts_str(&[~"mode"]);
let mode: u32 = if mode_match.is_some() {
let m: ~str = mode_match.unwrap();
let res = strconv::from_str_common(m, 8, false, false, false,
strconv::ExpNone,
false, false);
if res.is_some() {
res.unwrap()
} else {
writeln!(&mut stderr() as &mut Writer,
"Error: no mode given");
os::set_exit_status(1);
return;
}
} else {
0o755
};
let dirs: ~[~str] = matches.free;
mkdir(dirs, mk_parents);
exec(dirs, mk_parents, mode, verbose_flag);
}
fn print_help(opts: &[groups::OptGroup]) {
@ -65,27 +93,79 @@ fn print_help(opts: &[groups::OptGroup]) {
" if they do not exist", opts));
}
/* std::libc currently does not provide bindings for any bits
besides user bits, so might as well use octal for now.
See 'std::io::FilePermission',
'std::libc::consts::os::posix88' for future updates */
fn mkdir(dirs: ~[~str], mk_parents: bool) {
let default: u32 = 0o755;
/**
* Create the list of new directories
*/
fn exec(dirs: ~[~str], mk_parents: bool, mode: u32, verbose: bool) {
let mut parent_dirs: ~[~str] = ~[];
for dir in dirs.iter() {
let path = Path::new((*dir).clone());
// Recursively create parent dirs as needed
// Build list of parent dirs which need to be created
if mk_parents {
match path.dirname_str() {
Some(p) => if p != "." {
mkdir(~[p.into_owned()], mk_parents)
parent_dirs.push(p.into_owned())
},
None => ()
}
}
if !path.exists() {
println(*dir);
fs::mkdir(&path, default);
}
// Recursively build parent dirs that are needed
if !parent_dirs.is_empty() {
exec(parent_dirs, mk_parents, mode, verbose);
}
for dir in dirs.iter() {
let path = Path::new((*dir).clone());
// Determine if parent directory to the one to
// be created exists
let parent: &str = match path.dirname_str() {
Some(p) => p,
None => ""
};
let parent_exists:bool = Path::new(parent).exists();
if parent_exists && !path.exists() {
// if mkdir failed return
if !mkdir(&path, mode) {return;}
if verbose {println(*dir);}
} else {
let mut error_msg: ~str = ~"";
if !parent_exists {
error_msg.push_str("Error: parent directory '");
error_msg.push_str(parent);
error_msg.push_str("' does not exist");
} else {
error_msg.push_str("Error: directory '");
error_msg.push_str(*dir);
error_msg.push_str("' already exists");
}
writeln!(&mut stderr() as &mut Writer,
"{}", error_msg);
}
}
}
/**
* Wrapper to catch errors, return false if failed
*/
fn mkdir(path: &Path, mode: u32) -> bool {
match result(|| fs::mkdir(path, mode)) {
Ok(_) => true,
Err(e) => {
writeln!(&mut stderr() as &mut Writer,
"mkdir: test {}", e.to_str());
os::set_exit_status(1);
false
}
}
}
// #[test]
// fn create_dir() {
// let test_dir = "mkdir_test_dir";
// let path: Path = Path::new(test_dir);
// let mode: u32 = 0x755;
// let result = mkdir(&path, mode);
// fs::rmdir(&path);
// assert_eq!(true, result);
// }

3
mkdir/test.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
}