1 # functions for parsing and generating json 2 3 _json_get_var() { 4 # dest=$1 5 # var=$2 6 eval "$1=\"\$${JSON_PREFIX}$2\"" 7 } 8 9 _json_set_var() { 10 # var=$1 11 local ___val="$2" 12 eval "${JSON_PREFIX}$1=\"\$___val\"" 13 } 14 15 __jshn_raw_append() { 16 # var=$1 17 local value="$2" 18 local sep="${3:- }" 19 20 eval "export -- \"$1=\${$1:+\${$1}\${value:+\$sep}}\$value\"" 21 } 22 23 _jshn_append() { 24 # var=$1 25 local _a_value="$2" 26 eval "${JSON_PREFIX}$1=\"\${${JSON_PREFIX}$1}\${${JSON_PREFIX}$1:+ }\$_a_value\"" 27 } 28 29 _get_var() { 30 # var=$1 31 # value=$2 32 eval "$1=\"\$$2\"" 33 } 34 35 _set_var() { 36 # var=$1 37 local __val="$2" 38 eval "$1=\"\$__val\"" 39 } 40 41 _json_inc() { 42 # var=$1 43 # dest=$2 44 45 let "${JSON_PREFIX}$1 += 1" "$2 = ${JSON_PREFIX}$1" 46 } 47 48 _json_add_generic() { 49 # type=$1 50 # name=$2 51 # value=$3 52 # cur=$4 53 54 local var 55 if [ "${4%%[0-9]*}" = "J_A" ]; then 56 _json_inc "S_$4" var 57 else 58 var="${2//[^a-zA-Z0-9_]/_}" 59 [[ "$var" == "$2" ]] || export -- "${JSON_PREFIX}N_${4}_${var}=$2" 60 fi 61 62 export -- \ 63 "${JSON_PREFIX}${4}_$var=$3" \ 64 "${JSON_PREFIX}T_${4}_$var=$1" 65 _jshn_append "JSON_UNSET" "${4}_$var" 66 _jshn_append "K_$4" "$var" 67 } 68 69 _json_add_table() { 70 # name=$1 71 # type=$2 72 # itype=$3 73 local cur seq 74 75 _json_get_var cur JSON_CUR 76 _json_inc JSON_SEQ seq 77 78 local table="J_$3$seq" 79 _json_set_var "U_$table" "$cur" 80 export -- "${JSON_PREFIX}K_$table=" 81 unset "${JSON_PREFIX}S_$table" 82 _json_set_var JSON_CUR "$table" 83 _jshn_append "JSON_UNSET" "$table" 84 85 _json_add_generic "$2" "$1" "$table" "$cur" 86 } 87 88 _json_close_table() { 89 local _s_cur 90 91 _json_get_var _s_cur JSON_CUR 92 _json_get_var "${JSON_PREFIX}JSON_CUR" "U_$_s_cur" 93 } 94 95 json_set_namespace() { 96 local _new="$1" 97 local _old="$2" 98 99 [ -n "$_old" ] && _set_var "$_old" "$JSON_PREFIX" 100 JSON_PREFIX="$_new" 101 } 102 103 json_cleanup() { 104 local unset tmp 105 106 _json_get_var unset JSON_UNSET 107 for tmp in $unset J_V; do 108 unset \ 109 ${JSON_PREFIX}U_$tmp \ 110 ${JSON_PREFIX}K_$tmp \ 111 ${JSON_PREFIX}S_$tmp \ 112 ${JSON_PREFIX}T_$tmp \ 113 ${JSON_PREFIX}N_$tmp \ 114 ${JSON_PREFIX}$tmp 115 done 116 117 unset \ 118 ${JSON_PREFIX}JSON_SEQ \ 119 ${JSON_PREFIX}JSON_CUR \ 120 ${JSON_PREFIX}JSON_UNSET 121 } 122 123 json_init() { 124 json_cleanup 125 export -n ${JSON_PREFIX}JSON_SEQ=0 126 export -- \ 127 ${JSON_PREFIX}JSON_CUR="J_V" \ 128 ${JSON_PREFIX}K_J_V= 129 } 130 131 json_add_object() { 132 _json_add_table "$1" object T 133 } 134 135 json_close_object() { 136 _json_close_table 137 } 138 139 json_add_array() { 140 _json_add_table "$1" array A 141 } 142 143 json_close_array() { 144 _json_close_table 145 } 146 147 json_add_string() { 148 local cur 149 _json_get_var cur JSON_CUR 150 _json_add_generic string "$1" "$2" "$cur" 151 } 152 153 json_add_int() { 154 local cur 155 _json_get_var cur JSON_CUR 156 _json_add_generic int "$1" "$2" "$cur" 157 } 158 159 json_add_boolean() { 160 local cur 161 _json_get_var cur JSON_CUR 162 _json_add_generic boolean "$1" "$2" "$cur" 163 } 164 165 json_add_double() { 166 local cur 167 _json_get_var cur JSON_CUR 168 _json_add_generic double "$1" "$2" "$cur" 169 } 170 171 json_add_null() { 172 local cur 173 _json_get_var cur JSON_CUR 174 _json_add_generic null "$1" "" "$cur" 175 } 176 177 json_add_fields() { 178 while [ "$#" -gt 0 ]; do 179 local field="$1" 180 shift 181 182 local name="${field%%=*}" 183 local val="${field#*=}" 184 [ "$name" != "$val" ] || val="" 185 186 local type="${name#*:}" 187 [ "$type" != "$name" ] || type=string 188 name="${name%%:*}" 189 190 case "$type" in 191 string|int|boolean|double) 192 local cur 193 _json_get_var cur JSON_CUR 194 _json_add_generic "$type" "$name" "$val" "$cur" 195 ;; 196 esac 197 done 198 } 199 200 json_get_index() { 201 local __dest="$1" 202 local __cur __parent __seq 203 _json_get_var __cur JSON_CUR 204 _json_get_var __parent "U_$__cur" 205 if [ "${__parent%%[0-9]*}" != "J_A" ]; then 206 [ -n "$_json_no_warning" ] || \ 207 echo "WARNING: Not inside an array" >&2 208 return 1 209 fi 210 __seq="S_$__parent" 211 eval "export -- \"$__dest=\${$__seq}\"; [ -n \"\${$__seq+x}\" ]" 212 } 213 214 # functions read access to json variables 215 216 json_compact() { 217 JSON_NONEWLINE=1 218 JSON_INDENT= 219 } 220 221 json_pretty() { 222 JSON_NONEWLINE= 223 JSON_INDENT=1 224 } 225 226 json_load() { 227 eval "`jshn -r "$1"`" 228 } 229 230 json_load_file() { 231 eval "`jshn -R "$1"`" 232 } 233 234 json_dump() { 235 jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} ${JSON_NONEWLINE:+-n} ${JSON_INDENT:+-i} -w 236 } 237 238 json_get_type() { 239 local __dest="$1" 240 local __cur 241 242 _json_get_var __cur JSON_CUR 243 local __var="${JSON_PREFIX}T_${__cur}_${2//[^a-zA-Z0-9_]/_}" 244 eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]" 245 } 246 247 json_get_keys() { 248 local __dest="$1" 249 local _tbl_cur 250 251 if [ -n "$2" ]; then 252 json_get_var _tbl_cur "$2" 253 else 254 _json_get_var _tbl_cur JSON_CUR 255 fi 256 local __var="${JSON_PREFIX}K_${_tbl_cur}" 257 eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]" 258 } 259 260 json_get_values() { 261 local _v_dest="$1" 262 local _v_keys _v_val _select= 263 local _json_no_warning=1 264 265 unset "$_v_dest" 266 [ -n "$2" ] && { 267 json_select "$2" || return 1 268 _select=1 269 } 270 271 json_get_keys _v_keys 272 set -- $_v_keys 273 while [ "$#" -gt 0 ]; do 274 json_get_var _v_val "$1" 275 __jshn_raw_append "$_v_dest" "$_v_val" 276 shift 277 done 278 [ -n "$_select" ] && json_select .. 279 280 return 0 281 } 282 283 json_get_var() { 284 local __dest="$1" 285 local __cur 286 287 _json_get_var __cur JSON_CUR 288 local __var="${JSON_PREFIX}${__cur}_${2//[^a-zA-Z0-9_]/_}" 289 eval "export -- \"$__dest=\${$__var:-$3}\"; [ -n \"\${$__var+x}\${3+x}\" ]" 290 } 291 292 json_get_vars() { 293 while [ "$#" -gt 0 ]; do 294 local _var="$1"; shift 295 if [ "$_var" != "${_var#*:}" ]; then 296 json_get_var "${_var%%:*}" "${_var%%:*}" "${_var#*:}" 297 else 298 json_get_var "$_var" "$_var" 299 fi 300 done 301 } 302 303 json_select() { 304 local target="$1" 305 local type 306 local cur 307 308 [ -z "$1" ] && { 309 _json_set_var JSON_CUR "J_V" 310 return 0 311 } 312 [[ "$1" == ".." ]] && { 313 _json_get_var cur JSON_CUR 314 _json_get_var cur "U_$cur" 315 _json_set_var JSON_CUR "$cur" 316 return 0 317 } 318 json_get_type type "$target" 319 case "$type" in 320 object|array) 321 json_get_var cur "$target" 322 _json_set_var JSON_CUR "$cur" 323 ;; 324 *) 325 [ -n "$_json_no_warning" ] || \ 326 echo "WARNING: Variable '$target' does not exist or is not an array/object" 327 return 1 328 ;; 329 esac 330 } 331 332 json_is_a() { 333 local type 334 335 json_get_type type "$1" 336 [ "$type" = "$2" ] 337 } 338 339 json_for_each_item() { 340 [ "$#" -ge 2 ] || return 0 341 local function="$1"; shift 342 local target="$1"; shift 343 local type val 344 345 json_get_type type "$target" 346 case "$type" in 347 object|array) 348 local keys key 349 json_select "$target" 350 json_get_keys keys 351 for key in $keys; do 352 json_get_var val "$key" 353 eval "$function \"\$val\" \"\$key\" \"\$@\"" 354 done 355 json_select .. 356 ;; 357 *) 358 json_get_var val "$target" 359 eval "$function \"\$val\" \"\" \"\$@\"" 360 ;; 361 esac 362 }
This page was automatically generated by LXR 0.3.1. • OpenWrt