| # 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 |
| } |