pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/mk/check Rewrote check-portability in awk instead of s...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/71330f76e171
branches:  trunk
changeset: 521328:71330f76e171
user:      rillig <rillig%pkgsrc.org@localhost>
date:      Thu Nov 09 14:36:18 2006 +0000

description:
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:

 mk/check/check-portability.awk |  78 +++++++++++++++++++++++++++++++++++++
 mk/check/check-portability.mk  |   4 +-
 mk/check/check-portability.sh  |  87 +++++------------------------------------
 mk/check/check-subr.awk        |  56 +++++++++++++++++++++++++++
 4 files changed, 147 insertions(+), 78 deletions(-)

diffs (271 lines):

diff -r 5e2d897f73aa -r 71330f76e171 mk/check/check-portability.awk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/mk/check/check-portability.awk    Thu Nov 09 14:36:18 2006 +0000
@@ -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 -r 5e2d897f73aa -r 71330f76e171 mk/check/check-portability.mk
--- a/mk/check/check-portability.mk     Thu Nov 09 13:45:33 2006 +0000
+++ b/mk/check/check-portability.mk     Thu Nov 09 14:36:18 2006 +0000
@@ -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 @@
        [ -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 -r 5e2d897f73aa -r 71330f76e171 mk/check/check-portability.sh
--- a/mk/check/check-portability.sh     Thu Nov 09 13:45:33 2006 +0000
+++ b/mk/check/check-portability.sh     Thu Nov 09 14:36:18 2006 +0000
@@ -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 @@
 
 # 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 @@
                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 -r 5e2d897f73aa -r 71330f76e171 mk/check/check-subr.awk
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/mk/check/check-subr.awk   Thu Nov 09 14:36:18 2006 +0000
@@ -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);
+}



Home | Main Index | Thread Index | Old Index