592f2dbd82
When traversing arrays of tables or arrays of array it is required to call json_select # where # is the index of the array item to select. Internally json_select() calls json_get_var() to obtain the correct prefix to populate $JSON_CUR with. However, the "tr" call in json_get_var() incorrectly replaces all digits with underscores, making any lookup for numeric array items fail. The attached patch changes the "tr" expression to allow digits and thus implements the expected behaviour for nested arrays.
135 lines
2.6 KiB
Bash
135 lines
2.6 KiB
Bash
# functions for parsing and generating json
|
|
|
|
jshn_append() {
|
|
local var="$1"
|
|
local value="$2"
|
|
local sep="${3:- }"
|
|
|
|
eval "export -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""
|
|
}
|
|
|
|
json_init() {
|
|
[ -n "$JSON_UNSET" ] && eval "unset $JSON_UNSET"
|
|
export -- JSON_SEQ=0 JSON_STACK= JSON_CUR="JSON_VAR" JSON_UNSET="" KEYS_JSON_VAR= TYPE_JSON_VAR=
|
|
}
|
|
|
|
json_add_generic() {
|
|
local type="$1"
|
|
local var="$2"
|
|
local val="$3"
|
|
local cur="${4:-$JSON_CUR}"
|
|
|
|
if [ "${cur%%[0-9]*}" = "JSON_ARRAY" ]; then
|
|
eval "local aseq=\"\${SEQ_$cur}\""
|
|
var=$(( ${aseq:-0} + 1 ))
|
|
export -- "SEQ_$cur=$var"
|
|
else
|
|
local name="$(echo -n "$var" | tr -C '[a-zA-Z_]' _)"
|
|
[[ "$name" == "$var" ]] || export -- "NAME_${cur}_${name}=$var"
|
|
var="$name"
|
|
fi
|
|
|
|
export -- "${cur}_$var=$val"
|
|
export -- "TYPE_${cur}_$var=$type"
|
|
jshn_append JSON_UNSET "${cur}_$var TYPE_${cur}_$var"
|
|
jshn_append "KEYS_${cur}" "$var"
|
|
}
|
|
|
|
json_add_table() {
|
|
local TYPE="$1"
|
|
JSON_SEQ=$(($JSON_SEQ + 1))
|
|
jshn_append JSON_STACK "$JSON_CUR"
|
|
local table="JSON_$TYPE$JSON_SEQ"
|
|
export -- "UP_$table=$JSON_CUR"
|
|
export -- "KEYS_$table="
|
|
jshn_append JSON_UNSET "KEYS_$table UP_$table"
|
|
[ "$TYPE" = "ARRAY" ] && jshn_append JSON_UNSET "SEQ_$table"
|
|
JSON_CUR="$table"
|
|
}
|
|
|
|
json_add_object() {
|
|
local cur="$JSON_CUR"
|
|
json_add_table TABLE
|
|
json_add_generic object "$1" "$JSON_CUR" "$cur"
|
|
}
|
|
|
|
json_close_object() {
|
|
local oldstack="$JSON_STACK"
|
|
JSON_CUR="${JSON_STACK##* }"
|
|
JSON_STACK="${JSON_STACK% *}"
|
|
[[ "$oldstack" == "$JSON_STACK" ]] && JSON_STACK=
|
|
}
|
|
|
|
json_add_array() {
|
|
local cur="$JSON_CUR"
|
|
json_add_table ARRAY
|
|
json_add_generic array "$1" "$JSON_CUR" "$cur"
|
|
}
|
|
|
|
json_close_array() {
|
|
json_close_object
|
|
}
|
|
|
|
json_add_string() {
|
|
json_add_generic string "$1" "$2"
|
|
}
|
|
|
|
json_add_int() {
|
|
json_add_generic int "$1" "$2"
|
|
}
|
|
|
|
json_add_boolean() {
|
|
json_add_generic boolean "$1" "$2"
|
|
}
|
|
|
|
# functions read access to json variables
|
|
|
|
json_load() {
|
|
eval `jshn -r "$1"`
|
|
}
|
|
|
|
json_dump() {
|
|
jshn "$@" -w
|
|
}
|
|
|
|
json_get_type() {
|
|
local dest="$1"
|
|
local var="$2"
|
|
eval "export -- \"$dest=\${TYPE_${JSON_CUR}_$var}\""
|
|
}
|
|
|
|
json_get_var() {
|
|
local dest="$1"
|
|
local var="$(echo -n "$2" | tr -C '[a-zA-Z0-9_]' _)"
|
|
eval "export -- \"$dest=\${${JSON_CUR}_$var}\""
|
|
}
|
|
|
|
json_get_vars() {
|
|
while [ "$#" -gt 0 ]; do
|
|
local _var="$1"; shift
|
|
json_get_var "$_var" "$_var"
|
|
done
|
|
}
|
|
|
|
json_select() {
|
|
local target="$1"
|
|
local type
|
|
|
|
[ -z "$1" ] && {
|
|
JSON_CUR="JSON_VAR"
|
|
return
|
|
}
|
|
[[ "$1" == ".." ]] && {
|
|
eval "JSON_CUR=\"\${UP_$JSON_CUR}\""
|
|
return;
|
|
}
|
|
json_get_type type "$target"
|
|
case "$type" in
|
|
object|array)
|
|
json_get_var JSON_CUR "$target"
|
|
;;
|
|
*)
|
|
echo "WARNING: Variable '$target' does not exist or is not an array/object"
|
|
;;
|
|
esac
|
|
}
|