bb0c830b2a
Function usefull to iterate through the different elements of an array or object; the provided callback function is called for each element which is passed the value, key and user provided arguments. For field types different from array or object the callback is called with the retrieved value. Signed-off-by: Hans Dedecker <dedeckeh@gmail.com> Acked-by: Jo-Philipp Wich <jo@mein.io>
315 lines
5.3 KiB
Bash
315 lines
5.3 KiB
Bash
# functions for parsing and generating json
|
|
|
|
_json_get_var() {
|
|
# dest=$1
|
|
# var=$2
|
|
eval "$1=\"\$${JSON_PREFIX}$2\""
|
|
}
|
|
|
|
_json_set_var() {
|
|
# var=$1
|
|
local ___val="$2"
|
|
eval "${JSON_PREFIX}$1=\"\$___val\""
|
|
}
|
|
|
|
__jshn_raw_append() {
|
|
# var=$1
|
|
local value="$2"
|
|
local sep="${3:- }"
|
|
|
|
eval "export -- \"$1=\${$1:+\${$1}\${value:+\$sep}}\$value\""
|
|
}
|
|
|
|
_jshn_append() {
|
|
# var=$1
|
|
local _a_value="$2"
|
|
eval "${JSON_PREFIX}$1=\"\${${JSON_PREFIX}$1} \$_a_value\""
|
|
}
|
|
|
|
_get_var() {
|
|
# var=$1
|
|
# value=$2
|
|
eval "$1=\"\$$2\""
|
|
}
|
|
|
|
_set_var() {
|
|
# var=$1
|
|
local __val="$2"
|
|
eval "$1=\"\$__val\""
|
|
}
|
|
|
|
_json_inc() {
|
|
# var=$1
|
|
# dest=$2
|
|
|
|
let "${JSON_PREFIX}$1 += 1" "$2 = ${JSON_PREFIX}$1"
|
|
}
|
|
|
|
_json_add_generic() {
|
|
# type=$1
|
|
# name=$2
|
|
# value=$3
|
|
# cur=$4
|
|
|
|
local var
|
|
if [ "${4%%[0-9]*}" = "J_A" ]; then
|
|
_json_inc "S_$4" var
|
|
else
|
|
var="${2//[^a-zA-Z0-9_]/_}"
|
|
[[ "$var" == "$2" ]] || export -- "${JSON_PREFIX}N_${4}_${var}=$2"
|
|
fi
|
|
|
|
export -- \
|
|
"${JSON_PREFIX}${4}_$var=$3" \
|
|
"${JSON_PREFIX}T_${4}_$var=$1"
|
|
_jshn_append "JSON_UNSET" "${4}_$var"
|
|
_jshn_append "K_$4" "$var"
|
|
}
|
|
|
|
_json_add_table() {
|
|
# name=$1
|
|
# type=$2
|
|
# itype=$3
|
|
local cur seq
|
|
|
|
_json_get_var cur JSON_CUR
|
|
_json_inc JSON_SEQ seq
|
|
|
|
local table="J_$3$seq"
|
|
_json_set_var "U_$table" "$cur"
|
|
export -- "${JSON_PREFIX}K_$table="
|
|
unset "${JSON_PREFIX}S_$table"
|
|
_json_set_var JSON_CUR "$table"
|
|
_jshn_append "JSON_UNSET" "$table"
|
|
|
|
_json_add_generic "$2" "$1" "$table" "$cur"
|
|
}
|
|
|
|
_json_close_table() {
|
|
local _s_cur
|
|
|
|
_json_get_var _s_cur JSON_CUR
|
|
_json_get_var "${JSON_PREFIX}JSON_CUR" "U_$_s_cur"
|
|
}
|
|
|
|
json_set_namespace() {
|
|
local _new="$1"
|
|
local _old="$2"
|
|
|
|
[ -n "$_old" ] && _set_var "$_old" "$JSON_PREFIX"
|
|
JSON_PREFIX="$_new"
|
|
}
|
|
|
|
json_cleanup() {
|
|
local unset tmp
|
|
|
|
_json_get_var unset JSON_UNSET
|
|
for tmp in $unset J_V; do
|
|
unset \
|
|
${JSON_PREFIX}U_$tmp \
|
|
${JSON_PREFIX}K_$tmp \
|
|
${JSON_PREFIX}S_$tmp \
|
|
${JSON_PREFIX}T_$tmp \
|
|
${JSON_PREFIX}N_$tmp \
|
|
${JSON_PREFIX}$tmp
|
|
done
|
|
|
|
unset \
|
|
${JSON_PREFIX}JSON_SEQ \
|
|
${JSON_PREFIX}JSON_CUR \
|
|
${JSON_PREFIX}JSON_UNSET
|
|
}
|
|
|
|
json_init() {
|
|
json_cleanup
|
|
export -n ${JSON_PREFIX}JSON_SEQ=0
|
|
export -- \
|
|
${JSON_PREFIX}JSON_CUR="J_V" \
|
|
${JSON_PREFIX}K_J_V=
|
|
}
|
|
|
|
json_add_object() {
|
|
_json_add_table "$1" object T
|
|
}
|
|
|
|
json_close_object() {
|
|
_json_close_table
|
|
}
|
|
|
|
json_add_array() {
|
|
_json_add_table "$1" array A
|
|
}
|
|
|
|
json_close_array() {
|
|
_json_close_table
|
|
}
|
|
|
|
json_add_string() {
|
|
local cur
|
|
_json_get_var cur JSON_CUR
|
|
_json_add_generic string "$1" "$2" "$cur"
|
|
}
|
|
|
|
json_add_int() {
|
|
local cur
|
|
_json_get_var cur JSON_CUR
|
|
_json_add_generic int "$1" "$2" "$cur"
|
|
}
|
|
|
|
json_add_boolean() {
|
|
local cur
|
|
_json_get_var cur JSON_CUR
|
|
_json_add_generic boolean "$1" "$2" "$cur"
|
|
}
|
|
|
|
json_add_double() {
|
|
local cur
|
|
_json_get_var cur JSON_CUR
|
|
_json_add_generic double "$1" "$2" "$cur"
|
|
}
|
|
|
|
json_add_null() {
|
|
local cur
|
|
_json_get_var cur JSON_CUR
|
|
_json_add_generic null "$1" "" "$cur"
|
|
}
|
|
|
|
# functions read access to json variables
|
|
|
|
json_load() {
|
|
eval "`jshn -r "$1"`"
|
|
}
|
|
|
|
json_load_file() {
|
|
eval "`jshn -R "$1"`"
|
|
}
|
|
|
|
json_dump() {
|
|
jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} -w
|
|
}
|
|
|
|
json_get_type() {
|
|
local __dest="$1"
|
|
local __cur
|
|
|
|
_json_get_var __cur JSON_CUR
|
|
local __var="${JSON_PREFIX}T_${__cur}_${2//[^a-zA-Z0-9_]/_}"
|
|
eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
|
|
}
|
|
|
|
json_get_keys() {
|
|
local __dest="$1"
|
|
local _tbl_cur
|
|
|
|
if [ -n "$2" ]; then
|
|
json_get_var _tbl_cur "$2"
|
|
else
|
|
_json_get_var _tbl_cur JSON_CUR
|
|
fi
|
|
local __var="${JSON_PREFIX}K_${_tbl_cur}"
|
|
eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
|
|
}
|
|
|
|
json_get_values() {
|
|
local _v_dest="$1"
|
|
local _v_keys _v_val _select=
|
|
local _json_no_warning=1
|
|
|
|
unset "$_v_dest"
|
|
[ -n "$2" ] && {
|
|
json_select "$2" || return 1
|
|
_select=1
|
|
}
|
|
|
|
json_get_keys _v_keys
|
|
set -- $_v_keys
|
|
while [ "$#" -gt 0 ]; do
|
|
json_get_var _v_val "$1"
|
|
__jshn_raw_append "$_v_dest" "$_v_val"
|
|
shift
|
|
done
|
|
[ -n "$_select" ] && json_select ..
|
|
|
|
return 0
|
|
}
|
|
|
|
json_get_var() {
|
|
local __dest="$1"
|
|
local __cur
|
|
|
|
_json_get_var __cur JSON_CUR
|
|
local __var="${JSON_PREFIX}${__cur}_${2//[^a-zA-Z0-9_]/_}"
|
|
eval "export -- \"$__dest=\${$__var:-$3}\"; [ -n \"\${$__var+x}\${3+x}\" ]"
|
|
}
|
|
|
|
json_get_vars() {
|
|
while [ "$#" -gt 0 ]; do
|
|
local _var="$1"; shift
|
|
if [ "$_var" != "${_var#*:}" ]; then
|
|
json_get_var "${_var%%:*}" "${_var%%:*}" "${_var#*:}"
|
|
else
|
|
json_get_var "$_var" "$_var"
|
|
fi
|
|
done
|
|
}
|
|
|
|
json_select() {
|
|
local target="$1"
|
|
local type
|
|
local cur
|
|
|
|
[ -z "$1" ] && {
|
|
_json_set_var JSON_CUR "J_V"
|
|
return 0
|
|
}
|
|
[[ "$1" == ".." ]] && {
|
|
_json_get_var cur JSON_CUR
|
|
_json_get_var cur "U_$cur"
|
|
_json_set_var JSON_CUR "$cur"
|
|
return 0
|
|
}
|
|
json_get_type type "$target"
|
|
case "$type" in
|
|
object|array)
|
|
json_get_var cur "$target"
|
|
_json_set_var JSON_CUR "$cur"
|
|
;;
|
|
*)
|
|
[ -n "$_json_no_warning" ] || \
|
|
echo "WARNING: Variable '$target' does not exist or is not an array/object"
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
json_is_a() {
|
|
local type
|
|
|
|
json_get_type type "$1"
|
|
[ "$type" = "$2" ]
|
|
}
|
|
|
|
json_for_each_item() {
|
|
[ "$#" -ge 2 ] || return 0
|
|
local function="$1"; shift
|
|
local target="$1"; shift
|
|
local type val
|
|
|
|
json_get_type type "$target"
|
|
case "$type" in
|
|
object|array)
|
|
local keys key
|
|
json_select "$target"
|
|
json_get_keys keys
|
|
for key in $keys; do
|
|
json_get_var val "$key"
|
|
eval "$function \"\$val\" \"\$key\" \"\$@\""
|
|
done
|
|
json_select ..
|
|
;;
|
|
*)
|
|
json_get_var val "$target"
|
|
eval "$function \"\$val\" \"\" \"\$@\""
|
|
;;
|
|
esac
|
|
}
|