Commit | Line | Data |
---|---|---|
e976486e DM |
1 | #!/bin/sh |
2 | # Take a list of MSYS-compatible paths and convert them to native | |
3 | # MS-Windows format. | |
4 | # Status is zero if successful, nonzero otherwise. | |
5 | ||
6 | # Copyright (C) 2013 Free Software Foundation, Inc. | |
7 | ||
8 | # This program is free software: you can redistribute it and/or modify | |
9 | # it under the terms of the GNU General Public License as published by | |
10 | # the Free Software Foundation, either version 3 of the License, or | |
11 | # (at your option) any later version. | |
12 | ||
13 | # This program is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | ||
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 | ||
21 | # Take only the basename from the full pathname | |
22 | me=${0//*\//} | |
23 | ||
24 | usage="usage: ${me} PATHLIST [MUSTEXIST] [SEPARATOR [SEPARATOR2]]" | |
25 | ||
26 | help="$usage | |
27 | or: ${me} OPTION | |
28 | ||
29 | Convert MSYS-compatible paths to MS-Windows native format. | |
30 | ||
31 | PATHLIST should be a list of paths separated by SEPARATOR. This list | |
32 | will be written to the standard output after performing the following | |
33 | transformations: | |
34 | 1. Discard empty paths. | |
35 | 2. Replace backslashes with forward slashes. | |
36 | 3. Replace two consecutive slashes with single ones. | |
37 | 4. Translate to Windows-native format those paths that are not in such | |
38 | format already. The translated paths will not end with a slash, | |
39 | except for root directories (e.g. 'c:/' or 'c:/foo'). | |
48a2a0b4 | 40 | 5. Escape with backslashes every occurrence of SEPARATOR2 within the paths. |
e976486e DM |
41 | 6. Concatenate the translated paths with SEPARATOR2. |
42 | ||
43 | If MUSTEXIST is 'Y' or not supplied, then each path in PATHLIST must | |
44 | exist. Otherwise, only some part of each path is required to exist | |
45 | (the deepest existing subpath will be translated and the remainder | |
46 | concatenated to the translation). | |
47 | ||
48 | If SEPARATOR is not supplied, PATHLIST will be regarded as a single | |
49 | path. | |
50 | ||
51 | If SEPARATOR2 is not supplied, it will take the same value as | |
52 | SEPARATOR. | |
53 | ||
54 | Options: | |
55 | --help display this help and exit | |
56 | ||
57 | Report bugs to <bug-gnu-emacs@gnu.org>." | |
58 | ||
59 | for arg | |
60 | do | |
61 | case $arg in | |
62 | --help | --hel | --he | --h) | |
63 | exec echo "$help" ;; | |
64 | --) | |
65 | shift | |
66 | break ;; | |
67 | -*) | |
68 | echo "${me}: invalid option: $arg" >&2 | |
69 | exit 1 ;; | |
70 | *) | |
71 | break ;; | |
72 | esac | |
73 | done | |
74 | ||
75 | { test $# -ge 1 && test $# -le 4; } || | |
76 | { echo "${me}: $usage" >&2; exit 1; } | |
77 | ||
78 | # Arguments | |
79 | pathlist="$1" | |
80 | mustexist="${2:-Y}" | |
81 | separator="$3" | |
82 | separator2="${4:-${separator}}" | |
83 | ||
84 | # Split pathlist into its path components | |
85 | if test -n "$separator" | |
86 | then | |
87 | IFS=${separator} patharray=( $pathlist ) | |
88 | else | |
89 | patharray=( "$pathlist" ) | |
90 | fi | |
91 | ||
92 | w32pathlist="" | |
93 | ||
94 | for p in "${patharray[@]}" | |
95 | do | |
96 | # Skip empty paths | |
97 | test "$p" = "" && continue | |
98 | ||
99 | # Replace '\' with '/' and '//' with '/' | |
100 | p="${p//\\//}" | |
101 | p="${p//\/\///}" | |
102 | ||
103 | if test -d "$p" | |
104 | then | |
105 | # The path exists, so just translate it | |
106 | w32p=`cd "$p" && pwd -W` | |
107 | else | |
108 | # The path does not exists. So, try to guess the | |
109 | # Windows-native translation, by looking for the deepest | |
110 | # existing directory in this path, and then translating the | |
111 | # existing part and concatenating the remainder. | |
112 | ||
113 | test "${mustexist}" = "Y" && | |
114 | { echo "${me}: invalid path: $p" >&2; exit 1; } | |
115 | ||
116 | p1=$p | |
117 | IFS=/ pcomponents=( $p ) | |
118 | ||
119 | for (( i=${#pcomponents[@]}-1 ; i>=0 ; i-- )) | |
120 | do | |
121 | ||
122 | if test "${pcomponents[i]}" = "" | |
123 | then | |
124 | # The path component is empty. This can only mean | |
125 | # that the path starts with "/" and all components | |
126 | # have been stripped out already. So in this case we | |
127 | # want to test with the MSYS root directory | |
128 | p1="/" | |
129 | else | |
130 | p1="${p1%/}" | |
131 | p1="${p1%${pcomponents[i]}}" | |
132 | fi | |
133 | ||
134 | if test -d "${p1}" | |
135 | then | |
136 | ||
137 | # Existing path found | |
138 | ||
139 | # Translate the existing part and concatenate the | |
140 | # remainder (ensuring that only one slash is used in | |
141 | # the join, and no trailing slash is left) | |
142 | w32p1=`cd "${p1}" && pwd -W` | |
143 | remainder="${p#${p1}}" | |
144 | remainder="${remainder#/}" | |
145 | remainder="${remainder%/}" | |
146 | w32p="${w32p1%/}/${remainder}" | |
147 | ||
148 | break | |
149 | fi | |
150 | ||
151 | done | |
152 | ||
153 | # If no existing directory was found, error out | |
154 | test -e "${p1}" || | |
155 | { echo "${me}: invalid path: ${p}" >&2; exit 1; } | |
156 | fi | |
157 | ||
158 | # Concatenate the translated path to the translated pathlist | |
159 | test "${w32pathlist}" = "" || w32pathlist="${w32pathlist}${separator2}" | |
160 | w32pathlist="${w32pathlist}${w32p//${separator2}/\\${separator2}}" | |
161 | ||
162 | done | |
163 | ||
164 | # Write the translated pathlist to the standard output | |
165 | printf "${w32pathlist}" |