1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// This file is part of the uutils coreutils package.
//
// (c) Derek Chiang <derekchiang93@gmail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

#[macro_use]
extern crate uucore;

use std::path::Path;

static NAME: &str = "dirname";
static SYNTAX: &str = "[OPTION] NAME...";
static SUMMARY: &str = "strip last component from file name";
static LONG_HELP: &str = "
 Output each NAME with its last non-slash component and trailing slashes
 removed; if NAME contains no /'s, output '.' (meaning the current
 directory).
";

pub fn uumain(args: impl uucore::Args) -> i32 {
    let args = args.collect_str();

    let matches = app!(SYNTAX, SUMMARY, LONG_HELP)
        .optflag("z", "zero", "separate output with NUL rather than newline")
        .parse(args);

    let separator = if matches.opt_present("zero") {
        "\0"
    } else {
        "\n"
    };

    if !matches.free.is_empty() {
        for path in &matches.free {
            let p = Path::new(path);
            match p.parent() {
                Some(d) => {
                    if d.components().next() == None {
                        print!(".")
                    } else {
                        print!("{}", d.to_string_lossy());
                    }
                }
                None => {
                    if p.is_absolute() || path == "/" {
                        print!("/");
                    } else {
                        print!(".");
                    }
                }
            }
            print!("{}", separator);
        }
    } else {
        println!("{0}: missing operand", NAME);
        println!("Try '{0} --help' for more information.", NAME);
        return 1;
    }

    0
}