Add array utilities append and in_array.
[matthijs/upstream/backupninja.git] / lib / array.in
1 # -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
2 # vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
3
4 # Append $2, $3, etc. to the array variable pointed to by $1.
5 # For example:
6 #   $ foo=(a)
7 #   $ append foo b c
8 #   $ echo "${foo[@]}"
9 #   a b c
10 # It can be used to concatenate arrays too:
11 #   $ append foo "${foo[@]}"
12 #   $ echo "${foo[@]}"  
13 #   a b c a b c
14 function append {
15    # Get the variable name, so $@ only contains the elements to append
16    varname="$1"
17    shift
18    # Here we quote the entire string passed to eval to prevent the
19    # normal braces from creating parse errors. We also escape the $ in
20    # the value, to ensure no stuff like pathname expansion is
21    # performed on it (since $@ could contain anything). We can safely
22    # expand $varname before evaluation, since we can be pretty sure that a
23    # valid variable name does not contain any weird stuff like backticks
24    # or tildes.
25    # We need this eval in the first place to do indirect assignment and
26    # indirectly reference the old value. The former could be done using
27    # some export hack, which is perhaps a bit more elegant, but the
28    # latter is not possible without eval it seems (there is the ${!var}
29    # syntax, but stupid bash has assigned a different meaning to
30    # ${!var[@]}, so you can't indirectly reference an array...
31    eval "$varname=(\"\${$varname[@]}\" \"\$@\")"
32 }
33
34 # Does $1 occur in $2, $3, etc.?
35 function in_array {
36    search=$1
37    shift
38    for i in "$@"; do
39       if [ x"$i" == x"$search" ]; then
40             # Found
41             return 0
42       fi
43    done
44    # Not found
45    return 1
46 }