summaryrefslogtreecommitdiff
path: root/build-aux/msys-to-w32
blob: a8394d71b511dd4a07ba3a8d39c91553b371684b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/sh
# Take a list of MSYS-compatible paths and convert them to native
# MS-Windows format.
# Status is zero if successful, nonzero otherwise.

# Copyright (C) 2013-2015 Free Software Foundation, Inc.

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Take only the basename from the full pathname
me=${0//*\//}

usage="usage: ${me} PATHLIST [MUSTEXIST] [SEPARATOR [SEPARATOR2]]"

help="$usage
  or:  ${me} OPTION

Convert MSYS-compatible paths to MS-Windows native format.

PATHLIST should be a list of paths separated by SEPARATOR.  This list
will be written to the standard output after performing the following
transformations:
1. Discard empty paths.
2. Replace backslashes with forward slashes.
3. Replace two consecutive slashes with single ones.
4. Translate to Windows-native format those paths that are not in such
   format already. The translated paths will not end with a slash,
   except for root directories (e.g. 'c:/' or 'c:/foo').  Paths
   starting with '%emacs_dir%' will not be translated.
5. Escape with backslashes every occurrence of SEPARATOR2 within the paths.
6. Concatenate the translated paths with SEPARATOR2.

If MUSTEXIST is 'Y' or not supplied, then each path in PATHLIST must
exist.  Otherwise, only some part of each path is required to exist
(the deepest existing subpath will be translated and the remainder
concatenated to the translation).

If SEPARATOR is not supplied, PATHLIST will be regarded as a single
path.

If SEPARATOR2 is not supplied, it will take the same value as
SEPARATOR.

Options:
  --help     display this help and exit

Report bugs to <bug-gnu-emacs@gnu.org>."

for arg
do
  case $arg in
    --help | --hel | --he | --h)
      exec echo "$help" ;;
    --)
      shift
      break ;;
    -*)
      echo "${me}: invalid option: $arg" >&2
      exit 1 ;;
    *)
      break ;;
  esac
done

{ test $# -ge 1 && test $# -le 4; } ||
{ echo "${me}: $usage" >&2; exit 1; }

# Arguments
pathlist="$1"
mustexist="${2:-Y}"
separator="$3"
separator2="${4:-${separator}}"

# Split pathlist into its path components
if test -n "$separator"
then
    IFS=${separator} patharray=( $pathlist )
else
    patharray=( "$pathlist" )
fi

w32pathlist=""

for p in "${patharray[@]}"
do
    # Skip empty paths
    test "$p" = "" && continue

    # Replace '\' with '/' and '//' with '/'
    p="${p//\\//}"
    p="${p//\/\///}"

    if test "${p:0:11}" = "%emacs_dir%"
    then
	# Paths starting with "%emacs_dir%" will not be translated
	w32p=$p
    elif test -d "$p"
    then
	# The path exists, so just translate it
	w32p=`cd "$p" && pwd -W`
    else
	# The path does not exist.  So, try to guess the
	# Windows-native translation, by looking for the deepest
	# existing directory in this path, and then translating the
	# existing part and concatenating the remainder.

	test "${mustexist}" = "Y" &&
	{ echo "${me}: invalid path: $p" >&2; exit 1; }

	p1=$p
	IFS=/ pcomponents=( $p )

	for (( i=${#pcomponents[@]}-1 ; i>=0 ; i-- ))
	do

	    if test "${pcomponents[i]}" = ""
	    then
		# The path component is empty.  This can only mean
		# that the path starts with "/" and all components
		# have been stripped out already.  So in this case we
		# want to test with the MSYS root directory
		p1="/"
	    else
		p1="${p1%/}"
		p1="${p1%${pcomponents[i]}}"
	    fi

	    if test -d "${p1}"
	    then

		# Existing path found

		# Translate the existing part and concatenate the
		# remainder (ensuring that only one slash is used in
		# the join, and no trailing slash is left)
		w32p1=`cd "${p1}" && pwd -W`
		remainder="${p#${p1}}"
		remainder="${remainder#/}"
		remainder="${remainder%/}"
		w32p="${w32p1%/}/${remainder}"

		break
	    fi

	done

	# If no existing directory was found, error out
	test -e "${p1}" ||
	{ echo "${me}: invalid path: ${p}" >&2; exit 1; }
    fi

    # Concatenate the translated path to the translated pathlist
    test "${w32pathlist}" = "" || w32pathlist="${w32pathlist}${separator2}"
    w32pathlist="${w32pathlist}${w32p//${separator2}/\\${separator2}}"

done

# Write the translated pathlist to the standard output
printf "%s" "${w32pathlist}"