* [PATCH] Add test-tr: poor-man tr @ 2008-06-11 18:25 Alex Riesen, Alex Riesen 2008-06-11 18:26 ` [PATCH] Use test-tr in the tests Alex Riesen ` (3 more replies) 0 siblings, 4 replies; 14+ messages in thread From: Alex Riesen, Alex Riesen @ 2008-06-11 18:25 UTC (permalink / raw) To: git; +Cc: Junio C Hamano It offers a limited set of POSIX tr, in particular: no character class support and no [n*m] operators. Only 8bit. C-escapes supported, and character ranges. Deletion and squeezing should work, but -s does not match the GNU tr from coreutils (which, in turn, does not match POSIX). Signed-off-by: Alex Riesen <raa.lkml@gmail.com> --- Rebased on top of current master. I still think it makes the test suite more portable. Makefile | 2 +- test-tr.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+), 1 deletions(-) create mode 100644 test-tr.c diff --git a/Makefile b/Makefile index 1937507..5f208d6 100644 --- a/Makefile +++ b/Makefile @@ -1229,7 +1229,7 @@ endif ### Testing rules -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X +TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X test-tr$X all:: $(TEST_PROGRAMS) diff --git a/test-tr.c b/test-tr.c new file mode 100644 index 0000000..82af602 --- /dev/null +++ b/test-tr.c @@ -0,0 +1,206 @@ +/* +vim: sw=8 +*/ +#include "cache.h" + +static int squeeze, delete; + +static unsigned char *unquote(const char *s, unsigned *len) +{ + unsigned char *result = malloc(strlen(s)), *r = result; + + while (*s) { + switch (*s) { + case '\\': + ++s; +#define ISOCT(c) (((c) >= '0' && (c) <= '7')) + if (ISOCT(*s)) { + unsigned int c; + char oct[4] = {0,0,0,0}; + oct[0] = *s++; + c = (oct[0] - '0'); + if (ISOCT(*s)) { + oct[1] = *s++; + c = (c << 3) |(oct[1] - '0'); + if (ISOCT(*s)) { + oct[2] = *s++; + c = (c << 3) |(oct[2] - '0'); + } + } + if (c > 255) { + fprintf(stderr, "invalid octal character specification: \\%s\n", oct); + exit(1); + } + *r++ = c & 0xff; + } else { + switch (*s) { + case '\0': + *r++ = '\\'; + break; + case '\\': + *r++ = *s++; + break; + case 'a': + *r++ = '\a'; + ++s; + break; + case 'b': + *r++ = '\b'; + ++s; + break; + case 'f': + *r++ = '\f'; + ++s; + break; + case 'n': + *r++ = '\n'; + ++s; + break; + case 'r': + *r++ = '\r'; + ++s; + break; + case 't': + *r++ = '\t'; + ++s; + break; + case 'v': + *r++ = '\v'; + ++s; + break; + default: + *r++ = '\\'; + *r++ = *s++; + break; + } + } + break; + default: + *r++ = *s++; + } + } + + *len = r - result; + *r = '\0'; + return result; +} + +#define MAX_PATTERN 256 +static void put_op(unsigned char *conv, unsigned char ch, unsigned *len) +{ + unsigned i = (*len)++; + if (*len > MAX_PATTERN) { + fprintf(stderr, "pattern too long\n"); + exit(1); + } + conv[i] = ch; +} + +static void parse(const unsigned char *rule, unsigned rule_len, + unsigned char *set, unsigned *set_len) +{ + const unsigned char *p = rule; + while (p < rule + rule_len) { + if ('-' == *p && p > rule && p[1]) { + unsigned c; + if (p[-1] > p[1]) { + fprintf(stderr, "%c%c%c: range is reversed\n", + p[-1], *p, p[1]); + exit(1); + } + c = p[-1] + 1u; + for (; c <= p[1]; ++c) + put_op(set, c, set_len); + ++p; + ++p; + continue; + } + put_op(set, *p, set_len); + ++p; + } +} + +int main(int argc, char *argv[]) +{ + unsigned set1_len = 0, set2_len = 0; + unsigned char set1[MAX_PATTERN]; + unsigned char set2[MAX_PATTERN]; + + ssize_t n; + unsigned char last = 0, have_last = 0; + unsigned char buf[BUFSIZ]; + + char *rule1 = NULL, *rule2 = NULL; + unsigned char *urule1, *urule2; + unsigned urule1_len, urule2_len; + int opt; + + for (opt = 1; opt < argc; ++opt) { + if (!strcmp("-s", argv[opt])) + squeeze = 1; + else if (!strcmp("-d", argv[opt])) + delete = 1; + else if (!rule1) { + rule1 = argv[opt]; + } else if (!rule2) + rule2 = argv[opt]; + } + if (!rule1) { + fprintf(stderr, "no source set given\n" + "test-tr [-s] [-d] set1 [set2]\n" + "\"set\" supports only \\NNN, \\a-\\v and CHAR1-CHAR2 rules\n"); + exit(1); + } + if (delete && rule2) { + fprintf(stderr, "extra operand %s when deleting\n", rule2); + exit(1); + } + urule1 = unquote(rule1, &urule1_len); + urule2 = NULL; + urule2_len = 0; + if ((!rule2 || !*rule2) && !delete && !squeeze) { + fprintf(stderr, "set2 must be non-empty\n"); + exit(1); + } + + parse(urule1, urule1_len, set1, &set1_len); + + if (rule2) { + unsigned i; + urule2 = unquote(rule2, &urule2_len); + parse(urule2, urule2_len, set2, &set2_len); + i = set2[set2_len - 1]; + while (set2_len < set1_len) + put_op(set2, i, &set2_len); + } + + while ((n = read(STDIN_FILENO, buf, sizeof(buf)))) { + if (n < 0) { + int err = errno; + if (EINTR == err || EAGAIN == err) + continue; + fprintf(stderr, "%s: %s\n", argv[0], strerror(err)); + exit(1); + } + if (set1_len) { + unsigned i, o = 0; + for (i = 0; i < (unsigned)n; ++i) { + unsigned char *p, ch = buf[i]; + p = memchr(set1, ch, set1_len); + if (p) { + if (delete) + continue; + if (set2_len) + ch = set2[p - set1]; + } + if (!(squeeze && have_last && ch == last)) + buf[o++] = ch; + have_last = 1; + last = ch; + } + n = o; + } + write(STDOUT_FILENO, buf, n); + } + return 0; +} -- 1.5.6.rc2.57.gc9624 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH] Use test-tr in the tests 2008-06-11 18:25 [PATCH] Add test-tr: poor-man tr Alex Riesen, Alex Riesen @ 2008-06-11 18:26 ` Alex Riesen 2008-06-11 21:34 ` [PATCH] Add test-tr: poor-man tr Alex Riesen ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Alex Riesen @ 2008-06-11 18:26 UTC (permalink / raw) To: git; +Cc: Junio C Hamano Signed-off-by: Alex Riesen <raa.lkml@gmail.com> --- t/annotate-tests.sh | 4 ++-- t/diff-lib.sh | 4 ++-- t/t0000-basic.sh | 2 +- t/t0020-crlf.sh | 10 +++++----- t/t0021-conversion.sh | 2 +- t/t1300-repo-config.sh | 4 ++-- t/t3300-funny-names.sh | 6 +++--- t/t3402-rebase-merge.sh | 4 ++-- t/t4004-diff-rename-symlink.sh | 2 +- t/t4015-diff-whitespace.sh | 6 +++--- t/t4019-diff-wserror.sh | 2 +- t/t4020-diff-external.sh | 2 +- t/t4022-diff-rewrite.sh | 2 +- t/t4101-apply-nonl.sh | 4 ++-- t/t4103-apply-binary.sh | 4 ++-- t/t4116-apply-reverse.sh | 4 ++-- t/t4118-apply-empty-context.sh | 4 ++-- t/t4200-rerere.sh | 2 +- t/t4201-shortlog.sh | 4 ++-- t/t5300-pack-object.sh | 2 +- t/t5500-fetch-pack.sh | 2 +- t/t5505-remote.sh | 4 ++-- t/t6003-rev-list-topo-order.sh | 2 +- t/t6033-merge-crlf.sh | 4 ++-- t/t7003-filter-branch.sh | 2 +- t/t9200-git-cvsexportcommit.sh | 2 +- t/t9401-git-cvsserver-crlf.sh | 4 ++-- t/test-lib.sh | 12 +++++++----- 28 files changed, 54 insertions(+), 52 deletions(-) diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index cacb273..8e10323 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -104,7 +104,7 @@ test_expect_success \ test_expect_success \ 'an incomplete line added' \ - 'echo "incomplete" | tr -d "\\012" >>file && + 'echo "incomplete" | test-tr -d "\\012" >>file && GIT_AUTHOR_NAME="C" git commit -a -m "Incomplete"' test_expect_success \ @@ -115,7 +115,7 @@ test_expect_success \ 'some edit' \ 'mv file file.orig && sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" < file.orig > file && - echo "incomplete" | tr -d "\\012" >>file && + echo "incomplete" | test-tr -d "\\012" >>file && GIT_AUTHOR_NAME="D" git commit -a -m "edit"' test_expect_success \ diff --git a/t/diff-lib.sh b/t/diff-lib.sh index 4bddeb5..f840340 100644 --- a/t/diff-lib.sh +++ b/t/diff-lib.sh @@ -21,8 +21,8 @@ compare_diff_raw_z () { # Also we do not check SHA1 hash generation in this test, which # is a job for t0000-basic.sh - perl -pe 'y/\000/\012/' <"$1" | sed -e "$sanitize_diff_raw_z" >.tmp-1 - perl -pe 'y/\000/\012/' <"$2" | sed -e "$sanitize_diff_raw_z" >.tmp-2 + test-tr '\000' '\012' <"$1" | sed -e "$sanitize_diff_raw_z" >.tmp-1 + test-tr '\000' '\012' <"$2" | sed -e "$sanitize_diff_raw_z" >.tmp-2 test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2 } diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 690f80a..ad81546 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -324,7 +324,7 @@ test_expect_success 'very long name in the index handled sanely' ' ( git ls-files -s path4 | sed -e "s/ .*/ /" | - tr -d "\012" + test-tr -d "\012" echo "$a" ) | git update-index --index-info && len=$(git ls-files "a*" | wc -c) && diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 2bfeac9..7427d59 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -5,20 +5,20 @@ test_description='CRLF conversion' . ./test-lib.sh q_to_nul () { - perl -pe 'y/Q/\000/' + test-tr Q '\000' } q_to_cr () { - tr Q '\015' + test-tr Q '\015' } append_cr () { - sed -e 's/$/Q/' | tr Q '\015' + sed -e 's/$/Q/' | test-tr Q '\015' } remove_cr () { - tr '\015' Q <"$1" | grep Q >/dev/null && - tr '\015' Q <"$1" | sed -ne 's/Q$//p' + test-tr '\015' Q <"$1" | grep Q >/dev/null && + test-tr '\015' Q <"$1" | sed -ne 's/Q$//p' } test_expect_success setup ' diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index 8fc39d7..d146db4 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -5,7 +5,7 @@ test_description='blob conversion via gitattributes' . ./test-lib.sh cat <<\EOF >rot13.sh -tr \ +test-tr \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \ 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM' EOF diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index afe7e66..57ba088 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -715,12 +715,12 @@ Qsection.sub=section.val4 Qsection.sub=section.val5Q EOF -git config --null --list | perl -pe 'y/\000/Q/' > result +git config --null --list | test-tr '\000' Q > result echo >>result test_expect_success '--null --list' 'cmp result expect' -git config --null --get-regexp 'val[0-9]' | perl -pe 'y/\000/Q/' > result +git config --null --get-regexp 'val[0-9]' | test-tr '\000' Q > result echo >>result test_expect_success '--null --get-regexp' 'cmp result expect' diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index 0574ef1..6ec6c24 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -54,7 +54,7 @@ echo 'just space no-funny tabs ," (dq) and spaces' >expected test_expect_success 'git ls-files -z with-funny' \ - 'git ls-files -z | perl -pe y/\\000/\\012/ >current && + 'git ls-files -z | test-tr "\000" "\012" >current && test_cmp expected current' t1=`git write-tree` @@ -83,11 +83,11 @@ test_expect_success 'git diff-tree with-funny' \ echo 'A tabs ," (dq) and spaces' >expected test_expect_success 'git diff-index -z with-funny' \ - 'git diff-index -z --name-status $t0 | perl -pe y/\\000/\\012/ >current && + 'git diff-index -z --name-status $t0 | test-tr "\000" "\012" >current && test_cmp expected current' test_expect_success 'git diff-tree -z with-funny' \ - 'git diff-tree -z --name-status $t0 $t1 | perl -pe y/\\000/\\012/ >current && + 'git diff-tree -z --name-status $t0 $t1 | test-tr "\000" "\012" >current && test_cmp expected current' cat > expected <<\EOF diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 7b7d072..704f9a3 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -30,11 +30,11 @@ test_expect_success setup ' git update-index --force-remove original && git commit -a -m"side renames and edits." && - tr "[a-z]" "[A-Z]" <original >newfile && + test-tr a-z A-Z <original >newfile && git add newfile && git commit -a -m"side edits further." && - tr "[a-m]" "[A-M]" <original >newfile && + test-tr a-m A-M <original >newfile && rm -f original && git commit -a -m"side edits once again." && diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh index 3d25be7..b49efa4 100755 --- a/t/t4004-diff-rename-symlink.sh +++ b/t/t4004-diff-rename-symlink.sh @@ -14,7 +14,7 @@ by an edit for them. test_expect_success \ 'prepare reference tree' \ - 'echo xyzzy | tr -d '\\\\'012 >yomin && + 'echo xyzzy | test-tr -d "\012" >yomin && ln -s xyzzy frotz && git update-index --add frotz yomin && tree=$(git write-tree) && diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index ca0302f..8841626 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -51,7 +51,7 @@ test_expect_success "Ray's example with -w" 'test_cmp expect out' git diff -b > out test_expect_success "Ray's example with -b" 'test_cmp expect out' -tr 'Q' '\015' << EOF > x +test-tr 'Q' '\015' << EOF > x whitespace at beginning whitespace change whitespace in the middle @@ -71,7 +71,7 @@ unchanged line CR at end EOF -tr 'Q' '\015' << EOF > expect +test-tr 'Q' '\015' << EOF > expect diff --git a/x b/x index d99af23..8b32fb5 100644 --- a/x @@ -99,7 +99,7 @@ EOF git diff -w > out test_expect_success 'another test, with -w' 'test_cmp expect out' -tr 'Q' '\015' << EOF > expect +test-tr 'Q' '\015' << EOF > expect diff --git a/x b/x index d99af23..8b32fb5 100644 --- a/x diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index 0d9cbb6..4967026 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -12,7 +12,7 @@ test_expect_success setup ' echo " Eight SP indent" >>F && echo " HT and SP indent" >>F && echo "With trailing SP " >>F && - echo "Carriage ReturnQ" | tr Q "\015" >>F && + echo "Carriage ReturnQ" | test-tr Q "\015" >>F && echo "No problem" >>F ' diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index 637b4e1..3ae3165 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -99,7 +99,7 @@ test_expect_success 'no diff with -diff' ' git diff | grep Binary ' -echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file +echo NULZbetweenZwords | test-tr 'Z' '\000' > file test_expect_success 'force diff with "diff"' ' echo >.gitattributes "file diff" && diff --git a/t/t4022-diff-rewrite.sh b/t/t4022-diff-rewrite.sh index bf996fc..01d221b 100755 --- a/t/t4022-diff-rewrite.sh +++ b/t/t4022-diff-rewrite.sh @@ -8,7 +8,7 @@ test_expect_success setup ' cat ../../COPYING >test && git add test && - tr \ + test-tr \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM" \ <../../COPYING >test diff --git a/t/t4101-apply-nonl.sh b/t/t4101-apply-nonl.sh index da8abcf..53277e6 100755 --- a/t/t4101-apply-nonl.sh +++ b/t/t4101-apply-nonl.sh @@ -12,8 +12,8 @@ test_description='git apply should handle files with incomplete lines. (echo a; echo b) >frotz.0 (echo a; echo b; echo c) >frotz.1 -(echo a; echo b | tr -d '\012') >frotz.2 -(echo a; echo c; echo b | tr -d '\012') >frotz.3 +(echo a; echo b | test-tr -d '\012') >frotz.2 +(echo a; echo c; echo b | test-tr -d '\012') >frotz.3 for i in 0 1 2 3 do diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index 1b58233..f7542a0 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -24,10 +24,10 @@ git update-index --add --remove file1 file2 file4 git-commit -m 'Initial Version' 2>/dev/null git-checkout -b binary -perl -pe 'y/x/\000/' <file1 >file3 +test-tr x '\000' <file1 >file3 cat file3 >file4 git add file2 -perl -pe 'y/\000/v/' <file3 >file1 +test-tr '\000' v <file3 >file1 rm -f file2 git update-index --add --remove file1 file2 file3 file4 git-commit -m 'Second Version' diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index 1459a90..31608df 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -12,14 +12,14 @@ test_description='git apply in reverse test_expect_success setup ' for i in a b c d e f g h i j k l m n; do echo $i; done >file1 && - perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 && + test-tr "ijk" "\000\001\002" <file1 >file2 && git add file1 file2 && git commit -m initial && git tag initial && for i in a b c g h i J K L m o n p q; do echo $i; done >file1 && - perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 && + test-tr "mon" "\000\001\002" <file1 >file2 && git commit -a -m second && git tag second && diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh index f92e259..89e5d14 100755 --- a/t/t4118-apply-empty-context.sh +++ b/t/t4118-apply-empty-context.sh @@ -18,13 +18,13 @@ test_expect_success setup ' cat file1 >file1.orig && { cat file1 && - echo Q | tr -d "\\012" + echo Q | test-tr -d "\012" } >file2 && cat file2 >file2.orig git add file1 file2 && sed -e "/^B/d" <file1.orig >file1 && sed -e "/^[BQ]/d" <file2.orig >file2 && - echo Q | tr -d "\\012" >>file2 && + echo Q | test-tr -d "\012" >>file2 && cat file1 >file1.mods && cat file2 >file2.mods && git diff | diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 85d7e3e..23b10f2 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -129,7 +129,7 @@ test_expect_success 'rerere kicked in' "! grep ======= a1" test_expect_success 'rerere prefers first change' 'test_cmp a1 expect' rm $rr/postimage -echo "$sha1 a1" | perl -pe 'y/\012/\000/' > .git/rr-cache/MERGE_RR +echo "$sha1 a1" | test-tr '\012' '\000' > .git/rr-cache/MERGE_RR test_expect_success 'rerere clear' 'git rerere clear' diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index 405b971..1a4b88d 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -19,12 +19,12 @@ git commit --quiet -m "This is a very, very long first line for the commit messa # test if the wrapping is still valid when replacing all i's by treble clefs. echo 3 > a1 -git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1 +git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | test-tr 1234 '\360\235\204\236')" a1 # now fsck up the utf8 git config i18n.commitencoding non-utf-8 echo 4 > a1 -git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1 +git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | test-tr 1234 '\370\235\204\236')" a1 echo 5 > a1 git commit --quiet -m "a 12 34 56 78" a1 diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 983a393..ebb85a5 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -15,7 +15,7 @@ test_expect_success \ 'rm -f .git/index* for i in a b c do - dd if=/dev/zero bs=4k count=1 | perl -pe "y/\\000/$i/" >$i && + dd if=/dev/zero bs=4k count=1 | test-tr "\000" "$i" >$i && git update-index --add $i || return 1 done && cat c >d && echo foo >>d && git update-index --add d && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 140e874..784600e 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -37,7 +37,7 @@ add () { } count_objects () { - ls .git/objects/??/* 2>>log2.txt | wc -l | tr -d " " + ls .git/objects/??/* 2>>log2.txt | wc -l | test-tr -d " " } test_expect_object_count () { diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 0d7ed1f..4c08c81 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -22,8 +22,8 @@ setup_repository () { } tokens_match () { - echo "$1" | tr ' ' '\012' | sort | sed -e '/^$/d' >expect && - echo "$2" | tr ' ' '\012' | sort | sed -e '/^$/d' >actual && + echo "$1" | test-tr ' ' '\012' | sort | sed -e '/^$/d' >expect && + echo "$2" | test-tr ' ' '\012' | sort | sed -e '/^$/d' >actual && test_cmp expect actual } diff --git a/t/t6003-rev-list-topo-order.sh b/t/t6003-rev-list-topo-order.sh index 5daa0be..5dbc6a7 100755 --- a/t/t6003-rev-list-topo-order.sh +++ b/t/t6003-rev-list-topo-order.sh @@ -79,7 +79,7 @@ save_tag g4 unique_commit g6 tree -p g3 -p h2 git update-ref HEAD $(tag l5) -test_output_expect_success 'rev-list has correct number of entries' 'git rev-list HEAD | wc -l | tr -d \" \"' <<EOF +test_output_expect_success 'rev-list has correct number of entries' 'git rev-list HEAD | wc -l | test-tr -d \" \"' <<EOF 19 EOF diff --git a/t/t6033-merge-crlf.sh b/t/t6033-merge-crlf.sh index 75d9602..fed088a 100755 --- a/t/t6033-merge-crlf.sh +++ b/t/t6033-merge-crlf.sh @@ -1,11 +1,11 @@ #!/bin/sh append_cr () { - sed -e 's/$/Q/' | tr Q '\015' + sed -e 's/$/Q/' | test-tr Q '\015' } remove_cr () { - tr '\015' Q | sed -e 's/Q$//' + test-tr '\015' Q | sed -e 's/Q$//' } test_description='merge conflict in crlf repo diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index e26f726..9928863 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -4,7 +4,7 @@ test_description='git-filter-branch' . ./test-lib.sh make_commit () { - lower=$(echo $1 | tr '[A-Z]' '[a-z]') + lower=$(echo $1 | test-tr 'A-Z' 'a-z') echo $lower > $lower git add $lower test_tick diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index b1dc32d..f84a99c 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -35,7 +35,7 @@ check_entries () { then >expected else - printf '%s\n' "$2" | tr '|' '\012' >expected + printf '%s\n' "$2" | test-tr '|' '\012' >expected fi test_cmp expected actual } diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index e27a1c5..f5b4d94 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -12,11 +12,11 @@ repository using cvs CLI client via git-cvsserver server' . ./test-lib.sh q_to_nul () { - perl -pe 'y/Q/\000/' + test-tr Q '\000' } q_to_cr () { - tr Q '\015' + test-tr Q '\015' } marked_as () { diff --git a/t/test-lib.sh b/t/test-lib.sh index 7a8bd27..c3eb7df 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -44,11 +44,16 @@ export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME export EDITOR VISUAL GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u} +# Test the binaries we have just built. The tests are kept in +# t/ subdirectory and are run in trash subdirectory. +PATH=$(pwd)/..:$PATH +export PATH + # Protect ourselves from common misconfiguration to export # CDPATH into the environment unset CDPATH -case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in +case $(echo $GIT_TRACE |test-tr A-Z a-z) in 1|2|true) echo "* warning: Some tests will not work if GIT_TRACE" \ "is set as to trace on STDERR ! *" @@ -385,16 +390,13 @@ test_done () { esac } -# Test the binaries we have just built. The tests are kept in -# t/ subdirectory and are run in trash subdirectory. -PATH=$(pwd)/..:$PATH GIT_EXEC_PATH=$(pwd)/.. GIT_TEMPLATE_DIR=$(pwd)/../templates/blt unset GIT_CONFIG unset GIT_CONFIG_LOCAL GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_NOGLOBAL=1 -export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL +export GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git export GITPERLLIB -- 1.5.6.rc2.57.gc9624 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-11 18:25 [PATCH] Add test-tr: poor-man tr Alex Riesen, Alex Riesen 2008-06-11 18:26 ` [PATCH] Use test-tr in the tests Alex Riesen @ 2008-06-11 21:34 ` Alex Riesen 2008-06-11 22:54 ` Jeff King 2008-06-12 6:32 ` Alf Clement 3 siblings, 0 replies; 14+ messages in thread From: Alex Riesen @ 2008-06-11 21:34 UTC (permalink / raw) To: git; +Cc: Junio C Hamano Alex Riesen, Wed, Jun 11, 2008 20:25:01 +0200: > --- /dev/null > +++ b/test-tr.c > @@ -0,0 +1,206 @@ > +/* > +vim: sw=8 > +*/ Sorry about that... ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-11 18:25 [PATCH] Add test-tr: poor-man tr Alex Riesen, Alex Riesen 2008-06-11 18:26 ` [PATCH] Use test-tr in the tests Alex Riesen 2008-06-11 21:34 ` [PATCH] Add test-tr: poor-man tr Alex Riesen @ 2008-06-11 22:54 ` Jeff King 2008-06-12 6:01 ` Alex Riesen 2008-06-12 6:32 ` Alf Clement 3 siblings, 1 reply; 14+ messages in thread From: Jeff King @ 2008-06-11 22:54 UTC (permalink / raw) To: Alex Riesen, Alex Riesen; +Cc: git, Junio C Hamano On Wed, Jun 11, 2008 at 08:25:01PM +0200, Alex Riesen wrote: > It offers a limited set of POSIX tr, in particular: no character class > support and no [n*m] operators. Only 8bit. C-escapes supported, and > character ranges. Deletion and squeezing should work, but -s does not > match the GNU tr from coreutils (which, in turn, does not match POSIX). > > Signed-off-by: Alex Riesen <raa.lkml@gmail.com> > --- > > Rebased on top of current master. I still think it makes the test > suite more portable. Having wrestled with Solaris tr, I can understand where you are coming from. However, does this _actually_ increase the portability of the test suite? That is, are there failing tests that this fixes, and if so, for which platforms (getting a successful run of the test suite on Solaris is still on my long-term todo, but I thought I had fixed all of the tr issues)? Or is your rationale "this will prevent people from screwing up the test scripts accidentally in the future"? I am not opposed to the latter, but I think it makes sense to state it clearly in the commit message. -Peff ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-11 22:54 ` Jeff King @ 2008-06-12 6:01 ` Alex Riesen 2008-06-12 6:23 ` Jeff King 0 siblings, 1 reply; 14+ messages in thread From: Alex Riesen @ 2008-06-12 6:01 UTC (permalink / raw) To: Jeff King; +Cc: git, Junio C Hamano Jeff King, Thu, Jun 12, 2008 00:54:48 +0200: > On Wed, Jun 11, 2008 at 08:25:01PM +0200, Alex Riesen wrote: > > > It offers a limited set of POSIX tr, in particular: no character class > > support and no [n*m] operators. Only 8bit. C-escapes supported, and > > character ranges. Deletion and squeezing should work, but -s does not > > match the GNU tr from coreutils (which, in turn, does not match POSIX). > > > > Signed-off-by: Alex Riesen <raa.lkml@gmail.com> > > --- > > > > Rebased on top of current master. I still think it makes the test > > suite more portable. > > Having wrestled with Solaris tr, I can understand where you are coming > from. However, does this _actually_ increase the portability of the test > suite? That is, are there failing tests that this fixes, and if so, for > which platforms (getting a successful run of the test suite on Solaris > is still on my long-term todo, but I thought I had fixed all of the tr > issues)? Frankly, it started because I wanted to minimize use of Perl on Windows (because I can't get around ActiveState Perl at work, and it breaks almost everything it touches). Accidentally, it is also faster there (maybe just because it's smaller). But, as was already noted, tr does not behave the same for all platforms (there were even differences in output, BSD or Solaris put out a stray LF?). > Or is your rationale "this will prevent people from screwing up the test > scripts accidentally in the future"? We just can't have that. Nothing can prevent people from screwing up anything in any given point of time :) In any case, I wont push this change too hard. I must admit, that there is no real good reason besides one "screwed" company using obsoleted tools in a weird way. And it is a maintenance effort (and people will forget to use test-tr instead of perl and tr). And maybe someday my employment situation improves and I wont push it at all :) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-12 6:01 ` Alex Riesen @ 2008-06-12 6:23 ` Jeff King 2008-06-12 6:28 ` Jeff King 2008-06-12 20:32 ` Alex Riesen 0 siblings, 2 replies; 14+ messages in thread From: Jeff King @ 2008-06-12 6:23 UTC (permalink / raw) To: Alex Riesen; +Cc: git, Junio C Hamano On Thu, Jun 12, 2008 at 08:01:52AM +0200, Alex Riesen wrote: > Frankly, it started because I wanted to minimize use of Perl on > Windows (because I can't get around ActiveState Perl at work, and it > breaks almost everything it touches). Accidentally, it is also faster > there (maybe just because it's smaller). Ah, right. Well, I am not opposed to getting rid of perl in the test scripts (there is core functionality provided by perl, so one can easily run git on a system with no perl at all). However, even with your patch, there is still some perl left, so I am not sure that it has really bought us very much. > But, as was already noted, tr does not behave the same for all > platforms (there were even differences in output, BSD or Solaris put > out a stray LF?). I think those were all resolved by using perl, and your patch replaces them with test-tr. > > Or is your rationale "this will prevent people from screwing up the test > > scripts accidentally in the future"? > We just can't have that. Nothing can prevent people from screwing up > anything in any given point of time :) Heh. At least we can yell at them after the fact for not using the available tool. :) > In any case, I wont push this change too hard. I must admit, that > there is no real good reason besides one "screwed" company using > obsoleted tools in a weird way. And it is a maintenance effort (and > people will forget to use test-tr instead of perl and tr). There is maintenance effort either way; people need to know not to do unportable things with tr (and other tools), and the solution to that is to run the test scripts on each platform (something we are starting to do). So I am not opposed to test-tr, I just wanted you to explain it better in the commit log. ;) -Peff ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-12 6:23 ` Jeff King @ 2008-06-12 6:28 ` Jeff King 2008-06-12 20:32 ` Alex Riesen 1 sibling, 0 replies; 14+ messages in thread From: Jeff King @ 2008-06-12 6:28 UTC (permalink / raw) To: Alex Riesen; +Cc: git, Junio C Hamano On Thu, Jun 12, 2008 at 02:23:09AM -0400, Jeff King wrote: > Ah, right. Well, I am not opposed to getting rid of perl in the test > scripts (there is core functionality provided by perl, so one can easily > run git on a system with no perl at all). Er, sorry. This should read: "there is _no_ core functionality provide by perl". -Peff ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-12 6:23 ` Jeff King 2008-06-12 6:28 ` Jeff King @ 2008-06-12 20:32 ` Alex Riesen 2008-06-13 6:02 ` Jeff King 1 sibling, 1 reply; 14+ messages in thread From: Alex Riesen @ 2008-06-12 20:32 UTC (permalink / raw) To: Jeff King; +Cc: git, Junio C Hamano Jeff King, Thu, Jun 12, 2008 08:23:09 +0200: > On Thu, Jun 12, 2008 at 08:01:52AM +0200, Alex Riesen wrote: > > > Frankly, it started because I wanted to minimize use of Perl on > > Windows (because I can't get around ActiveState Perl at work, and it > > breaks almost everything it touches). Accidentally, it is also faster > > there (maybe just because it's smaller). > > Ah, right. Well, I am not opposed to getting rid of perl in the test > scripts (there is core functionality provided by perl, so one can easily > run git on a system with no perl at all). "git add --interactive" and "git send-mail". The first has a very good replacement (git gui). The other, even if not that "core", is a very popular tool. (And I can't use it at work at all: noone to understand word "patch" there. And even then, noone would care about change review anyway). > However, even with your patch, there is still some perl left, so I am > not sure that it has really bought us very much. I was forced to carefully check every instance and am positive that the others are ok with regard to ActiveState Perl and Windows quirks :) (IOW, I run the testsuite every day and it aint broke yet) > > But, as was already noted, tr does not behave the same for all > > platforms (there were even differences in output, BSD or Solaris put > > out a stray LF?). > > I think those were all resolved by using perl, and your patch replaces > them with test-tr. That was the problem. ActiveState Perl always replaces LF in the output with CRLF, which caused mismatches with template files in some tests (even the generated templates had LF line endings, cygwins tools follow that convention). At first, I tried to get by putting "binmode(STDOUT)" into every test, but this became boring with a time. Besides, the lines get very long and ugly (and make conflict resolving harder). > > In any case, I wont push this change too hard. I must admit, that > > there is no real good reason besides one "screwed" company using > > obsoleted tools in a weird way. And it is a maintenance effort (and > > people will forget to use test-tr instead of perl and tr). > > There is maintenance effort either way; people need to know not to do > unportable things with tr (and other tools), and the solution to that is > to run the test scripts on each platform (something we are starting to > do). With test-tr they still have to do all that, but also support its existence. So I'm not sure. > So I am not opposed to test-tr, I just wanted you to explain it better > in the commit log. ;) I already tried. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-12 20:32 ` Alex Riesen @ 2008-06-13 6:02 ` Jeff King 2008-06-13 17:26 ` Alex Riesen 0 siblings, 1 reply; 14+ messages in thread From: Jeff King @ 2008-06-13 6:02 UTC (permalink / raw) To: Alex Riesen; +Cc: git, Junio C Hamano On Thu, Jun 12, 2008 at 10:32:45PM +0200, Alex Riesen wrote: > That was the problem. ActiveState Perl always replaces LF in the > output with CRLF, which caused mismatches with template files in some > tests (even the generated templates had LF line endings, cygwins tools > follow that convention). At first, I tried to get by putting > "binmode(STDOUT)" into every test, but this became boring with a time. > Besides, the lines get very long and ugly (and make conflict resolving > harder). Does ActiveState respect the PERLIO environment variable? I haven't played with it much, but my understanding is that setting PERLIO=:unix:perlio should give you sane behavior (the default on Windows should be PERLIO=:unix:crlf). > > So I am not opposed to test-tr, I just wanted you to explain it better > > in the commit log. ;) > > I already tried. I think this thread and the improved commit message have helped. -Peff ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-13 6:02 ` Jeff King @ 2008-06-13 17:26 ` Alex Riesen 2008-06-13 18:00 ` Jeff King 0 siblings, 1 reply; 14+ messages in thread From: Alex Riesen @ 2008-06-13 17:26 UTC (permalink / raw) To: Jeff King; +Cc: git, Junio C Hamano Jeff King, Fri, Jun 13, 2008 08:02:15 +0200: > On Thu, Jun 12, 2008 at 10:32:45PM +0200, Alex Riesen wrote: > > > That was the problem. ActiveState Perl always replaces LF in the > > output with CRLF, which caused mismatches with template files in some > > tests (even the generated templates had LF line endings, cygwins tools > > follow that convention). At first, I tried to get by putting > > "binmode(STDOUT)" into every test, but this became boring with a time. > > Besides, the lines get very long and ugly (and make conflict resolving > > harder). > > Does ActiveState respect the PERLIO environment variable? I haven't > played with it much, but my understanding is that setting > PERLIO=:unix:perlio should give you sane behavior (the default on > Windows should be PERLIO=:unix:crlf). I didn't know about it (and managed to miss it when I looked to workaround the problem. I even looked into the manpage documenting environment variables!) Yes, it works. It has side effects (the scripts of some build processes will be affected), but that's already something... ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-13 17:26 ` Alex Riesen @ 2008-06-13 18:00 ` Jeff King 0 siblings, 0 replies; 14+ messages in thread From: Jeff King @ 2008-06-13 18:00 UTC (permalink / raw) To: Alex Riesen; +Cc: git, Junio C Hamano On Fri, Jun 13, 2008 at 07:26:34PM +0200, Alex Riesen wrote: > > Does ActiveState respect the PERLIO environment variable? I haven't > > played with it much, but my understanding is that setting > > PERLIO=:unix:perlio should give you sane behavior (the default on > > Windows should be PERLIO=:unix:crlf). > > I didn't know about it (and managed to miss it when I looked to > workaround the problem. I even looked into the manpage documenting > environment variables!) > > Yes, it works. It has side effects (the scripts of some build > processes will be affected), but that's already something... I was thinking that we could set it inside test-lib.sh to get consistent behavior. It should just be a no-op on sane systems. -Peff ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-11 18:25 [PATCH] Add test-tr: poor-man tr Alex Riesen, Alex Riesen ` (2 preceding siblings ...) 2008-06-11 22:54 ` Jeff King @ 2008-06-12 6:32 ` Alf Clement 2008-06-12 7:25 ` Johannes Schindelin 3 siblings, 1 reply; 14+ messages in thread From: Alf Clement @ 2008-06-12 6:32 UTC (permalink / raw) To: Alex Riesen; +Cc: git, Junio C Hamano Hi Alex, > +static unsigned char *unquote(const char *s, unsigned *len) > +{ > + unsigned char *result = malloc(strlen(s)), *r = result; are you sure that the buffer is big enough?? Nomally you do a malloc(strlen(s)+1). CU, Alf ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Add test-tr: poor-man tr 2008-06-12 6:32 ` Alf Clement @ 2008-06-12 7:25 ` Johannes Schindelin 2008-06-12 20:20 ` Alex Riesen, Alex Riesen 0 siblings, 1 reply; 14+ messages in thread From: Johannes Schindelin @ 2008-06-12 7:25 UTC (permalink / raw) To: Alf Clement; +Cc: Alex Riesen, git, Junio C Hamano Hi, On Thu, 12 Jun 2008, Alf Clement wrote: > > +static unsigned char *unquote(const char *s, unsigned *len) +{ > > + unsigned char *result = malloc(strlen(s)), *r = result; > > are you sure that the buffer is big enough?? Nomally you do a > malloc(strlen(s)+1). AFAIU a "tr" really only ever replaces single characters by single characters. So, not even looking at the code -- just like you -- I would expect it to get the exact number of bytes read, and to write the same number of bytes. I certainly would not expect it to do something string based, introducing a silly expectation of NUL-terminations (which tr(1) does not expect either). Ciao, Dscho ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] Add test-tr: poor-man tr 2008-06-12 7:25 ` Johannes Schindelin @ 2008-06-12 20:20 ` Alex Riesen, Alex Riesen 0 siblings, 0 replies; 14+ messages in thread From: Alex Riesen, Alex Riesen @ 2008-06-12 20:20 UTC (permalink / raw) To: git; +Cc: Alf Clement, Johannes Schindelin, Junio C Hamano, Jeff King It offers a limited set of POSIX tr, in particular: no character class support and no [n*m] operators. Only 8bit. C-escapes supported, and character ranges. Deletion and squeezing should work, but -s does not match the GNU tr from coreutils (which, in turn, does not match POSIX). Even if the program does not offers the full tr features, what's left is guaranteed to work the same on every platform where you manage to compile it (unless the platform does something really nasty at low level). Originally written to overcome brokenness of ActiveState Perl on Windows, it should also improve (assuming it will be used instead of local "tr" and "perl -pe y///") portability of the test suite on other platforms. Signed-off-by: Alex Riesen <raa.lkml@gmail.com> --- Johannes Schindelin, Thu, Jun 12, 2008 09:25:09 +0200: > On Thu, 12 Jun 2008, Alf Clement wrote: > > > > +static unsigned char *unquote(const char *s, unsigned *len) +{ > > > + unsigned char *result = malloc(strlen(s)), *r = result; > > > > are you sure that the buffer is big enough?? Nomally you do a > > malloc(strlen(s)+1). > > AFAIU a "tr" really only ever replaces single characters by single > characters. So, not even looking at the code -- just like you -- I would > expect it to get the exact number of bytes read, and to write the same > number of bytes. > > I certainly would not expect it to do something string based, introducing > a silly expectation of NUL-terminations (which tr(1) does not expect > either). In any case, Alf is right. The unquote is called unconditionally with its arguments, even if there is nothing to unquote. In which case the size of result is off by one. Corrected test-tr.c (also with a sensible header) below. Makefile | 2 +- test-tr.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 1 deletions(-) create mode 100644 test-tr.c diff --git a/Makefile b/Makefile index 1937507..5f208d6 100644 --- a/Makefile +++ b/Makefile @@ -1229,7 +1229,7 @@ endif ### Testing rules -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X +TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X test-tr$X all:: $(TEST_PROGRAMS) diff --git a/test-tr.c b/test-tr.c new file mode 100644 index 0000000..2248535 --- /dev/null +++ b/test-tr.c @@ -0,0 +1,212 @@ +/* + * test-tr A simplified tr(1) implementation for testing purposes + * + * It offers a limited set of POSIX tr, in particular: no character + * class support and no [n*m] operators. Only 8bit. C-escapes + * supported, and character ranges. Deletion and squeezing should + * work, but -s does not match the GNU tr from coreutils (which, in + * turn, does not match POSIX). + */ +#include "cache.h" + +static int squeeze, delete; + +static unsigned char *unquote(const char *s, unsigned *len) +{ + unsigned char *result = malloc(strlen(s) + 1), *r = result; + + while (*s) { + switch (*s) { + case '\\': + ++s; +#define ISOCT(c) (((c) >= '0' && (c) <= '7')) + if (ISOCT(*s)) { + unsigned int c; + char oct[4] = {0,0,0,0}; + oct[0] = *s++; + c = (oct[0] - '0'); + if (ISOCT(*s)) { + oct[1] = *s++; + c = (c << 3) |(oct[1] - '0'); + if (ISOCT(*s)) { + oct[2] = *s++; + c = (c << 3) |(oct[2] - '0'); + } + } + if (c > 255) { + fprintf(stderr, "invalid octal character specification: \\%s\n", oct); + exit(1); + } + *r++ = c & 0xff; + } else { + switch (*s) { + case '\0': + *r++ = '\\'; + break; + case '\\': + *r++ = *s++; + break; + case 'a': + *r++ = '\a'; + ++s; + break; + case 'b': + *r++ = '\b'; + ++s; + break; + case 'f': + *r++ = '\f'; + ++s; + break; + case 'n': + *r++ = '\n'; + ++s; + break; + case 'r': + *r++ = '\r'; + ++s; + break; + case 't': + *r++ = '\t'; + ++s; + break; + case 'v': + *r++ = '\v'; + ++s; + break; + default: + *r++ = '\\'; + *r++ = *s++; + break; + } + } + break; + default: + *r++ = *s++; + } + } + + *len = r - result; + *r = '\0'; + return result; +} + +#define MAX_PATTERN 256 +static void put_op(unsigned char *conv, unsigned char ch, unsigned *len) +{ + unsigned i = (*len)++; + if (*len > MAX_PATTERN) { + fprintf(stderr, "pattern too long\n"); + exit(1); + } + conv[i] = ch; +} + +static void parse(const unsigned char *rule, unsigned rule_len, + unsigned char *set, unsigned *set_len) +{ + const unsigned char *p = rule; + while (p < rule + rule_len) { + if ('-' == *p && p > rule && p[1]) { + unsigned c; + if (p[-1] > p[1]) { + fprintf(stderr, "%c%c%c: range is reversed\n", + p[-1], *p, p[1]); + exit(1); + } + c = p[-1] + 1u; + for (; c <= p[1]; ++c) + put_op(set, c, set_len); + ++p; + ++p; + continue; + } + put_op(set, *p, set_len); + ++p; + } +} + +int main(int argc, char *argv[]) +{ + unsigned set1_len = 0, set2_len = 0; + unsigned char set1[MAX_PATTERN]; + unsigned char set2[MAX_PATTERN]; + + ssize_t n; + unsigned char last = 0, have_last = 0; + unsigned char buf[BUFSIZ]; + + char *rule1 = NULL, *rule2 = NULL; + unsigned char *urule1, *urule2; + unsigned urule1_len, urule2_len; + int opt; + + for (opt = 1; opt < argc; ++opt) { + if (!strcmp("-s", argv[opt])) + squeeze = 1; + else if (!strcmp("-d", argv[opt])) + delete = 1; + else if (!rule1) { + rule1 = argv[opt]; + } else if (!rule2) + rule2 = argv[opt]; + } + if (!rule1) { + fprintf(stderr, "no source set given\n" + "test-tr [-s] [-d] set1 [set2]\n" + "\"set\" supports only \\NNN, \\a-\\v and CHAR1-CHAR2 rules\n"); + exit(1); + } + if (delete && rule2) { + fprintf(stderr, "extra operand %s when deleting\n", rule2); + exit(1); + } + urule1 = unquote(rule1, &urule1_len); + urule2 = NULL; + urule2_len = 0; + if ((!rule2 || !*rule2) && !delete && !squeeze) { + fprintf(stderr, "set2 must be non-empty\n"); + exit(1); + } + + parse(urule1, urule1_len, set1, &set1_len); + + if (rule2) { + unsigned i; + urule2 = unquote(rule2, &urule2_len); + parse(urule2, urule2_len, set2, &set2_len); + i = set2[set2_len - 1]; + while (set2_len < set1_len) + put_op(set2, i, &set2_len); + } + + while ((n = read(STDIN_FILENO, buf, sizeof(buf)))) { + if (n < 0) { + int err = errno; + if (EINTR == err || EAGAIN == err) + continue; + fprintf(stderr, "%s: %s\n", argv[0], strerror(err)); + exit(1); + } + if (set1_len) { + unsigned i, o = 0; + for (i = 0; i < (unsigned)n; ++i) { + unsigned char *p, ch = buf[i]; + p = memchr(set1, ch, set1_len); + if (p) { + if (delete) + continue; + if (set2_len) + ch = set2[p - set1]; + } + if (!(squeeze && have_last && ch == last)) + buf[o++] = ch; + have_last = 1; + last = ch; + } + n = o; + } + write(STDOUT_FILENO, buf, n); + } + return 0; +} -- 1.5.6.rc2.43.g77bfa ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2008-06-13 18:01 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-06-11 18:25 [PATCH] Add test-tr: poor-man tr Alex Riesen, Alex Riesen 2008-06-11 18:26 ` [PATCH] Use test-tr in the tests Alex Riesen 2008-06-11 21:34 ` [PATCH] Add test-tr: poor-man tr Alex Riesen 2008-06-11 22:54 ` Jeff King 2008-06-12 6:01 ` Alex Riesen 2008-06-12 6:23 ` Jeff King 2008-06-12 6:28 ` Jeff King 2008-06-12 20:32 ` Alex Riesen 2008-06-13 6:02 ` Jeff King 2008-06-13 17:26 ` Alex Riesen 2008-06-13 18:00 ` Jeff King 2008-06-12 6:32 ` Alf Clement 2008-06-12 7:25 ` Johannes Schindelin 2008-06-12 20:20 ` Alex Riesen, Alex Riesen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).