1# string.bash --- bash emulation of string(3) library routines
2# Author: Noah Friedman <friedman@prep.ai.mit.edu>
3# Created: 1992-07-01
4# Last modified: 1993-09-29
5# Public domain
6
7# Conversion to bash v2 syntax done by Chet Ramey
8
9# Commentary:
10# Code:
11
12#:docstring strcat:
13# Usage: strcat s1 s2
14#
15# Strcat appends the value of variable s2 to variable s1. 
16#
17# Example:
18#    a="foo"
19#    b="bar"
20#    strcat a b
21#    echo $a
22#    => foobar
23#
24#:end docstring:
25
26###;;;autoload
27function strcat ()
28{
29    local s1_val s2_val
30
31    s1_val=${!1}			# indirect variable expansion
32    s2_val=${!2}
33    eval "$1"=\'"${s1_val}${s2_val}"\'
34}
35
36#:docstring strncat:
37# Usage: strncat s1 s2 $n
38# 
39# Line strcat, but strncat appends a maximum of n characters from the value
40# of variable s2.  It copies fewer if the value of variabl s2 is shorter
41# than n characters.  Echoes result on stdout.
42#
43# Example:
44#    a=foo
45#    b=barbaz
46#    strncat a b 3
47#    echo $a
48#    => foobar
49#
50#:end docstring:
51
52###;;;autoload
53function strncat ()
54{
55    local s1="$1"
56    local s2="$2"
57    local -i n="$3"
58    local s1_val s2_val
59
60    s1_val=${!s1}			# indirect variable expansion
61    s2_val=${!s2}
62
63    if [ ${#s2_val} -gt ${n} ]; then
64       s2_val=${s2_val:0:$n}		# substring extraction
65    fi
66
67    eval "$s1"=\'"${s1_val}${s2_val}"\'
68}
69
70#:docstring strcmp:
71# Usage: strcmp $s1 $s2
72#
73# Strcmp compares its arguments and returns an integer less than, equal to,
74# or greater than zero, depending on whether string s1 is lexicographically
75# less than, equal to, or greater than string s2.
76#:end docstring:
77
78###;;;autoload
79function strcmp ()
80{
81    [ "$1" = "$2" ] && return 0
82
83    [ "${1}" '<' "${2}" ] > /dev/null && return -1
84
85    return 1
86}
87
88#:docstring strncmp:
89# Usage: strncmp $s1 $s2 $n
90# 
91# Like strcmp, but makes the comparison by examining a maximum of n
92# characters (n less than or equal to zero yields equality).
93#:end docstring:
94
95###;;;autoload
96function strncmp ()
97{
98    if [ -z "${3}" ] || [ "${3}" -le "0" ]; then
99       return 0
100    fi
101   
102    if [ ${3} -ge ${#1} ] && [ ${3} -ge ${#2} ]; then
103       strcmp "$1" "$2"
104       return $?
105    else
106       s1=${1:0:$3}
107       s2=${2:0:$3}
108       strcmp $s1 $s2
109       return $?
110    fi
111}
112
113#:docstring strlen:
114# Usage: strlen s
115#
116# Strlen returns the number of characters in string literal s.
117#:end docstring:
118
119###;;;autoload
120function strlen ()
121{
122    eval echo "\${#${1}}"
123}
124
125#:docstring strspn:
126# Usage: strspn $s1 $s2
127# 
128# Strspn returns the length of the maximum initial segment of string s1,
129# which consists entirely of characters from string s2.
130#:end docstring:
131
132###;;;autoload
133function strspn ()
134{
135    # Unsetting IFS allows whitespace to be handled as normal chars. 
136    local IFS=
137    local result="${1%%[!${2}]*}"
138 
139    echo ${#result}
140}
141
142#:docstring strcspn:
143# Usage: strcspn $s1 $s2
144#
145# Strcspn returns the length of the maximum initial segment of string s1,
146# which consists entirely of characters not from string s2.
147#:end docstring:
148
149###;;;autoload
150function strcspn ()
151{
152    # Unsetting IFS allows whitspace to be handled as normal chars. 
153    local IFS=
154    local result="${1%%[${2}]*}"
155 
156    echo ${#result}
157}
158
159#:docstring strstr:
160# Usage: strstr s1 s2
161# 
162# Strstr echoes a substring starting at the first occurrence of string s2 in
163# string s1, or nothing if s2 does not occur in the string.  If s2 points to
164# a string of zero length, strstr echoes s1.
165#:end docstring:
166
167###;;;autoload
168function strstr ()
169{
170    # if s2 points to a string of zero length, strstr echoes s1
171    [ ${#2} -eq 0 ] && { echo "$1" ; return 0; }
172
173    # strstr echoes nothing if s2 does not occur in s1
174    case "$1" in
175    *$2*) ;;
176    *) return 1;;
177    esac
178
179    # use the pattern matching code to strip off the match and everything
180    # following it
181    first=${1/$2*/}
182
183    # then strip off the first unmatched portion of the string
184    echo "${1##$first}"
185}
186
187#:docstring strtok:
188# Usage: strtok s1 s2
189#
190# Strtok considers the string s1 to consist of a sequence of zero or more
191# text tokens separated by spans of one or more characters from the
192# separator string s2.  The first call (with a non-empty string s1
193# specified) echoes a string consisting of the first token on stdout. The
194# function keeps track of its position in the string s1 between separate
195# calls, so that subsequent calls made with the first argument an empty
196# string will work through the string immediately following that token.  In
197# this way subsequent calls will work through the string s1 until no tokens
198# remain.  The separator string s2 may be different from call to call.
199# When no token remains in s1, an empty value is echoed on stdout.
200#:end docstring:
201
202###;;;autoload
203function strtok ()
204{
205 :
206}
207
208#:docstring strtrunc:
209# Usage: strtrunc $n $s1 {$s2} {$...}
210#
211# Used by many functions like strncmp to truncate arguments for comparison.
212# Echoes the first n characters of each string s1 s2 ... on stdout. 
213#:end docstring:
214
215###;;;autoload
216function strtrunc ()
217{
218    n=$1 ; shift
219    for z; do
220	echo "${z:0:$n}"
221    done
222}
223
224provide string
225
226# string.bash ends here
227