Chris@1808
|
1 #!/bin/bash
|
Chris@1808
|
2
|
Chris@1808
|
3 # Disable shellcheck warnings for useless-use-of-cat. UUOC is good
|
Chris@1808
|
4 # practice, not bad: clearer, safer, less error-prone.
|
Chris@1808
|
5 # shellcheck disable=SC2002
|
Chris@1808
|
6
|
Chris@1808
|
7 sml="$REPOINT_SML"
|
Chris@1808
|
8
|
Chris@1808
|
9 set -eu
|
Chris@1808
|
10
|
Chris@1808
|
11 # avoid gussying up output
|
Chris@1808
|
12 export HGPLAIN=true
|
Chris@1808
|
13
|
Chris@1808
|
14 mydir=$(dirname "$0")
|
Chris@1808
|
15 program="$mydir/repoint.sml"
|
Chris@1808
|
16
|
Chris@1808
|
17 hasher=
|
Chris@1808
|
18 local_install=
|
Chris@1808
|
19 if [ -w "$mydir" ]; then
|
Chris@1808
|
20 if echo | sha256sum >/dev/null 2>&1 ; then
|
Chris@1808
|
21 hasher=sha256sum
|
Chris@1808
|
22 local_install=true
|
Chris@1808
|
23 elif echo | shasum >/dev/null 2>&1 ; then
|
Chris@1808
|
24 hasher=shasum
|
Chris@1808
|
25 local_install=true
|
Chris@1808
|
26 else
|
Chris@1808
|
27 echo "WARNING: sha256sum or shasum program not found" 1>&2
|
Chris@1808
|
28 fi
|
Chris@1808
|
29 fi
|
Chris@1808
|
30
|
Chris@1808
|
31 if [ -n "$local_install" ]; then
|
Chris@1808
|
32 hash=$(echo "$sml" | cat "$program" - | $hasher | cut -c1-16)
|
Chris@1808
|
33 gen_sml=$mydir/.repoint-$hash.sml
|
Chris@1808
|
34 gen_out=$mydir/.repoint-$hash.bin
|
Chris@1808
|
35 trap 'rm -f $gen_sml' 0
|
Chris@1808
|
36 else
|
Chris@1808
|
37 gen_sml=$(mktemp /tmp/repoint-XXXXXXXX.sml)
|
Chris@1808
|
38 gen_out=$(mktemp /tmp/repoint-XXXXXXXX.bin)
|
Chris@1808
|
39 trap 'rm -f $gen_sml $gen_out' 0
|
Chris@1808
|
40 fi
|
Chris@1808
|
41
|
Chris@1808
|
42 if [ -x "$gen_out" ]; then
|
Chris@1808
|
43 exec "$gen_out" "$@"
|
Chris@1808
|
44 fi
|
Chris@1808
|
45
|
Chris@1808
|
46 # We need one of Poly/ML, SML/NJ, MLton, or MLKit. Since we're running
|
Chris@1808
|
47 # a single-file SML program as if it were a script, our order of
|
Chris@1808
|
48 # preference is usually based on startup speed. An exception is the
|
Chris@1808
|
49 # local_install case, where we retain a persistent binary
|
Chris@1808
|
50
|
Chris@1808
|
51 if [ -z "$sml" ]; then
|
Chris@1808
|
52 if [ -n "$local_install" ] && mlton 2>&1 | grep -q 'MLton'; then
|
Chris@1808
|
53 sml="mlton"
|
Chris@1808
|
54 elif sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then
|
Chris@1808
|
55 sml="smlnj"
|
Chris@1808
|
56 # We would prefer Poly/ML to SML/NJ, except that Poly v5.7 has a
|
Chris@1808
|
57 # nasty bug that occasionally causes it to deadlock on startup.
|
Chris@1808
|
58 # That is fixed in v5.7.1, so we could promote it up the order
|
Chris@1808
|
59 # again at some point in future
|
Chris@1808
|
60 elif echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then
|
Chris@1808
|
61 sml="poly"
|
Chris@1808
|
62 elif mlton 2>&1 | grep -q 'MLton'; then
|
Chris@1808
|
63 sml="mlton"
|
Chris@1808
|
64 # MLKit is at the bottom because it leaves compiled files around
|
Chris@1808
|
65 # in an MLB subdir in the current directory
|
Chris@1808
|
66 elif mlkit 2>&1 | grep -q 'MLKit'; then
|
Chris@1808
|
67 sml="mlkit"
|
Chris@1808
|
68 else cat 1>&2 <<EOF
|
Chris@1808
|
69
|
Chris@1808
|
70 ERROR: No supported SML compiler or interpreter found
|
Chris@1808
|
71 EOF
|
Chris@1808
|
72 cat 1>&2 <<EOF
|
Chris@1808
|
73
|
Chris@1808
|
74 The Repoint external source code manager needs a Standard ML (SML)
|
Chris@1808
|
75 compiler or interpreter to run.
|
Chris@1808
|
76
|
Chris@1808
|
77 Please ensure you have one of the following SML implementations
|
Chris@1808
|
78 installed and present in your PATH, and try again.
|
Chris@1808
|
79
|
Chris@1808
|
80 1. Standard ML of New Jersey
|
Chris@1808
|
81 - may be found in a distribution package called: smlnj
|
Chris@1808
|
82 - executable name: sml
|
Chris@1808
|
83
|
Chris@1808
|
84 2. Poly/ML
|
Chris@1808
|
85 - may be found in a distribution package called: polyml
|
Chris@1808
|
86 - executable name: poly
|
Chris@1808
|
87
|
Chris@1808
|
88 3. MLton
|
Chris@1808
|
89 - may be found in a distribution package called: mlton
|
Chris@1808
|
90 - executable name: mlton
|
Chris@1808
|
91
|
Chris@1808
|
92 4. MLKit
|
Chris@1808
|
93 - may be found in a distribution package called: mlkit
|
Chris@1808
|
94 - executable name: mlkit
|
Chris@1808
|
95
|
Chris@1808
|
96 EOF
|
Chris@1808
|
97 exit 2
|
Chris@1808
|
98 fi
|
Chris@1808
|
99 fi
|
Chris@1808
|
100
|
Chris@1808
|
101 arglist=""
|
Chris@1808
|
102 for arg in "$@"; do
|
Chris@1808
|
103 if [ -n "$arglist" ]; then arglist="$arglist,"; fi
|
Chris@1808
|
104 if echo "$arg" | grep -q '["'"'"']' ; then
|
Chris@1808
|
105 arglist="$arglist\"usage\""
|
Chris@1808
|
106 else
|
Chris@1808
|
107 arglist="$arglist\"$arg\""
|
Chris@1808
|
108 fi
|
Chris@1808
|
109 done
|
Chris@1808
|
110
|
Chris@1808
|
111 case "$sml" in
|
Chris@1808
|
112 poly)
|
Chris@1808
|
113 if [ -n "$local_install" ] && polyc --help >/dev/null 2>&1 ; then
|
Chris@1808
|
114 if [ ! -x "$gen_out" ]; then
|
Chris@1808
|
115 polyc -o "$gen_out" "$program"
|
Chris@1808
|
116 fi
|
Chris@1808
|
117 "$gen_out" "$@"
|
Chris@1808
|
118 else
|
Chris@1808
|
119 echo 'use "'"$program"'"; repoint ['"$arglist"'];' |
|
Chris@1808
|
120 poly -q --error-exit
|
Chris@1808
|
121 fi ;;
|
Chris@1808
|
122 mlton)
|
Chris@1808
|
123 if [ ! -x "$gen_out" ]; then
|
Chris@1808
|
124 echo "[Precompiling Repoint binary...]" 1>&2
|
Chris@1808
|
125 echo "val _ = main ()" | cat "$program" - > "$gen_sml"
|
Chris@1808
|
126 mlton -output "$gen_out" "$gen_sml"
|
Chris@1808
|
127 fi
|
Chris@1808
|
128 "$gen_out" "$@" ;;
|
Chris@1808
|
129 mlkit)
|
Chris@1808
|
130 if [ ! -x "$gen_out" ]; then
|
Chris@1808
|
131 echo "[Precompiling Repoint binary...]" 1>&2
|
Chris@1808
|
132 echo "val _ = main ()" | cat "$program" - > "$gen_sml"
|
Chris@1808
|
133 mlkit -output "$gen_out" "$gen_sml"
|
Chris@1808
|
134 fi
|
Chris@1808
|
135 "$gen_out" "$@" ;;
|
Chris@1808
|
136 smlnj)
|
Chris@1808
|
137 cat "$program" | (
|
Chris@1808
|
138 cat <<EOF
|
Chris@1808
|
139 val smlrun__cp =
|
Chris@1808
|
140 let val x = !Control.Print.out in
|
Chris@1808
|
141 Control.Print.out := { say = fn _ => (), flush = fn () => () };
|
Chris@1808
|
142 x
|
Chris@1808
|
143 end;
|
Chris@1808
|
144 val smlrun__prev = ref "";
|
Chris@1808
|
145 Control.Print.out := {
|
Chris@1808
|
146 say = fn s =>
|
Chris@1808
|
147 (if String.isSubstring " Error" s
|
Chris@1808
|
148 then (Control.Print.out := smlrun__cp;
|
Chris@1808
|
149 (#say smlrun__cp) (!smlrun__prev);
|
Chris@1808
|
150 (#say smlrun__cp) s)
|
Chris@1808
|
151 else (smlrun__prev := s; ())),
|
Chris@1808
|
152 flush = fn s => ()
|
Chris@1808
|
153 };
|
Chris@1808
|
154 EOF
|
Chris@1808
|
155 cat -
|
Chris@1808
|
156 cat <<EOF
|
Chris@1808
|
157 val _ = repoint [$arglist];
|
Chris@1808
|
158 val _ = OS.Process.exit (OS.Process.success);
|
Chris@1808
|
159 EOF
|
Chris@1808
|
160 ) > "$gen_sml"
|
Chris@1808
|
161 CM_VERBOSE=false sml "$gen_sml" ;;
|
Chris@1808
|
162 *)
|
Chris@1808
|
163 echo "ERROR: Unknown SML implementation name: $sml" 1>&2;
|
Chris@1808
|
164 exit 2 ;;
|
Chris@1808
|
165 esac
|
Chris@1808
|
166
|