]> err.no Git - sope/blob - relative_path.sh
2268a9fc91b947b147b5e058e2feed9739b7add8
[sope] / relative_path.sh
1 #!/bin/sh
2 # relative_path.sh
3 #
4 # Copyright (C) 2002 Free Software Foundation, Inc.
5 #
6 # Author: Nicola Pero <n.pero@mi.flashnet.it>
7 # Date: April 2001
8 #
9 # This file is part of the GNUstep Makefile Package.
10 #
11 # This library is free software; you can redistribute it and/or
12 # modify it under the terms of the GNU General Public License
13 # as published by the Free Software Foundation; either version 2
14 # of the License, or (at your option) any later version.
15
16 # You should have received a copy of the GNU General Public
17 # License along with this library; see the file COPYING.LIB.
18 # If not, write to the Free Software Foundation,
19 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21 # This script gets two paths as argument - and outputs a relative path
22 # which, when appended to the first one, gives the second one ... more
23 # precisely, the path of minimum length with this property.
24 #
25 # <NB: the paths must be absolute.>
26 #
27 # for example,
28 #
29 # $GNUSTEP_MAKEFILES/relative_path.sh /usr/GNUstep/Local /usr/GNUstep/System
30 #
31 # returns ../System (and not ../../GNUstep/System which is not the minimum).
32 #
33 # This is needed by `ln -s' to properly create symlinks between
34 # directories which are related ... but we don't know how.  We only
35 # need this for frameworks, which are particularly complex and
36 # delicate.  For example, to create the link
37 #
38 # /usr/GNUstep/System/Library/Libraries/ix86/linux-gnu/gnu-gnu-gnu/libnicola.so
39 #   --> ../../../../Frameworks/nicola.framework/Versions/Current/ix86/linux-gnu/gnu-gnu-gnu/libnicola.so
40 #
41 # (and where the paths are actually computed by make variables which
42 # might depend on variables in user makefiles outside our control, so
43 # it's not obvious what the relationship is between the two paths, and
44 # you only have the absolute paths) we do -
45 #
46 # cd /usr/GNUstep/System/Library/Libraries/ix86/linux-gnu/gnu-gnu-gnu/
47 # $(LN_S) `$(RELATIVE_PATH_SCRIPT) /usr/GNUstep/System/Frameworks/nicola.framework/Versions/Current/ix86/linux-gnu/gnu-gnu-gnu/libnicola.so /usr/GNUstep/System/Library/Libraries/ix86/linux-gnu/gnu-gnu-gnu/` libnicola.so
48 #
49 # which creates the link.  We need to use the minimum path because
50 # that is the most relocatable possible path.  I consider all this a
51 # trick and a hack and recommend to use libraries and bundles instead
52 # of frameworks, since libraries and bundles are much more portable
53 # and stable, anyway here we are.
54 #
55
56
57 if [ "$#" != 2 ]; then
58   exit 1
59 fi
60
61 a="$1";
62 b="$2";
63
64 if [ "$a" = "" ]; then
65   exit 1
66 fi
67
68 if [ "$b" = "" ]; then
69   exit 1
70 fi
71
72
73 #
74 # Our first argument is a path like /xxx/yyy/zzz/ccc/ttt
75 # Our second argument is a path like /xxx/yyy/kkk/nnn/ppp
76 #
77
78 # Step zero is normalizing the paths by removing any /./ component
79 # inside the given paths (these components can occur for example when
80 # enable-flattened is used).
81 tmp_IFS="$IFS"
82 IFS=/
83
84 # Normalize a by removing any '.' path component.
85 normalized_a=""
86 for component in $a; do
87   if [ -n "$component" ]; then
88     if [ "$component" != "." ]; then
89       normalized_a="$normalized_a/$component"
90     fi
91   fi
92 done
93 a="$normalized_a"
94
95 # Normalize b by removing any '.' path component.
96 normalized_b=""
97 for component in $b; do
98   if [ -n "$component" ]; then
99     if [ "$component" != "." ]; then
100       normalized_b="$normalized_b/$component"
101     fi
102   fi
103 done
104 b="$normalized_b"
105
106 IFS="$tmp_IFS"
107
108
109
110 # Step one: we first want to remove the common root -- we want to get
111 # into having /zzz/ccc/tt and /kkk/nnn/ppp.
112
113 # We first try to match as much as possible between the first and the second
114 # So we loop on the fields in the second.  The common root must not contain
115 # empty path components (/./) for this to work, but we have already filtered
116 # those out at step zero.
117 tmp_IFS="$IFS"
118 IFS=/
119 partial_b=""
120 partial_match=""
121 for component in $b; do
122   if [ -n "$component" ]; then
123     partial_b="$partial_b/$component"
124     case "$a" in
125       "$partial_b"*) partial_match="$partial_b";;
126       *) break;;
127     esac
128   fi
129 done
130 IFS="$tmp_IFS"
131
132 if [ "$partial_match" != "" ]; then
133   # Now partial_match is the substring which matches (/xxx/yyy/) in the
134   # example.  Remove it from both a and b.
135   a=`echo $a | sed -e "s#$partial_match##"`
136   b=`echo $b | sed -e "s#$partial_match##"`
137 fi
138
139 # Ok - now ready to build the result
140 result=""
141
142 # First add as many ../ as there are components in a
143 tmp_IFS="$IFS"
144 IFS=/
145 for component in $a; do
146   if [ -n "$component" -a "$component" != "." ]; then
147     if [ -z "$result" ]; then
148       result=".."
149     else
150       result="$result/.."
151     fi
152   fi
153 done
154 IFS="$tmp_IFS"
155
156 # Then, append b
157 if [ -n "$result" ]; then
158   result="$result$b"
159 else
160   result="$b"
161 fi
162
163 echo "$result"