summaryrefslogtreecommitdiff
path: root/mk/check/check-portability.awk
blob: 277f0e6738809c993880a50f74f228e751724cf0 (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
# $NetBSD: check-portability.awk,v 1.9 2016/02/24 08:54:23 jklos Exp $
#
# Checks a shell file for possible portability problems.
#
# ENVIRONMENT
#	(See check-subr.awk)
#

BEGIN {
	found_random = no;
	found_test_eqeq = no;
}

# Check for $RANDOM, which is specific to ksh and bash.
function check_random(line) {

	# $RANDOM together with the PID is often found in GNU-style
	# configure scripts and is considered acceptable.
	if (line ~ /\$\$-\$RANDOM/ || line ~ /\$RANDOM-\$\$/) {
		# Assume that this is ok.

	} else if (line ~ /\$RANDOM[A-Z_]+/) {
		# That's ok, too.

	} else if (line ~ /\$RANDOM/) {
		found_random = yes;
		cs_warning_heading("Found $RANDOM:");
		cs_warning_msg(cs_fname ": " $0);
	}
}

function check_test_eqeq(line,  n, word, i) {

	if (length(line) == 0)
		return;
	n = split(line, word);
	for (i = 3; i < n; i++) {
		if (word[i] == "==") {
			if (word[i-2] == "test" || word[i-2] == "[") {
				found_test_eqeq = yes;
				cs_error_heading("Found test ... == ...:");
				cs_error_msg(cs_fname ": " $0);
			}
		}
	}
}

/./ {
	# 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 = $0;
	gsub(/^#.*/, "", line);
	gsub(/[[:space:]]#.*/, "", line);

	check_random(line);
	check_test_eqeq(line);
}

END {
	if (found_random) {
		h =   "The variable $RANDOM is not required for a POSIX-conforming shell, and\n";
		h = h "many implementations of /bin/sh do not support it. It should therefore\n";
		h = h "not be used in shell programs that are meant to be portable across a\n";
		h = h "large number of POSIX-like systems.\n"
		cs_explain(h);
	}

	if (found_test_eqeq) {
		h =   "The \"test\" command, as well as the \"[\" command, are not required to know\n";
		h = h "the \"==\" operator. Only a few implementations like bash and some\n";
		h = h "versions of ksh support it.\n";
		h = h "\n";
		h = h "When you run \"test foo == foo\" on a platform that does not support the\n";
		h = h "\"==\" operator, the result will be \"false\" instead of \"true\". This can\n";
		h = h "lead to unexpected behavior.\n";
		h = h "\n";
		h = h "There are two ways to fix this error message. If the file that contains\n";
		h = h "the \"test ==\" is needed for building the package, you should create a\n";
		h = h "patch for it, replacing the \"==\" operator with \"=\". If the file is not\n";
		h = h "needed, add its name to the CHECK_PORTABILITY_SKIP variable in the\n";
		h = h "package Makefile.\n";
		cs_explain(h);
	}

	cs_exit();
}