sh/jshn.sh: replace "tr" calls with inline substitution, signalize success with retur...
[project/libubox.git] / sh / jshn.sh
index 63d4b09..a15cb00 100644 (file)
@@ -10,7 +10,7 @@ jshn_append() {
 
 json_init() {
        [ -n "$JSON_UNSET" ] && eval "unset $JSON_UNSET"
-       export -- JSON_SEQ=0 JSON_STACK= JSON_CUR="JSON_VAR" JSON_UNSET=
+       export -- JSON_SEQ=0 JSON_STACK= JSON_CUR="JSON_VAR" JSON_UNSET="" KEYS_JSON_VAR= TYPE_JSON_VAR=
 }
 
 json_add_generic() {
@@ -19,6 +19,16 @@ json_add_generic() {
        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="${var//[^a-zA-Z0-9_]/_}"
+               [[ "$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"
@@ -26,18 +36,20 @@ json_add_generic() {
 }
 
 json_add_table() {
+       local TYPE="$1"
        JSON_SEQ=$(($JSON_SEQ + 1))
        jshn_append JSON_STACK "$JSON_CUR"
-       local table="JSON_TABLE$JSON_SEQ"
+       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
+       json_add_table TABLE
        json_add_generic object "$1" "$JSON_CUR" "$cur"
 }
 
@@ -50,7 +62,7 @@ json_close_object() {
 
 json_add_array() {
        local cur="$JSON_CUR"
-       json_add_table
+       json_add_table ARRAY
        json_add_generic array "$1" "$JSON_CUR" "$cur"
 }
 
@@ -82,14 +94,21 @@ json_dump() {
 
 json_get_type() {
        local dest="$1"
-       local var="$2"
-       eval "export -- \"$dest=\${TYPE_${JSON_CUR}_$var}\""
+       local var="TYPE_${JSON_CUR}_$2"
+       eval "[ -n \"\${$var+x}\" ] && export -- \"$dest=\${$var}\""
 }
 
 json_get_var() {
        local dest="$1"
-       local var="$2"
-       eval "export -- \"$dest=\${${JSON_CUR}_$var}\""
+       local var="${JSON_CUR}_${2//[^a-zA-Z0-9_]/_}"
+       eval "[ -n \"\${$var+x}\" ] && export -- \"$dest=\${$var}\""
+}
+
+json_get_vars() {
+       while [ "$#" -gt 0 ]; do
+               local _var="$1"; shift
+               json_get_var "$_var" "$_var"
+       done
 }
 
 json_select() {
@@ -98,11 +117,11 @@ json_select() {
 
        [ -z "$1" ] && {
                JSON_CUR="JSON_VAR"
-               return
+               return 0
        }
        [[ "$1" == ".." ]] && {
                eval "JSON_CUR=\"\${UP_$JSON_CUR}\""
-               return;
+               return 0
        }
        json_get_type type "$target"
        case "$type" in
@@ -111,6 +130,7 @@ json_select() {
                ;;
                *)
                        echo "WARNING: Variable '$target' does not exist or is not an array/object"
+                       return 1
                ;;
        esac
 }