Skip to content

Commit f4657df

Browse files
committed
Add optimization for character iteration over a string
Signed-off-by: Alexey Gladkov <legion@kernel.org>
1 parent 5ecdef7 commit f4657df

1 file changed

Lines changed: 36 additions & 6 deletions

File tree

shell-string

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,28 @@ __fill_mask()
3636
eval "$1=\$__fill_masko"
3737
}
3838

39+
__shell_is_bash()
40+
{
41+
[ -n "${BASH-}" ] && [ -n "${BASH_VERSION-}" ]
42+
}
43+
44+
__shell_is_ksh()
45+
{
46+
[ -n "${KSH_VERSION-}" ]
47+
}
48+
3949
__shell_string_foreach=0
4050

4151
# Usage: __shell_string_foreach_prepare ctxvar str
4252
__shell_string_foreach_prepare()
4353
{
4454
eval "__shell_string_foreach_${__shell_string_foreach:-0}_line=\"\$2\""
4555
eval "__shell_string_foreach_${__shell_string_foreach:-0}_mask=\"\""
56+
eval "__shell_string_foreach_${__shell_string_foreach:-0}_i=0"
4657

47-
fill_mask "__shell_string_foreach_${__shell_string_foreach:-0}_mask" "$2"
58+
if ! __shell_is_bash && ! __shell_is_ksh; then
59+
fill_mask "__shell_string_foreach_${__shell_string_foreach:-0}_mask" "$2"
60+
fi
4861

4962
eval "$1=\"__shell_string_foreach_${__shell_string_foreach:-0}\""
5063
__shell_string_foreach=$(( ${__shell_string_foreach:-0} + 1 ))
@@ -55,14 +68,23 @@ __shell_string_foreach_finish()
5568
{
5669
unset "${1}_line"
5770
unset "${1}_mask"
71+
unset "${1}_i"
5872
}
5973

6074
# Usage: __shell_string_foreach_condition ctxvar
6175
__shell_string_foreach_condition()
6276
{
63-
local l
77+
local i l
78+
eval "i=\"\${${1}_i-}\""
6479
eval "l=\"\${${1}_line-}\""
65-
[ -n "$l" ]
80+
81+
if __shell_is_bash || __shell_is_ksh; then
82+
[ $i -lt "${#l}" ] ||
83+
return 1
84+
else
85+
[ -n "$l" ] ||
86+
return 1
87+
fi
6688
}
6789

6890
# Usage: __shell_string_foreach_continue ctxvar
@@ -77,14 +99,22 @@ __shell_string_foreach_continue()
7799
# Usage: __shell_string_foreach_char retchar ctxvar
78100
__shell_string_foreach_char()
79101
{
80-
eval "$1=\"\${${2}_line%\$${2}_mask}\""
102+
if __shell_is_bash || __shell_is_ksh; then
103+
eval "$1=\"\${${2}_line:\$${2}_i:1}\""
104+
else
105+
eval "$1=\"\${${2}_line%\$${2}_mask}\""
106+
fi
81107
}
82108

83109
# Usage: __shell_string_foreach_char ctxvar
84110
__shell_string_foreach_iter()
85111
{
86-
eval "${1}_line=\"\${${1}_line#?}\""
87-
eval "${1}_mask=\"\${${1}_mask#?}\""
112+
if __shell_is_bash || __shell_is_ksh; then
113+
eval "${1}_i=\$(( \$${1}_i + 1 ))"
114+
else
115+
eval "${1}_line=\"\${${1}_line#?}\""
116+
eval "${1}_mask=\"\${${1}_mask#?}\""
117+
fi
88118
}
89119

90120
fi #__included_shell_string

0 commit comments

Comments
 (0)