Add files from parent branch HEAD:
[pkgsrc.git] / mk / check / check-portability.awk
1 # $NetBSD: check-portability.awk,v 1.3 2006/11/10 08:17:06 rillig Exp $
2 #
3 # Checks a shell file for possible portability problems.
4 #
5 # ENVIRONMENT
6 #       (See check-subr.awk)
7 #
8
9 BEGIN {
10         found_random = no;
11         found_test_eqeq = no;
12 }
13
14 # Check for $RANDOM, which is specific to ksh and bash.
15 function check_random(line) {
16
17         # $RANDOM together with the PID is often found in GNU-style
18         # configure scripts and is considered acceptable.
19         if (line ~ /\$\$-\$RANDOM/ || line ~ /\$RANDOM-\$\$/) {
20                 # Assume that this is ok.
21
22         } else if (line ~ /\$RANDOM[A-Z_]+/) {
23                 # That's ok, too.
24
25         } else if (line ~ /\$RANDOM/) {
26                 found_random = yes;
27                 cs_warning_heading("Found $RANDOM:");
28                 cs_warning_msg(cs_fname ": " $0);
29         }
30 }
31
32 function check_test_eqeq(line,  n, word, i) {
33
34         n = split(line, word);
35         for (i = 3; i < n; i++) {
36                 if (word[i] == "==") {
37                         if (word[i-2] == "test" || word[i-2] == "[") {
38                                 found_test_eqeq = yes;
39                                 cs_error_heading("Found test ... == ...:");
40                                 cs_error_msg(cs_fname ": " $0);
41                         }
42                 }
43         }
44 }
45
46 /./ {
47         # Note: This code does not find _all_ instances of
48         # unportable code. If a single line contains an unsafe and
49         # a safe usage of $RANDOM, it will pass the test.
50
51         # Strip comments
52         line = $0;
53         gsub(/^#.*/, "", line);
54         gsub(/[[:space:]]#.*/, "", line);
55
56         check_random(line);
57         check_test_eqeq(line);
58 }
59
60 END {
61         if (found_random) {
62                 h =   "The variable $RANDOM is not required for a POSIX-conforming shell, and\n";
63                 h = h "many implementations of /bin/sh do not support it. It should therefore\n";
64                 h = h "not be used in shell programs that are meant to be portable across a\n";
65                 h = h "large number of POSIX-like systems.\n"
66                 cs_explain(h);
67         }
68
69         if (found_test_eqeq) {
70                 h =   "The \"test\" command, as well as the \"[\" command, are not required to know\n";
71                 h = h "the \"==\" operator. Only a few implementations like bash and some\n";
72                 h = h "versions of ksh support it.\n";
73                 h = h "\n";
74                 h = h "When you run \"test foo == foo\" on a platform that does not support the\n";
75                 h = h "\"==\" operator, the result will be \"false\" instead of \"true\". This can\n";
76                 h = h "lead to unexpected behavior.\n";
77                 h = h "\n";
78                 h = h "There are two ways to fix this error message. If the file that contains\n";
79                 h = h "the \"test ==\" is needed for building the package, you should create a\n";
80                 h = h "patch for it, replacing the \"==\" operator with \"=\". If the file is not\n";
81                 h = h "needed, add its name to the CHECK_PORTABILITY_SKIP variable in the\n";
82                 h = h "package Makefile.\n";
83                 cs_explain(h);
84         }
85
86         cs_exit();
87 }