-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathshell-string
More file actions
117 lines (101 loc) · 2.85 KB
/
Copy pathshell-string
File metadata and controls
117 lines (101 loc) · 2.85 KB
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
#!/bin/sh -efu
### This file is covered by the GNU General Public License,
### which should be included with libshell as the file LICENSE.
### All copyright information are listed in the COPYING.
if [ -z "${__included_shell_string-}" ]; then
__included_shell_string=1
### Creates a mask of equal length string.
### The mask is shorter than the string by one character unless
### the full-length flag is present, in which case it has the same
### length as the string.
### Usage: fill_mask var str [full-length]
fill_mask()
{
local m='' p='?' n
n="${#2}"
[ "$#" -eq 2 ] && n=$(( n - 1 ))
# Build the mask by doubling the pattern: each round handles two
# bits of the requested length, so the loop runs log2(n) times
# and the total amount of copied data is O(n) instead of the
# O(n^2) of growing the mask one character at a time.
while [ "$n" -gt 0 ]; do
if [ $(( n % 2 )) -eq 1 ]; then
m="$m$p"
fi
n=$(( n / 2 ))
p="$p$p"
done
eval "$1=\"$m\""
}
__shell_is_bash()
{
[ -n "${BASH-}" ] && [ -n "${BASH_VERSION-}" ]
}
__shell_is_ksh()
{
[ -n "${KSH_VERSION-}" ]
}
if ! __shell_is_bash && ! __shell_is_ksh; then
# Iteration primitives for the remaining shells (dash, ash, ...).
# The walked string is trimmed one character at a time, each character
# being obtained as the first character of the current string:
# c="${l%"${l#?}"}"
# where the quoted ${l#?} is treated as a literal string, so neither
# glob characters nor any code embedded in the walked string can
# change the meaning of the expansion.
__shell_string_foreach_condition()
{
eval "[ \${#$1} -gt 0 ]" ||
return 1
}
__shell_string_foreach_char()
{
eval "$1=\"\${$2%\"\${$2#?}\"}\""
}
__shell_string_foreach_iter()
{
eval "$1=\"\${$1#?}\""
}
else
# Iteration primitives for shells with `${parameter:offset:length}'
# expansion (bash, ksh). The walked string is addressed by an index
# stored in a companion ${1}_i variable.
__shell_string_foreach_condition()
{
eval "set -- \"\$${1}_i\" \"\${#$1}\""
[ $1 -lt "$2" ] ||
return 1
}
__shell_string_foreach_char()
{
eval "$1=\"\${$2:\$$2_i:1}\""
}
__shell_string_foreach_iter()
{
eval "${1}_i=\$(( \$$1_i + 1 ))"
}
fi
# Usage: __shell_string_foreach_prepare var
### Prepare the variable for the per-character traversal helpers.
### The caller owns the string; the traversal state is kept in a
### companion ${var}_i variable.
__shell_string_foreach_prepare()
{
eval "${1}_i=0"
}
# Usage: __shell_string_foreach_finish var
__shell_string_foreach_finish()
{
unset "${1}_i"
}
# Usage: __shell_string_foreach_continue var
### Returns success while characters remain in the walked string, and
### calls __shell_string_foreach_finish when it becomes empty.
__shell_string_foreach_continue()
{
if ! __shell_string_foreach_condition "$1"; then
__shell_string_foreach_finish "$1"
return 1
fi
}
fi #__included_shell_string