From 38362a0c634162e22ee3817ac344ac4cfa07f437 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 17 Jun 2024 23:28:20 +0100 Subject: binutils/testsuite: Add a helper for relative path construction 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(+) diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp index ebc4c73..5bfcde5 100644 --- a/binutils/testsuite/lib/binutils-common.exp +++ b/binutils/testsuite/lib/binutils-common.exp @@ -481,6 +481,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. # -- cgit v1.1