summaryrefslogtreecommitdiff
path: root/mk/configure/check-portability.sh
blob: 59c2ea785aefccc07112c2e36510d6c15a8c0232 (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
# $NetBSD: check-portability.sh,v 1.2 2006/10/12 20:36:34 rillig Exp $
#
# This program checks the extracted files for portability issues that
# are likely to result in false assumptions by the package.
#
# The most prominent example is the "==" operator of test(1), which is
# only implemented by bash and some versions of the ksh.
#
# Note: because this program is run with the tools wrapper directory in
# the PATH, it calls the utilities by their base names. It also assumes
# to be interpreted by a POSIX-conforming shell.
#

set -eu

exitcode=0

last_heading=""

error_msg() {
	echo "ERROR: [check-portability.sh] $*" 1>&2
	exitcode=1
}

warning_msg() {
	echo "WARNING: [check-portability.sh] $*" 1>&2
}

error_heading() {
	if test "$1" != "$last_heading"; then
		last_heading="$1"
		error_msg "=> $1"
	fi
}

warning_heading() {
	if test "$1" != "$last_heading"; then
		last_heading="$1"
		warning_msg "=> $1"
	fi
}

# usage: check_shell <fname>
check_shell() {
	# See the end of the loop for the redirection.
	while read line; do

		# Note: This code does not find _all_ instances of
		# unportable code. If a single line contains an unsafe and
		# a safe usage of $RANDOM, it will pass the test.

		# Strip comments.
		line="${line%%#*}"

		# Check for $RANDOM, which is specific to ksh and bash.
		case "$line" in
		*"\$\$-\$RANDOM"* \
		| *"\$RANDOM-\$\$"* \
		| *"\$RANDOM"[A-Z_]*)
			# When $RANDOM is prefixed by the process ID, it
			# doesn't matter too much if $RANDOM is empty.
			# This code is often found in GNU configure scripts.
			;;

		*\$RANDOM*)
			warning_heading "Found \$RANDOM:"
			warning_msg "$fname: $line"
			;;
		esac

		#
		# Split the line into words and check them.
		#
		set args $line; shift
		while [ $# -ge 3 ]; do
			case "$1" in
			"test" | "[")
				if [ "==" = "$3" ]; then
					error_heading "Found test ... == ...:"
					error_msg "$fname: $line"
				fi
				;;
			esac
			shift
		done

	done < "$1"
}

find * -type f -print 2>/dev/null \
| {
	while read fname; do

		case "$fname" in
		*.orig)
			continue;;
		esac

		read firstline < "$fname" || continue
		case "$firstline" in
		"#!"*"/bin/sh")
			check_shell "$fname"
			;;
		esac
	done
	exit $exitcode
}