diff options
author | rillig <rillig@pkgsrc.org> | 2006-11-09 14:36:18 +0000 |
---|---|---|
committer | rillig <rillig@pkgsrc.org> | 2006-11-09 14:36:18 +0000 |
commit | ffe459f4de4bf51af76d9a431a95d4e93f3265b0 (patch) | |
tree | 9456b7c6c68ec712d70952b440e8f7e63d64d901 /mk | |
parent | 343fc520f8ea1becfe212fe5c3b59e5aaa110845 (diff) | |
download | pkgsrc-ffe459f4de4bf51af76d9a431a95d4e93f3265b0.tar.gz |
Rewrote check-portability in awk instead of shell, since the shell has a
huge performance problem: When reading files, it calls read(2) for every
single byte. awk instead reads a whole line at a time. For the lang/php5
package, the execution time changed from (7.8 real 4.5 user 3.1 sys) to
(1.6 real 1.5 user 0.4 sys).
Diffstat (limited to 'mk')
-rw-r--r-- | mk/check/check-portability.awk | 78 | ||||
-rw-r--r-- | mk/check/check-portability.mk | 4 | ||||
-rw-r--r-- | mk/check/check-portability.sh | 87 | ||||
-rw-r--r-- | mk/check/check-subr.awk | 56 |
4 files changed, 147 insertions, 78 deletions
diff --git a/mk/check/check-portability.awk b/mk/check/check-portability.awk new file mode 100644 index 00000000000..853b1ca6ee2 --- /dev/null +++ b/mk/check/check-portability.awk @@ -0,0 +1,78 @@ +# $NetBSD: check-portability.awk,v 1.1 2006/11/09 14:36:18 rillig Exp $ + +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) { + + for (i = 3; i < NF; i++) { + if ($i == "==") { + if ($(i-2) == "test" || $(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); + } +} diff --git a/mk/check/check-portability.mk b/mk/check/check-portability.mk index 61676d0a8b2..418fa68c537 100644 --- a/mk/check/check-portability.mk +++ b/mk/check/check-portability.mk @@ -1,4 +1,4 @@ -# $NetBSD: check-portability.mk,v 1.1 2006/11/09 02:53:15 rillig Exp $ +# $NetBSD: check-portability.mk,v 1.2 2006/11/09 14:36:18 rillig Exp $ # # This file contains some checks that are applied to the configure # scripts to check for certain constructs that are known to cause @@ -46,5 +46,5 @@ _check-portability: [ -d ${WRKSRC}/. ] || exit 0; \ cd ${WRKSRC}; \ env PKGSRCDIR=${PKGSRCDIR:Q} \ - SKIP_FILTER=${CHECK_PORTABILITY_SKIP:@p@${p}) continue;;@:Q} \ + SKIP_FILTER=${CHECK_PORTABILITY_SKIP:@p@${p}) skip=yes;;@:Q} \ sh ${PKGSRCDIR}/mk/check/check-portability.sh diff --git a/mk/check/check-portability.sh b/mk/check/check-portability.sh index a7320e0daef..2db4fbbdbc5 100644 --- a/mk/check/check-portability.sh +++ b/mk/check/check-portability.sh @@ -1,4 +1,4 @@ -# $NetBSD: check-portability.sh,v 1.2 2006/11/09 10:52:21 rillig Exp $ +# $NetBSD: check-portability.sh,v 1.3 2006/11/09 14:36:18 rillig Exp $ # # This program checks the extracted files for portability issues that # are likely to result in false assumptions by the package. @@ -17,60 +17,22 @@ found_test_eqeq=no # 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. - # Note: this has the side-effect that the # in $# is also - # regarded as a comment. - 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*) - found_random=yes - cs_warning_heading "Found \$RANDOM:" - cs_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 - found_test_eqeq=yes - cs_error_heading "Found test ... == ...:" - cs_error_msg "$fname: $line" - fi - ;; - esac - shift - done - - done < "$1" + env \ + CK_FNAME="$1" \ + CK_PROGNAME="check-portability.awk" \ + awk -f "$PKGSRCDIR/mk/check/check-subr.awk" \ + -f "$PKGSRCDIR/mk/check/check-portability.awk" \ + < "$1" \ + || cs_exitcode=1 } find * -type f -print 2>/dev/null \ | { while read fname; do - eval "case \"\$fname\" in $SKIP_FILTER *.orig) continue;; esac" + skip=no + eval "case \"\$fname\" in $SKIP_FILTER *.orig) skip=yes;; esac" + [ $skip = no ] || continue read firstline < "$fname" || continue case "$firstline" in @@ -80,32 +42,5 @@ find * -type f -print 2>/dev/null \ esac done - if [ $found_random = yes ]; then - cs_explain <<EOF -The variable \$RANDOM is not required for a POSIX-conforming shell, and -many implementations of /bin/sh do not support it. It should therefore -not be used in shell programs that are meant to be portable across a -large number of POSIX-like systems. -EOF - fi - - if [ $found_test_eqeq = yes ]; then - cs_explain <<EOF -The "test" command, as well as the "[" command, are not required to know -the "==" operator. Only a few implementations like bash and some -versions of ksh support it. - -When you run "test foo == foo" on a platform that does not support the -"==" operator, the result will be "false" instead of "true". This can -lead to unexpected behavior. - -There are two ways to fix this error message. If the file that contains -the "test ==" is needed for building the package, you should create a -patch for it, replacing the "==" operator with "=". If the file is not -needed, add its name to the CHECK_PORTABILITY_SKIP variable in the -package Makefile. -EOF - fi - cs_exit } diff --git a/mk/check/check-subr.awk b/mk/check/check-subr.awk new file mode 100644 index 00000000000..c24bee41f06 --- /dev/null +++ b/mk/check/check-subr.awk @@ -0,0 +1,56 @@ +# $NetBSD: check-subr.awk,v 1.1 2006/11/09 14:36:18 rillig Exp $ +# +# This file contains shell functions that are used by the various awk +# programs that check things in pkgsrc. All these programs must be +# called with the following environment variables set: +# +# CK_FNAME +# The name of the file that is checked. Since awk interprets +# command line arguments in a weird way, the input file must be +# passed via stdin. +# +# CK_PROGNAME +# The program name to be used in diagnostic messages. +# + +BEGIN { + cs_exitcode = 0; + cs_fname = ENVIRON["CK_FNAME"]; + cs_progname = ENVIRON["CK_PROGNAME"]; + cs_last_heading = ""; + cs_hline = "========================="; + cs_hline = cs_hline cs_hline cs_hline; + no = 0; + yes = 1; +} + +function cs_error_heading(new_heading) { + if (new_heading != cs_last_heading) { + cs_last_heading = new_heading; + cs_error_msg("=> " new_heading); + } +} + +function cs_warning_heading(new_heading) { + if (new_heading != cs_last_heading) { + cs_last_heading = new_heading; + cs_warning_msg("=> " new_heading); + } +} + +function cs_error_msg(msg) { + printf("ERROR: [%s] %s\n", cs_progname, msg) > "/dev/stderr"; + cs_exitcode = 1; +} + +function cs_warning_msg(msg) { + printf("WARNING: [%s] %s\n", cs_progname, msg) > "/dev/stderr"; +} + +function cs_explain(msg) { + printf("\nExplanation:\n%s\n%s%s\n\n", cs_hline, msg, cs_hline) > "/dev/stderr"; +} + +function cs_exit() { + exit(cs_exitcode); +} |