218 lines
4.6 KiB
Modula-2
218 lines
4.6 KiB
Modula-2
|
#!/bin/bash
|
||
|
#
|
||
|
# Author: Hugo Thunnissen <hugo.thunnissen@gmail.com>
|
||
|
# License: see LICENSE file.
|
||
|
#
|
||
|
##
|
||
|
# Utility functions for common array operations.
|
||
|
# To prevent circular references, none of the functions allow
|
||
|
# usage on an array named "array", and some won't allow the usage
|
||
|
# of an array by the name "oth_array" for a second arrayname that is passed.
|
||
|
# Functions that do variable assignment won't allow the usage of a variable
|
||
|
# by the name "variable".
|
||
|
#
|
||
|
##
|
||
|
|
||
|
## IMPPORTANT: CANNOT DO THIS IN A SUBSHELL i.e. $( )
|
||
|
|
||
|
##
|
||
|
# Check if an array is eligible to use the functions on.
|
||
|
# return values:
|
||
|
# 1: Array variable has not been set.
|
||
|
# 2: The array variable is named "array"
|
||
|
#
|
||
|
|
||
|
|
||
|
# array, string, delimiter
|
||
|
function String::split() {
|
||
|
#!/bin/bash
|
||
|
Array::isValid "$1" || return $?
|
||
|
[[ $2 ]] || return 1
|
||
|
delimiter=${3:-" "}
|
||
|
s=$2$delimiter
|
||
|
# echo del: $delimiter
|
||
|
# echo string: $s
|
||
|
declare -n array="$1"
|
||
|
while [[ $s ]]; do
|
||
|
array+=( "${s%%"$delimiter"*}" );
|
||
|
# echo added element now: ${array[@]}
|
||
|
s=${s#*"$delimiter"};
|
||
|
# echo remains: $s
|
||
|
done;
|
||
|
}
|
||
|
|
||
|
function Array::isValid() {
|
||
|
if ! declare -p "$1" &>>/dev/null; then
|
||
|
echo 'Array: Array variable needs to be set.' >&2
|
||
|
return 1
|
||
|
elif [[ $1 == array ]]; then
|
||
|
echo 'Array: Array variable can not be named "array"' >&2
|
||
|
return 2
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Check if a variable can be assigned.
|
||
|
# return values:
|
||
|
# 3: The variable has not yet been declared
|
||
|
# 5: The variable is named "variable"
|
||
|
#
|
||
|
# $1 variable_name
|
||
|
function Array::varIsValid() {
|
||
|
if ! [[ -v $1 ]]; then
|
||
|
echo 'Array: Variable needs to be declared before assigning to it.' >&2
|
||
|
return 3
|
||
|
elif [[ $1 == variable ]]; then
|
||
|
echo 'Array: Variable cannot be named "variable"' >&2
|
||
|
return 5
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# pop an array
|
||
|
# return values:
|
||
|
# 4: array size is 0
|
||
|
# other: see Array::isValid
|
||
|
#
|
||
|
# $1: array_name
|
||
|
function Array::pop() {
|
||
|
Array::isValid "$1" || return $?
|
||
|
|
||
|
declare -n array="$1"
|
||
|
[[ ${#array[@]} -gt 0 ]] || return 4
|
||
|
|
||
|
unset 'array[-1]'
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Pop an array and assign the popped value to a variable
|
||
|
# return values:
|
||
|
# 4: array size is 0
|
||
|
# other: see Array::isValid and Array::varIsValid
|
||
|
#
|
||
|
# $1: array_name
|
||
|
# $2: variable_name
|
||
|
function Array::popToVar() {
|
||
|
Array::isValid "$1" || return $?
|
||
|
Array::varIsValid "$2" || return $?
|
||
|
|
||
|
declare -n array="$1" variable="$2"
|
||
|
[[ ${#array[@]} -gt 0 ]] || return 4
|
||
|
variable="${array[-1]}"
|
||
|
|
||
|
Array::pop "$1"
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Shift an array.
|
||
|
# $1: array_name
|
||
|
function Array::shift() {
|
||
|
Array::isValid "$1" || return $?
|
||
|
|
||
|
declare -n array="$1"
|
||
|
declare -i shift_amount="$2"
|
||
|
((shift_amount = shift_amount == 0 ? ++shift_amount : shift_amount))
|
||
|
[[ ${#array[@]} -gt 0 ]] || return 4
|
||
|
set -- "${array[@]}"
|
||
|
shift $shift_amount
|
||
|
|
||
|
array=("$@")
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Shift an array and assign the shifted value to a variable
|
||
|
# $1: array_name
|
||
|
# $2: variable_name
|
||
|
function Array::shiftToVar() {
|
||
|
Array::isValid "$1" || return $?
|
||
|
Array::varIsValid "$2" || return $?
|
||
|
|
||
|
# TODO: Add shifting to multiple variables
|
||
|
declare -n array="$1" variable="$2"
|
||
|
[[ ${#array[@]} -gt 0 ]] || return 4
|
||
|
variable="${array[0]}"
|
||
|
|
||
|
Array::shift "$1"
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Push a value to an array
|
||
|
# $1: array_name
|
||
|
# $2: value
|
||
|
function Array::push() {
|
||
|
Array::isValid "$1" || return $?
|
||
|
declare -n array="$1"
|
||
|
shift
|
||
|
|
||
|
array=("${array[@]}" "$@")
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Unshift a value to an array
|
||
|
# $1: array_name
|
||
|
# $*: values
|
||
|
function Array::unshift() {
|
||
|
Array::isValid "$1" || return $?
|
||
|
declare -n array="$1"
|
||
|
shift
|
||
|
|
||
|
array=("$@" "${array[@]}")
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Map through an array with a callback and assign the yielded values
|
||
|
# to the defined array.
|
||
|
# $1: array_name
|
||
|
# $2: array_to_be_assigned_to_name (may not be "oth_array")
|
||
|
# $3: callback_name
|
||
|
function Array::map() {
|
||
|
if ! declare -F "$3" &>>/dev/null; then
|
||
|
echo 'Array: Error, $3 for Array::map must be a function name'
|
||
|
return 6
|
||
|
fi
|
||
|
Array::isValid "$1" || return $?
|
||
|
Array::isValid "$2" || return $?
|
||
|
|
||
|
declare -n array="$1"
|
||
|
declare -a oth_array=()
|
||
|
declare func="$3" in_Array_map="true"
|
||
|
|
||
|
for item in "${array[@]}"; do
|
||
|
"$func" "$item"
|
||
|
done
|
||
|
|
||
|
declare -n array="$2"
|
||
|
|
||
|
array=("${oth_array[@]}")
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Strictly for use in Array::map callbacks.
|
||
|
# $1: Variable that should be added to the new array
|
||
|
function Array::yield() {
|
||
|
[[ "$in_Array_map" == true ]] && oth_array=("${oth_array[@]}" "$@")
|
||
|
}
|
||
|
|
||
|
##
|
||
|
# Check if an array has a certain value stored in it.
|
||
|
# $1: arrayname
|
||
|
# $2: value
|
||
|
function Array::hasValue() {
|
||
|
if ! Array::isValid "$1"; then
|
||
|
echo "$(caller): $1 is not a valid array."
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
declare -n array="$1"
|
||
|
|
||
|
if [[ $2 == +([0-9]) ]]; then
|
||
|
for item in "${array[@]}"; do
|
||
|
[[ $2 -eq $item ]] && return 0
|
||
|
done
|
||
|
else
|
||
|
for item in "${array[@]}"; do
|
||
|
[[ "$2" == "$item" ]] && return 0
|
||
|
done
|
||
|
fi
|
||
|
return 1
|
||
|
}
|