jshn: support using characters in elements that do not conform to shell variable...
[project/libubox.git] / sh / jshn.sh
index 923f2b3..8ecefcf 100644 (file)
@@ -1,16 +1,16 @@
 # functions for parsing and generating json
 
-append() {
+jshn_append() {
        local var="$1"
        local value="$2"
        local sep="${3:- }"
 
-       eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\""
+       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=
+       export -- JSON_SEQ=0 JSON_STACK= JSON_CUR="JSON_VAR" JSON_UNSET="" KEYS_JSON_VAR= TYPE_JSON_VAR=
 }
 
 json_add_generic() {
@@ -19,29 +19,42 @@ json_add_generic() {
        local val="$3"
        local cur="${4:-$JSON_CUR}"
 
-       export ${NO_EXPORT:+-n} -- "${cur}_$var=$val"
-       export ${NO_EXPORT:+-n} -- "TYPE_${cur}_$var=$type"
-       append JSON_UNSET "${cur}_$var TYPE_${cur}_$var"
-       append "KEYS_${cur}" "$var"
+       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))
-       append JSON_STACK "$JSON_CUR"
-       local table="JSON_TABLE$JSON_SEQ"
-       export ${NO_EXPORT:+-n} -- "UP_$table=$JSON_CUR"
+       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
+       json_add_table TABLE
        json_add_generic object "$1" "$JSON_CUR" "$cur"
 }
 
 json_close_object() {
        local oldstack="$JSON_STACK"
-       export "KEYS_${JSON_CUR}"
        JSON_CUR="${JSON_STACK##* }"
        JSON_STACK="${JSON_STACK% *}"
        [[ "$oldstack" == "$JSON_STACK" ]] && JSON_STACK=
@@ -49,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"
 }
 
@@ -76,19 +89,19 @@ json_load() {
 }
 
 json_dump() {
-       jshn -w
+       jshn "$@" -w
 }
 
 json_get_type() {
        local dest="$1"
        local var="$2"
-       eval "export ${NO_EXPORT:+-n} -- \"$dest=\${TYPE_${JSON_CUR}_$var}\""
+       eval "export -- \"$dest=\${TYPE_${JSON_CUR}_$var}\""
 }
 
 json_get_var() {
        local dest="$1"
        local var="$2"
-       eval "export ${NO_EXPORT:+-n} -- \"$dest=\${${JSON_CUR}_$var}\""
+       eval "export -- \"$dest=\${${JSON_CUR}_$var}\""
 }
 
 json_select() {