#!/bin/bash
# qsort - pure bash qsort implementation
set -e
######
# Settings
core_qsort_config_init() {
lib_setting_vars qsort_compare_func
qsort_compare_func=compare_str_asc
}
######
# Internal functions
qsort_stack_push() { qsort_stack+=( "$@" ); }
qsort_stack_pop() { qsort_stack=( "${qsort_stack[@]:2}" ); }
######
# Public interface
# $1 - Array to receive sorted items
# ... - Items to sort
qsort() {
min_args 1 "$@"
local result=$1
shift
[ $# -gt 0 ] || return 0
local -a sorted=( "$@" )
local -a qsort_stack
local last=$(($# - 1))
qsort_stack_push 0 $last
local -a smaller larger
while (( ${#qsort_stack[@]} )); do
local a=${qsort_stack[0]}
local b=${qsort_stack[1]}
qsort_stack_pop
local pivot=${sorted[$a]}
local i
smaller=()
larger=()
for ((i = a + 1; i <= b; i++)); do
local value="${sorted[i]}"
local name
$qsort_compare_func "$value" "$pivot" \
&& smaller+=( $value ) \
|| larger+=( $value )
done
sorted=( \
"${sorted[@]:0:a}" \
"${smaller[@]}" "$pivot" "${larger[@]}" \
"${sorted[@]:b + 1:last - b}" \
)
if ((${#smaller[@]} >= 2)); then
qsort_stack_push $a $((a + ${#smaller[@]} - 1))
fi
if ((${#larger[@]} >= 2)); then
qsort_stack_push $((b - ${#larger[@]} + 1)) $b
fi
done
eval "$result=( \"\${sorted[@]}\" )"
}
# list_qsort - Sorts the list
qsort_list() {
has_args 1 "$@"
eval "qsort $1 \"\${$1[@]}\""
}
######
# Item comparison functions
compare_str_asc() { [[ "$1" < "$2" ]]; }
compare_str_dsc() { [[ "$1" > "$2" ]]; }
compare_int_asc() { (("$1" < "$2")); }
compare_int_dsc() { (("$1" > "$2")); }
compare_mtime() { [[ $1 -nt $2 ]]; }
Generated on Tue Apr 25 21:20:13 PDT 2017 by mcsh i7 v0.18.0.