Avoid difference in tr semantics between System V and BSD
authorBen Walton <bdwalton@gmail.com>
Mon, 28 Oct 2013 21:43:00 +0000 (21:43 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Oct 2013 17:38:23 +0000 (10:38 -0700)
Solaris' tr (both /usr/bin/ and /usr/xpg4/bin) uses the System V
semantics for tr whereby string1's length is truncated to the length
of string2 if string2 is shorter. The BSD semantics, as used by GNU tr
see string2 padded to the length of string1 using the final character
in string2. POSIX explicitly doesn't specify the correct behavior
here, making both equally valid.

This difference means that Solaris' native tr implementations produce
different results for tr ":\t\n" "\0" than GNU tr. This breaks a few
tests in t0008-ignores.sh.

Possible fixes for this are to make string2 be "\0\0\0" or "[\0*]".

Instead, use perl to perform these transliterations which means we
don't need to worry about the difference at all. Since we're replacing
tr with perl, we also use perl to replace the sed invocations used to
transform the files.

Replace four identical transforms with a function named
broken_c_unquote. Replace the other two identical transforms with a
fuction named broken_c_unquote_verbose.

Signed-off-by: Ben Walton <bdwalton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t0008-ignores.sh
index 181513ab4fba47750b3e6b25eb105f2c8a4a011f..b4d98e602f7422009599e58f0a7ae943476b1c7e 100755 (executable)
@@ -37,6 +37,14 @@ test_stderr () {
        test_cmp "$HOME/expected-stderr" "$HOME/stderr"
 }
 
+broken_c_unquote () {
+       "$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@"
+}
+
+broken_c_unquote_verbose () {
+       "$PERL_PATH" -pe 's/    "/      /; s/\\//; s/"$//; tr/:\t\n/\0/' "$@"
+}
+
 stderr_contains () {
        regexp="$1"
        if grep "$regexp" "$HOME/stderr"
@@ -606,12 +614,11 @@ cat <<-EOF >expected-verbose
        $global_excludes:2:!globaltwo   b/globaltwo
 EOF
 
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
-       tr "\n" "\0" >stdin0
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
-       tr "\n" "\0" >expected-default0
-sed -e 's/     "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
-       tr ":\t\n" "\0" >expected-verbose0
+broken_c_unquote stdin >stdin0
+
+broken_c_unquote expected-default >expected-default0
+
+broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 test_expect_success '--stdin' '
        expect_from_stdin <expected-default &&
@@ -692,12 +699,11 @@ EOF
 grep -v '^::   ' expected-all >expected-verbose
 sed -e 's/.*   //' expected-verbose >expected-default
 
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \
-       tr "\n" "\0" >stdin0
-sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \
-       tr "\n" "\0" >expected-default0
-sed -e 's/     "/      /' -e 's/\\//' -e 's/"$//' expected-verbose | \
-       tr ":\t\n" "\0" >expected-verbose0
+broken_c_unquote stdin >stdin0
+
+broken_c_unquote expected-default >expected-default0
+
+broken_c_unquote_verbose expected-verbose >expected-verbose0
 
 test_expect_success '--stdin from subdirectory' '
        expect_from_stdin <expected-default &&