1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#!/bin/sh
#
# $OpenBSD: substitute.sh,v 1.4 2016/05/30 16:31:02 schwarze Exp $
#
# Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
#
# Permission to use, copy, modify, and distribute this test suite for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# Test suite for the sed(1) -E substitute command, checking
# the handling of multiple zero-length matches in particular.
# error counter
err=0
# test function for one specific flag; arguments are:
# input string
# regular expression to replace
# substitution flag
# wanted output
tf() {
in=$1
patt="s/$2/x/$3"
want=$4
hexwant=`echo $want | hexdump -C`
hexout=`echo "$in" | sed -E "$patt" | hexdump -C`
if [ "X$hexout" != "X$hexwant" ]; then
echo "patt: $patt input: \"$in\\\\n\""
echo "want:" $hexwant
echo "got: " $hexout
fi
[ -z "$in" ] && want=""
hexwant=`echo -n $want | hexdump -C`
hexout=`echo -n "$in" | sed -E "$patt" | hexdump -C`
if [ "X$hexout" != "X$hexwant" ]; then
echo "patt: $patt input: \"$in\\\\0\""
echo "want:" $hexwant
echo "got: " $hexout
fi
}
# test function for various flags; arguments are:
# input string
# regular expression to replace
# wanted output for /g (global substitution)
# wanted output for /1 (substitution of first match) and so on
t() {
# global substitution
in=$1
expr=$2
want=$3
shift 3
tf "$in" "$expr" g "$want"
# substitution with specific index
num=1
while [ $# -gt 0 ]; do
want=$1
shift
tf "$in" "$expr" "$num" "$want"
num=$((num+1))
done
# substitution with excessive index
tf "$in" "$expr" "$num" "$in"
}
t '' ^ x x
t '' '()' x x
t '' '$' x x
t '' '^|$' x x
t a ^ xa xa
t a '()' xax xa ax
t a '$' ax ax
t a '\<' xa xa
t a '^|a' x x
t a '^|$' xax xa ax
t a '^|a|$' x x
t a 'a|$' x x
t a '\<|a' x x
t ab ^ xab xab
t ab '()' xaxbx xab axb abx
t ab '$' abx abx
t ab '\<' xab xab
t ab '^|a' xb xb
t ab '^|b' xax xab ax
t ab '^|$' xabx xab abx
t ab '^|a|$' xbx xb abx
t ab '^|b|$' xax xab ax
t ab '^|a|b|$' xx xb ax
t ab '^|ab|$' x x
t ab 'a|()' xbx xb abx
t ab 'a|$' xbx xb abx
t ab 'ab|$' x x
t ab 'b|()' xax xab ax
t ab 'b|$' ax ax
t ab '\<|a' xb xb
t ab '\<|b' xax xab ax
t abc '^|b' xaxc xabc axc
t abc '^|b|$' xaxcx xabc axc abcx
t abc '^|bc|$' xax xabc ax
t abc 'ab|()' xcx xc abcx
t abc 'ab|$' xcx xc abcx
t abc 'b|()' xaxcx xabc axc abcx
t abc 'bc|()' xax xabc ax
t abc 'b|$' axcx axc abcx
t aa a xx xa ax
t aa 'a|()' xx xa ax
t aa 'a*' x x
t a:a: '\<' xa:xa: xa:a: a:xa:
t a:a: '\<..' xx xa: a:x
exit $err
|