* lib/utils.exp (which): Reimplement to more closely mimic the
authorBen Elliston <bje@gnu.org>
Mon, 21 Mar 2016 23:44:20 +0000 (10:44 +1100)
committerBen Elliston <bje@gnu.org>
Sun, 27 Mar 2016 19:02:12 +0000 (06:02 +1100)
behaviour of the UNIX which utility.
* testsuite/runtest.all/utils.test: Test proc which.

ChangeLog
lib/utils.exp
testsuite/runtest.all/utils.test

index a5609cd..0a13edf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-03-28  Ben Elliston  <bje@gnu.org>
+
+       * lib/utils.exp (which): Reimplement to more closely mimic the
+       behaviour of the UNIX which utility.
+       * testsuite/runtest.all/utils.test: Test proc which.
+
 2016-03-27  Ben Elliston  <bje@gnu.org>
 
        * lib/remote.exp (standard_wait): Append any trailing characters
index e2a5040..c61785c 100644 (file)
@@ -130,24 +130,34 @@ proc which { file } {
     # strip off any extraneous arguments (like flags to the compiler)
     set file [lindex $file 0]
 
-    # if it exists then the path must be OK
-    # ??? What if $file has no path and "." isn't in $PATH?
-    if {[file exists $file]} {
-       return $file
+    # if the filename has a path component, then the file must exist
+    if {[llength [file split $file]] > 1} {
+       verbose "Checking $file" 2
+       if {[file exists $file] && \
+               [file executable $file] && [file type $file] == "file"} {
+           verbose "file $file is executable and not a link" 2
+           return [file normalize $file]
+       } else {
+           return 0
+       }
     }
+
+    # Otherwise the file must exist in the PATH
     if {[info exists env(PATH)]} {
        set path [split $env(PATH) ":"]
     } else {
        return 0
     }
 
-    foreach i $path {
-       verbose "Checking against $i" 3
-       if {[file exists [file join $i $file]]} {
-           if {[file executable [file join $i $file]]} {
-               return [file join $i $file]
+    foreach dir $path {
+       verbose "Checking $dir for $file" 3
+       set filename [file join $dir $file]
+       if {[file exists $filename]} {
+           if {[file executable $filename] && [file type $filename] == "file"} {
+               verbose "file $filename is executable and not a link" 2
+               return $filename
            } else {
-               warning "[file join $i $file] exists but is not an executable"
+               warning "file $filename exists but is not executable or is a link"
            }
        }
     }
index c3e2f3c..de8c809 100644 (file)
@@ -101,7 +101,30 @@ if [info exists env(TESTRUN)] {
     untested "unsetenv, unset an environment variable"
 }
 
-# which file
+# Test 'which' using a relative path.
+#
+if {[which ./config.status] != 0} {
+  pass "which, relative path to config.status"
+} else {
+  fail "which, relative path to config.status"
+}
+
+# Test 'which' using an absolute path.
+#
+if {[which [file join $objdir config.status]] != 0} {
+  pass "which, absolute path to config.status"
+} else {
+  fail "which, absolute path to config.status"
+}
+
+# Test 'which make'.
+#
+if {[which make] != 0} {
+  pass "which, make"
+} else {
+  pass "which, make"
+}
+
 # grep args
 # diff file_1 file_2
 # runtest_file_p