summaryrefslogtreecommitdiff
path: root/mk
diff options
context:
space:
mode:
authorrillig <rillig>2006-11-09 14:36:18 +0000
committerrillig <rillig>2006-11-09 14:36:18 +0000
commit67216b84d8930a27e1187d55c6992086c23297af (patch)
tree9456b7c6c68ec712d70952b440e8f7e63d64d901 /mk
parent1fe264c7888194748dbfd1b5da09bf63441614d6 (diff)
downloadpkgsrc-67216b84d8930a27e1187d55c6992086c23297af.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.awk78
-rw-r--r--mk/check/check-portability.mk4
-rw-r--r--mk/check/check-portability.sh87
-rw-r--r--mk/check/check-subr.awk56
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);
+}