Add array utilities append and in_array.
[matthijs/upstream/backupninja.git] / lib / array.in
diff --git a/lib/array.in b/lib/array.in
new file mode 100644 (file)
index 0000000..066e963
--- /dev/null
@@ -0,0 +1,46 @@
+# -*- mode: sh; sh-basic-offset: 3; indent-tabs-mode: nil; -*-
+# vim: set filetype=sh sw=3 sts=3 expandtab autoindent:
+
+# Append $2, $3, etc. to the array variable pointed to by $1.
+# For example:
+#   $ foo=(a)
+#   $ append foo b c
+#   $ echo "${foo[@]}"
+#   a b c
+# It can be used to concatenate arrays too:
+#   $ append foo "${foo[@]}"
+#   $ echo "${foo[@]}"  
+#   a b c a b c
+function append {
+   # Get the variable name, so $@ only contains the elements to append
+   varname="$1"
+   shift
+   # Here we quote the entire string passed to eval to prevent the
+   # normal braces from creating parse errors. We also escape the $ in
+   # the value, to ensure no stuff like pathname expansion is
+   # performed on it (since $@ could contain anything). We can safely
+   # expand $varname before evaluation, since we can be pretty sure that a
+   # valid variable name does not contain any weird stuff like backticks
+   # or tildes.
+   # We need this eval in the first place to do indirect assignment and
+   # indirectly reference the old value. The former could be done using
+   # some export hack, which is perhaps a bit more elegant, but the
+   # latter is not possible without eval it seems (there is the ${!var}
+   # syntax, but stupid bash has assigned a different meaning to
+   # ${!var[@]}, so you can't indirectly reference an array...
+   eval "$varname=(\"\${$varname[@]}\" \"\$@\")"
+}
+
+# Does $1 occur in $2, $3, etc.?
+function in_array {
+   search=$1
+   shift
+   for i in "$@"; do
+      if [ x"$i" == x"$search" ]; then
+            # Found
+            return 0
+      fi
+   done
+   # Not found
+   return 1
+}