# A simple print statement
function print() {
- printf "$@\n"
+ local fmt=${1}; shift
+
+ printf -- "${fmt}\n" "$@"
+}
+
+# The args() function takes a number of arguments like
+# var1="abc d" var2="abc" var3="abcd e"
+# and splits them into several arguments, devided by newline
+function args() {
+ echo "$@" | xargs printf "%s\n"
+}
+
+function unquote() {
+ local var="$@"
+
+ if [ "${var:0:1}" = "\"" ]; then
+ var=${var:1}
+ fi
+
+ local last=$(( ${#var} - 1 ))
+ if [ ${last} -ge 0 ] && [ "${var:${last}:1}" = "\"" ]; then
+ var=${var:0:${last}}
+ fi
+
+ print "${var}"
+}
+
+function quote() {
+ print "\"%s\"" "$@"
+}
+
+function strip() {
+ local value="$@"
+
+ # remove leading whitespace characters
+ value="${value#"${value%%[![:space:]]*}"}"
+
+ # remove trailing whitespace characters
+ value="${value%"${value##*[![:space:]]}"}"
+
+ print "${value}"
}
# Print a pretty error message
function error() {
- echo -e " ${COLOUR_ERROR}ERROR${COLOUR_NORMAL} : $@" >&2
+ echo -e " ${CLR_RED_B}ERROR${CLR_RESET} : $@" >&2
}
function error_log() {
# Print a pretty warn message
function warning() {
- echo -e " ${COLOUR_WARN}WARNING${COLOUR_NORMAL}: $@" >&2
+ echo -e " ${CLR_YELLOW_B}WARNING${CLR_RESET}: $@" >&2
}
function warning_log() {
log WARNING "$@"
}
+# The next three functions are kept for backwards
+# compatibility. The need to be dropped at some time.
function listsort() {
- local i
- for i in $@; do
- echo "${i}"
- done | sort | tr '\n' ' '
- echo
+ list_sort $@
}
function listmatch() {
- local match=${1}
- shift
-
- assert isset match
-
- local i
- for i in $@; do
- [ "${match}" = "${i}" ] && return ${EXIT_OK}
- done
-
- return ${EXIT_ERROR}
+ list_match $@
}
function listlength() {
- local length=0
-
- local i
- for i in $@; do
- length=$(( ${length} + 1 ))
- done
-
- echo "${length}"
+ list_length $@
}
# Speedup function to avoid a call of the basename binary
echo "${1##*/}"
}
-function touch() {
+function format() {
+ local key=${1}
+ assert isset key
+
+ local format=${2}
+ assert isset format
+
+ shift 2
+
+ printf -v "${key}" "${format}" "$@"
+}
+
+function assign() {
+ local key=${1}
+ assert isset key
+ shift
+
+ format "${key}" "%s" "$@"
+}
+
+function fread() {
local file=${1}
+ assert isset file
- : > ${file}
+ [ -r "${file}" ] || return ${EXIT_ERROR}
+
+ print "$(<${file})"
+}
+
+function fwrite() {
+ local file=${1}
+ assert isset file
+ shift
+
+ print "%s" "$@" >> ${file}
}
function enabled() {
local param=${1}
- [ "${!param}" = "yes" ] || [ "${!param}" = "on" ] || [ "${!param}" = "1" ]
+ list_match "${!param}" yes on true 1
}
function mac_generate() {
function mac_format() {
local mac=${1}
+ assert isset mac
- local output
+ # Remove all colons and make the rest lowercase.
+ mac=${mac//:/}
+ mac=${mac,,}
+ local output
if [ "${#mac}" = "12" ]; then
# Add colons (:) to mac address
output=${mac:0:2}
for i in 2 4 6 8 10; do
output="${output}:${mac:${i}:2}"
done
+ else
+ output=${mac}
fi
assert mac_is_valid ${output}
- echo "${output}"
+ print "${output}"
}
function mac_is_valid() {
[ -n "${!var}" ]
}
-# XXX Nearly same as listmatch
function isoneof() {
local var=${!1}
shift
- for i in $@; do
- [ "${var}" = "${i}" ] && return ${EXIT_OK}
- done
-
- return ${EXIT_ERROR}
+ list_match "${var}" "$@"
}
function isbool() {
mac_is_valid ${mac}
}
+function isipaddress() {
+ local addr=${!1}
+
+ ip_is_valid ${addr}
+}
+
function backtrace() {
local start=1
echo # Empty line
error_log "Backtrace (most recent call in first line):"
- local i
+ local i source
for i in $(seq ${start} ${#BASH_SOURCE[*]}); do
[ -z "${FUNCNAME[${i}]}" ] && continue
- [ "${FUNCNAME[${i}]}" == "main" ] && continue
- error_log " $(printf "%20s" "'${FUNCNAME[${i}]}'") called from ${BASH_SOURCE[$(( ${i} + 1 ))]}:${BASH_LINENO[${i}]}"
+ # Print called binary with arguments.
+ if [ "${FUNCNAME[${i}]}" == "main" ]; then
+ local args="$(list_reverse ${BASH_ARGV[*]})"
+ printf -v source "%20s" "$0"
+ error_log " ${source} ${args}"
+ continue
+ fi
+
+ source=${BASH_SOURCE[$(( ${i} + 1 ))]}
+ error_log " $(printf "%20s" "'${FUNCNAME[${i}]}'") called from ${source:-<shell>}:${BASH_LINENO[${i}]}"
done
}
if ! ${assertion}; then
error_log "Assertion '${assertion}' failed."
backtrace
- exit ${EXIT_ERROR}
+ exit ${EXIT_ERROR_ASSERT}
fi
return ${EXIT_OK}
}
+# This function checks, if the given argument is an assert error
+# exit code. If this is the case, the script will halt immediately.
+function assert_check_retval() {
+ local ret=${1}
+
+ if [ ${ret} -eq ${EXIT_ERROR_ASSERT} ]; then
+ exit ${EXIT_ERROR_ASSERT}
+ fi
+
+ return ${ret}
+}
+
function exec_cmd() {
local cmd=$@
cmd $@ &>/dev/null
}
+function cmd_exec() {
+ local cmd=$@
+
+ log DEBUG "Exec'ing command: ${cmd}"
+
+ exec ${cmd}
+
+ log ERROR "Could not exec-ute: ${cmd}"
+ exit ${EXIT_ERROR}
+}
+
+function cmd_not_implemented() {
+ assert false "not implemented"
+}
+
function seq() {
if [ $# -eq 2 ]; then
eval echo {${1}..${2}}
fi
}
+function which() {
+ type -P $@
+}
+
+# Prints the number of seconds since epoch.
+function timestamp() {
+ date -u "+%s"
+}
+
function beautify_time() {
local value=${1}
printf "%d\n" "${hex}"
}
+function chr() {
+ local char="${1}"
+
+ [ ${char} -lt 256 ] || return ${EXIT_ERROR}
+
+ printf "\\$(( ${char} / 64 * 100 + ${char} % 64 / 8 * 10 + ${char} % 8 ))\n"
+}
+
+function ord() {
+ LC_CTYPE="C" printf "%d\n" "'${1}"
+}
+
+function hex() {
+ printf "%X\n" "${1}"
+}
+
function network_is_running() {
# Check, if the network service is running.
service_is_active network
}
+
+function contains_spaces() {
+ local var="$@"
+
+ # Eliminate spaces.
+ local var2=${var// /}
+
+ if [ ${#var} -ne ${#var2} ]; then
+ return ${EXIT_TRUE}
+ fi
+
+ return ${EXIT_FALSE}
+}
+
+function string_split() {
+ local string="$@"
+
+ local pos=0
+ while [ ${pos} -lt ${#string} ]; do
+ print "${string:${pos}:1}"
+ pos=$(( ${pos} + 1 ))
+ done
+
+ return ${EXIT_OK}
+}
+
+function string_reverse() {
+ local string="$@"
+
+ local output
+ local pos=0
+ while [ ${pos} -lt ${#string} ]; do
+ output="${string:${pos}:1}${output}"
+ pos=$(( ${pos} + 1 ))
+ done
+
+ print "${output}"
+ return ${EXIT_OK}
+}
+
+function dec2bin() {
+ local number="${1}"
+
+ local output
+
+ local i div
+ for i in 7 6 5 4 3 2 1; do
+ div=$(( 2 ** ${i} ))
+
+ if [ $(( ${number} / ${div} )) -eq 1 ]; then
+ output="${output}1"
+ else
+ output="${output}0"
+ fi
+ number="$(( ${number} % ${div} ))"
+ done
+
+ if [ $(( ${number} % 2 )) -eq 1 ]; then
+ output="${output}1"
+ else
+ output="${output}0"
+ fi
+
+ print "${output}"
+}
+
+function bin2dec() {
+ local string="${1}"
+ local number=0
+
+ local pos=0 char
+ while [ ${pos} -lt ${#string} ]; do
+ char="${string:${pos}:1}"
+ pos=$(( ${pos} + 1 ))
+
+ number=$(( ${number} << 1 ))
+
+ case "${char}" in
+ 0) ;;
+ 1)
+ number=$(( ${number} + 1 ))
+ ;;
+ *)
+ assert false "Invalid character: ${char}"
+ ;;
+ esac
+ done
+
+ print "${number}"
+ return ${EXIT_OK}
+}
+
+function char2bin() {
+ local dec="$(ord "${1}")"
+
+ dec2bin "${dec}"
+}
+
+function bin2char() {
+ local dec="$(bin2dec "$@")"
+
+ chr "${dec}"
+}
+
+function bin2hex() {
+ local dec="$(bin2dec "$@")"
+
+ dec2hex "${dec}"
+}
+
+function hex2bin() {
+ local dec="$(hex2dec "$@")"
+
+ dec2bin "${dec}"
+}
+
+function hex2dec() {
+ local hex="${1}"
+
+ # Prepend 0x if necessary.
+ [ "${hex:0:2}" = "0x" ] || hex="0x${hex}"
+
+ printf "%d\n" "${hex}"
+}
+
+function dec2hex() {
+ printf "%02x\n" "${1}"
+}