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

Fix basename when trailing slashes are present.

The GNU implementation first strips all trailing slashes before deleting
the directory portion. This case wasn't handled.

I also rewrote the method that strips the directory to use the PathBuf
methods for improved platform-indepedence.
This commit is contained in:
Joseph Crail 2015-05-09 13:23:48 -04:00
parent 39de3f7b71
commit 3abf19a595

View file

@ -13,8 +13,8 @@
extern crate getopts; extern crate getopts;
extern crate libc; extern crate libc;
use std::borrow::ToOwned;
use std::io::Write; use std::io::Write;
use std::path::{is_separator, PathBuf};
#[path = "../common/util.rs"] #[path = "../common/util.rs"]
#[macro_use] #[macro_use]
@ -24,7 +24,7 @@ static NAME: &'static str = "basename";
static VERSION: &'static str = "1.0.0"; static VERSION: &'static str = "1.0.0";
pub fn uumain(args: Vec<String>) -> i32 { pub fn uumain(args: Vec<String>) -> i32 {
let program = strip_dir(args[0].as_ref()); let program = strip_dir(&args[0]);
// //
// Argument parsing // Argument parsing
@ -72,9 +72,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
// Main Program Processing // Main Program Processing
// //
let fullname = &args[1]; let mut name = strip_dir(&args[1]);
let mut name = strip_dir(fullname.as_ref());
if args.len() > 2 { if args.len() > 2 {
let suffix = args[2].clone(); let suffix = args[2].clone();
@ -87,26 +85,28 @@ pub fn uumain(args: Vec<String>) -> i32 {
} }
fn strip_dir(fullname: &str) -> String { fn strip_dir(fullname: &str) -> String {
let mut name = String::new(); // Remove all platform-specific path separators from the end
let mut path: String = fullname.chars().rev().skip_while(|&ch| is_separator(ch)).collect();
for c in fullname.chars().rev() { // Undo reverse
if c == '/' || c == '\\' { path = path.chars().rev().collect();
break;
} // Convert to path buffer and get last path component
name.push(c); let pb = PathBuf::from(path);
match pb.components().last() {
Some(c) => c.as_os_str().to_str().unwrap().to_string(),
None => "".to_string()
} }
name.chars().rev().collect()
} }
fn strip_suffix(name: &str, suffix: &str) -> String { fn strip_suffix(name: &str, suffix: &str) -> String {
if name == suffix { if name == suffix {
return name.to_owned(); return name.to_string();
} }
if name.ends_with(suffix) { if name.ends_with(suffix) {
return name[..name.len() - suffix.len()].to_owned(); return name[..name.len() - suffix.len()].to_string();
} }
name.to_owned() name.to_string()
} }