To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Revision:

root / vext @ 124:fc093b176444

History | View | Annotate | Download (3.9 KB)

1
#!/bin/bash
2

    
3
# Disable shellcheck warnings for useless-use-of-cat. UUOC is good
4
# practice, not bad: clearer, safer, less error-prone.
5
# shellcheck disable=SC2002
6

    
7
sml="$VEXT_SML"
8

    
9
set -eu
10

    
11
mydir=$(dirname "$0")
12
program="$mydir/vext.sml"
13

    
14
hasher=
15
local_install=
16
if [ -w "$mydir" ]; then
17
    if echo | sha256sum >/dev/null 2>&1 ; then
18
	hasher=sha256sum
19
        local_install=true
20
    elif echo | shasum >/dev/null 2>&1 ; then
21
	hasher=shasum
22
	local_install=true
23
    else
24
        echo "WARNING: sha256sum or shasum program not found" 1>&2
25
    fi
26
fi
27

    
28
if [ -n "$local_install" ]; then
29
    hash=$(echo "$sml" | cat "$program" - | $hasher | cut -c1-16)
30
    gen_sml=$mydir/.vext-$hash.sml
31
    gen_out=$mydir/.vext-$hash.bin
32
    trap 'rm -f $gen_sml' 0
33
else
34
    gen_sml=$(mktemp /tmp/vext-XXXXXXXX.sml)
35
    gen_out=$(mktemp /tmp/vext-XXXXXXXX.bin)
36
    trap 'rm -f $gen_sml $gen_out' 0
37
fi
38

    
39
if [ -x "$gen_out" ]; then
40
    exec "$gen_out" "$@"
41
fi
42

    
43
# We need one of Poly/ML, SML/NJ, or MLton. Since we're running a
44
# single-file SML program as if it were a script, our order of
45
# preference is based on startup speed, except in the local_install
46
# case where we retain a persistent binary.
47

    
48
if [ -z "$sml" ]; then
49
    if [ -n "$local_install" ] && mlton 2>&1 | grep -q 'MLton'; then
50
	sml="mlton"
51
    elif sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then
52
	sml="smlnj"
53
    # We would prefer Poly/ML to SML/NJ, except that Poly v5.7 has a
54
    # nasty bug that occasionally causes it to deadlock on startup.
55
    # That appears to be fixed in their repo, so we could promote it
56
    # up the order again at some point in future
57
    elif echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then
58
	sml="poly"
59
    elif mlton 2>&1 | grep -q 'MLton'; then
60
	sml="mlton"
61
    else cat 1>&2 <<EOF
62

    
63
ERROR: No supported SML compiler or interpreter found       
64
EOF
65
	cat 1>&2 <<EOF
66

    
67
  The Vext external source code manager needs a Standard ML (SML)
68
  compiler or interpreter to run.
69

    
70
  Please ensure you have one of the following SML implementations
71
  installed and present in your PATH, and try again.
72

    
73
    1. Standard ML of New Jersey
74
       - often found in a distribution package called: smlnj
75
       - executable name: sml
76

    
77
    2. Poly/ML
78
       - often found in a distribution package called: polyml
79
       - executable name: poly
80

    
81
    3. MLton
82
       - often found in a distribution package called: mlton
83
       - executable name: mlton
84

    
85
EOF
86
	exit 2
87
    fi
88
fi
89

    
90
arglist=""
91
for arg in "$@"; do
92
    if [ -n "$arglist" ]; then arglist="$arglist,"; fi
93
    if echo "$arg" | grep -q '["'"'"']' ; then
94
	arglist="$arglist\"usage\""
95
    else
96
	arglist="$arglist\"$arg\""
97
    fi
98
done
99

    
100
case "$sml" in
101
    poly)
102
        if [ -n "$local_install" ] && polyc --help >/dev/null 2>&1 ; then
103
            if [ ! -x "$gen_out" ]; then
104
                polyc -o "$gen_out" "$program"
105
            fi
106
	    "$gen_out" "$@"
107
        else
108
            echo 'use "'"$program"'"; vext ['"$arglist"'];' |
109
                poly -q --error-exit
110
        fi ;;
111
    mlton)
112
        if [ ! -x "$gen_out" ]; then
113
	    echo "[Precompiling Vext binary...]" 1>&2
114
	    echo "val _ = main ()" | cat "$program" - > "$gen_sml"
115
	    mlton -output "$gen_out" "$gen_sml"
116
        fi
117
	"$gen_out" "$@" ;;
118
    smlnj)
119
	cat "$program" | (
120
	    cat <<EOF
121
val smlrun__cp = 
122
    let val x = !Control.Print.out in
123
        Control.Print.out := { say = fn _ => (), flush = fn () => () };
124
        x
125
    end;
126
val smlrun__prev = ref "";
127
Control.Print.out := { 
128
    say = fn s => 
129
        (if String.isSubstring " Error" s
130
         then (Control.Print.out := smlrun__cp;
131
               (#say smlrun__cp) (!smlrun__prev);
132
               (#say smlrun__cp) s)
133
         else (smlrun__prev := s; ())),
134
    flush = fn s => ()
135
};
136
EOF
137
	    cat -
138
	    cat <<EOF
139
val _ = vext [$arglist];
140
val _ = OS.Process.exit (OS.Process.success);
141
EOF
142
            ) > "$gen_sml"
143
	CM_VERBOSE=false sml "$gen_sml" ;;
144
    *)
145
	echo "ERROR: Unknown SML implementation name: $sml" 1>&2;
146
	exit 2 ;;
147
esac
148