-
Notifications
You must be signed in to change notification settings - Fork 3
/
smlbuild-include.sh
151 lines (137 loc) · 3.86 KB
/
smlbuild-include.sh
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
#!/bin/bash
#
# Chris Cannam, 2015-2022. MIT licence
# Disable shellcheck warnings for useless-use-of-cat. UUOC is good
# practice, not bad: clearer, safer, less error-prone.
# shellcheck disable=SC2002
internal_debug=no
if [ -z "${SML_LIB:-}" ]; then
lib=/usr/lib/mlton/sml
if [ ! -d "$lib" ]; then
lib=/usr/local/lib/mlton/sml
fi
else
lib="$SML_LIB"
fi
canonicalise() {
local pre="$1"
local post=""
while [ "$pre" != "$post" ]; do
if [ -z "$post" ]; then post="$pre"; else pre="$post"; fi
post=$(echo "$post" | sed -e 's|[^/.][^/.]*/\.\./||g')
done
echo "$post" | sed -e 's|^./||' -e 's|//|/|g'
}
simplify() {
local path="$1"
simple=$(canonicalise "$path")
if [ "$internal_debug" = "yes" ]; then
echo "simplified \"$path\" to \"$simple\"" 1>&2
fi
if [ ! -f "$simple" ]; then
echo "*** Error: input file \"$simple\" not found" 1>&2
exit 1
fi
echo "$simple"
}
cat_mlb() {
local mlb=$(canonicalise "$1")
if [ ! -f "$mlb" ]; then exit 1; fi
local dir
dir=$(dirname "$mlb")
if [ "$internal_debug" = "yes" ]; then
echo "reading MLB file \"$mlb\":" 1>&2
fi
cat "$mlb" | while read -r line; do
if [ "$internal_debug" = "yes" ]; then
echo "read line \"$line\":" 1>&2
fi
local trimmed
# remove leading and trailing whitespace
trimmed="${line#"${line%%[![:space:]]*}"}"
trimmed="${trimmed%"${trimmed##*[![:space:]]}"}"
case "$trimmed" in
# check for ML-style comments or variable sigils; only
# launch a further substitution if we see any
*[\($]*)
# Tell shellcheck that the $-variables in
# single-quotes are not intended for bash to expand
# shellcheck disable=SC2016
trimmed=$(
echo "$trimmed" |
# remove ML-style comments; expand library path
sed -e 's|(\*.*\*)||' -e 's#$(SML_LIB)#'"${lib}"'#g' |
# expand other vars:
perl -p -e 's|\$\(([A-Za-z_-]+)\)|$ENV{$1}|'
)
;;
*) ;;
esac
local path="$trimmed"
case "$path" in
"") ;; # keep empty lines for ignoring later
/*) ;;
*) path="$dir/$trimmed" ;;
esac
case "$path" in
"") ;; # ignore empty lines
*basis.mlb) ;; # remove incompatible Basis lib
*mlton.mlb) ;; # remove incompatible MLton lib
*main.sml) ;; # remove redundant call to main
*.mlb) cat_mlb "$path" ;;
*.sml) simplify "$path" ;;
*.sig) simplify "$path" ;;
*) echo "*** Warning: unsupported syntax or file in $mlb: $trimmed" 1>&2
esac
done
if [ "$internal_debug" = "yes" ]; then
echo "finished reading MLB file \"$mlb\"" 1>&2
fi
}
expand_arg() {
local arg="$1"
local unique="no"
case "$arg" in
"-u") unique=yes
shift
arg="$1" ;;
*) ;;
esac
case "$arg" in
*.sml) echo "$arg" ;;
*.mlb) cat_mlb "$arg" ;;
*) echo "*** Error: .sml or .mlb file must be provided" 1>&2
exit 1 ;;
esac | (
if [ "$unique" = "yes" ]; then
cat -n | sort +1 -u | sort -n | awk '{ print $2; }'
else
cat
fi
)
}
get_base() {
local arg="$1"
case "$arg" in
*.sml) basename "$arg" .sml ;;
*.mlb) basename "$arg" .mlb ;;
*) echo "*** Error: .sml or .mlb file must be provided" 1>&2
exit 1 ;;
esac
}
get_outfile() {
local arg="$1"
canonicalise $(dirname "$arg")/$(get_base "$arg")
}
get_tmpfile() {
local arg="$1"
mktemp /tmp/smlbuild-$(get_base "$arg")-XXXXXXXX
}
get_tmpsmlfile() {
local arg="$1"
mktemp /tmp/smlbuild-$(get_base "$arg")-XXXXXXXX.sml
}
get_tmpobjfile() {
local arg="$1"
mktemp /tmp/smlbuild-$(get_base "$arg")-XXXXXXXX.o
}