[1/3] binutils/testsuite: Add a helper for relative path construction

Message ID alpine.DEB.2.21.2406111128380.9248@angie.orcam.me.uk
State New
Headers
Series GAS/testsuite: Make sure none.s is not overwritten |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Test passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Maciej W. Rozycki June 11, 2024, 11:51 a.m. UTC
  From: Maciej W. Rozycki <macro@redhat.com>

Implement a helper to construct a relative path between two locations in 
the filesystem, for example to make a path from the source to the object 
directory for the case where a tool has been set up to look at a given 
path and there is a need to point it elsewhere, but an absolute path 
will not work.  The helper works on normalized paths internally, so the 
result is correct even in the presence of symlinks as intermediate path 
components.

So given "/path/to/src/gas/testsuite/gas/all" as the FROM argument and 
then "/path/to/obj/gas/testsuite/tmpdir/none.s" as the TO argument the 
helper will return "../../../../../obj/gas/testsuite/tmpdir/none.s" in 
the absence of symlinks.
---
 binutils/testsuite/lib/binutils-common.exp |   32 +++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

binutils-test-binutils-get-relative-path.diff
  

Patch

Index: binutils-gdb/binutils/testsuite/lib/binutils-common.exp
===================================================================
--- binutils-gdb.orig/binutils/testsuite/lib/binutils-common.exp
+++ binutils-gdb/binutils/testsuite/lib/binutils-common.exp
@@ -480,6 +480,38 @@  proc supports_dt_relr {} {
     return 0
 }
 
+# get_relative_path FROM TO
+#
+# Return a relative path to TO starting from FROM, which is usually
+# supposed to be a directory.  The result is optimised in that both
+# paths are normalized and any leading part shared between the two
+# discarded, and then a suitable number of "../" elements prepended
+# to the remaining part of TO to get to the point of divergence from
+# FROM.
+
+proc get_relative_path { from to } {
+    set split_from [file split [file normalize $from]]
+    set split_to [file split [file normalize [file dirname $to]]]
+    set from_len [llength $split_from]
+    set to_len [llength $split_to]
+    set len [expr { $to_len < $from_len } ? $to_len : $from_len]
+    set relative_path {}
+
+    for { set i 0 } { $i < $len } { incr i } {
+	if { ![string equal [lindex $split_from $i] [lindex $split_to $i]] } {
+	    break
+	}
+    }
+    for { set j $i } { $j < $from_len } { incr j } {
+	lappend relative_path ".."
+    }
+    for { set j $i } { $j < $to_len } { incr j } {
+	lappend relative_path [lindex $split_to $j]
+    }
+
+    return [eval file join $relative_path [file tail $to]]
+}
+
 # Compare two files line-by-line.  FILE_1 is the actual output and FILE_2
 # is the expected output.  Ignore blank lines in either file.
 #