10
10
11
11
mod parser;
12
12
13
- use clap:: { App , AppSettings } ;
13
+ use clap:: { crate_version , App , AppSettings } ;
14
14
use parser:: { parse, Symbol } ;
15
15
use std:: ffi:: { OsStr , OsString } ;
16
16
use std:: path:: Path ;
17
17
use uucore:: executable;
18
18
19
+ const USAGE : & str = "test EXPRESSION
20
+ or: test
21
+ or: [ EXPRESSION ]
22
+ or: [ ]
23
+ or: [ OPTION" ;
24
+
25
+ // We use after_help so that this comes after the usage string (it would come before if we used about)
26
+ const AFTER_HELP : & str = "
27
+ Exit with the status determined by EXPRESSION.
28
+
29
+ An omitted EXPRESSION defaults to false. Otherwise,
30
+ EXPRESSION is true or false and sets exit status. It is one of:
31
+
32
+ ( EXPRESSION ) EXPRESSION is true
33
+ ! EXPRESSION EXPRESSION is false
34
+ EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true
35
+ EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true
36
+
37
+ -n STRING the length of STRING is nonzero
38
+ STRING equivalent to -n STRING
39
+ -z STRING the length of STRING is zero
40
+ STRING1 = STRING2 the strings are equal
41
+ STRING1 != STRING2 the strings are not equal
42
+
43
+ INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2
44
+ INTEGER1 -ge INTEGER2 INTEGER1 is greater than or equal to INTEGER2
45
+ INTEGER1 -gt INTEGER2 INTEGER1 is greater than INTEGER2
46
+ INTEGER1 -le INTEGER2 INTEGER1 is less than or equal to INTEGER2
47
+ INTEGER1 -lt INTEGER2 INTEGER1 is less than INTEGER2
48
+ INTEGER1 -ne INTEGER2 INTEGER1 is not equal to INTEGER2
49
+
50
+ FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers
51
+ FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2
52
+ FILE1 -ot FILE2 FILE1 is older than FILE2
53
+
54
+ -b FILE FILE exists and is block special
55
+ -c FILE FILE exists and is character special
56
+ -d FILE FILE exists and is a directory
57
+ -e FILE FILE exists
58
+ -f FILE FILE exists and is a regular file
59
+ -g FILE FILE exists and is set-group-ID
60
+ -G FILE FILE exists and is owned by the effective group ID
61
+ -h FILE FILE exists and is a symbolic link (same as -L)
62
+ -k FILE FILE exists and has its sticky bit set
63
+ -L FILE FILE exists and is a symbolic link (same as -h)
64
+ -N FILE FILE exists and has been modified since it was last read
65
+ -O FILE FILE exists and is owned by the effective user ID
66
+ -p FILE FILE exists and is a named pipe
67
+ -r FILE FILE exists and read permission is granted
68
+ -s FILE FILE exists and has a size greater than zero
69
+ -S FILE FILE exists and is a socket
70
+ -t FD file descriptor FD is opened on a terminal
71
+ -u FILE FILE exists and its set-user-ID bit is set
72
+ -w FILE FILE exists and write permission is granted
73
+ -x FILE FILE exists and execute (or search) permission is granted
74
+
75
+ Except for -h and -L, all FILE-related tests dereference symbolic links.
76
+ Beware that parentheses need to be escaped (e.g., by backslashes) for shells.
77
+ INTEGER may also be -l STRING, which evaluates to the length of STRING.
78
+
79
+ NOTE: Binary -a and -o are inherently ambiguous. Use 'test EXPR1 && test
80
+ EXPR2' or 'test EXPR1 || test EXPR2' instead.
81
+
82
+ NOTE: [ honors the --help and --version options, but test does not.
83
+ test treats each of those as it treats any other nonempty STRING.
84
+
85
+ NOTE: your shell may have its own version of test and/or [, which usually supersedes
86
+ the version described here. Please refer to your shell's documentation
87
+ for details about the options it supports." ;
88
+
19
89
pub fn uu_app ( ) -> App < ' static , ' static > {
20
90
App :: new ( executable ! ( ) )
21
91
. setting ( AppSettings :: DisableHelpFlags )
@@ -30,8 +100,22 @@ pub fn uumain(mut args: impl uucore::Args) -> i32 {
30
100
. to_string_lossy ( ) ;
31
101
let mut args: Vec < _ > = args. collect ( ) ;
32
102
33
- // If invoked via name '[', matching ']' must be in the last arg
34
- if binary_name == "[" {
103
+ if binary_name. ends_with ( '[' ) {
104
+ // If invoked as [ we should recognize --help and --version (but not -h or -v)
105
+ if args. len ( ) == 1 && ( args[ 0 ] == "--help" || args[ 0 ] == "--version" ) {
106
+ // Let clap pretty-print help and version
107
+ App :: new ( binary_name)
108
+ . version ( crate_version ! ( ) )
109
+ . usage ( USAGE )
110
+ . after_help ( AFTER_HELP )
111
+ // Disable printing of -h and -v as valid alternatives for --help and --version,
112
+ // since we don't recognize -h and -v as help/version flags.
113
+ . setting ( AppSettings :: NeedsLongHelp )
114
+ . setting ( AppSettings :: NeedsLongVersion )
115
+ . get_matches_from ( std:: iter:: once ( program) . chain ( args. into_iter ( ) ) ) ;
116
+ return 0 ;
117
+ }
118
+ // If invoked via name '[', matching ']' must be in the last arg
35
119
let last = args. pop ( ) ;
36
120
if last != Some ( OsString :: from ( "]" ) ) {
37
121
eprintln ! ( "[: missing ']'" ) ;
0 commit comments