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_push_string() { 154 local cur 155 _json_get_var cur JSON_CUR 156 [ "${cur%%[0-9]*}" = "J_A" ] || { 157 [ -n "$_json_no_warning" ] || \ 158 echo "WARNING: Not in an array" >&2 159 return 1 160 } 161 _json_add_generic string "" "$1" "$cur" 162 } 163 164 json_add_int() { 165 local cur 166 _json_get_var cur JSON_CUR 167 _json_add_generic int "$1" "$2" "$cur" 168 } 169 170 json_push_int() { 171 local cur 172 _json_get_var cur JSON_CUR 173 [ "${cur%%[0-9]*}" = "J_A" ] || { 174 [ -n "$_json_no_warning" ] || \ 175 echo "WARNING: Not in an array" >&2 176 return 1 177 } 178 _json_add_generic int "" "$1" "$cur" 179 } 180 181 json_add_boolean() { 182 local cur 183 _json_get_var cur JSON_CUR 184 _json_add_generic boolean "$1" "$2" "$cur" 185 } 186 187 json_push_boolean() { 188 local cur 189 _json_get_var cur JSON_CUR 190 [ "${cur%%[0-9]*}" = "J_A" ] || { 191 [ -n "$_json_no_warning" ] || \ 192 echo "WARNING: Not in an array" >&2 193 return 1 194 } 195 _json_add_generic boolean "" "$1" "$cur" 196 } 197 198 json_add_double() { 199 local cur 200 _json_get_var cur JSON_CUR 201 _json_add_generic double "$1" "$2" "$cur" 202 } 203 204 json_push_double() { 205 local cur 206 _json_get_var cur JSON_CUR 207 [ "${cur%%[0-9]*}" = "J_A" ] || { 208 [ -n "$_json_no_warning" ] || \ 209 echo "WARNING: Not in an array" >&2 210 return 1 211 } 212 _json_add_generic double "" "$1" "$cur" 213 } 214 215 json_add_null() { 216 local cur 217 _json_get_var cur JSON_CUR 218 _json_add_generic null "$1" "" "$cur" 219 } 220 221 json_push_null() { 222 local cur 223 _json_get_var cur JSON_CUR 224 [ "${cur%%[0-9]*}" = "J_A" ] || { 225 [ -n "$_json_no_warning" ] || \ 226 echo "WARNING: Not in an array" >&2 227 return 1 228 } 229 _json_add_generic null "" "" "$cur" 230 } 231 232 json_add_fields() { 233 while [ "$#" -gt 0 ]; do 234 local field="$1" 235 shift 236 237 local name="${field%%=*}" 238 local val="${field#*=}" 239 [ "$name" != "$val" ] || val="" 240 241 local type="${name#*:}" 242 [ "$type" != "$name" ] || type=string 243 name="${name%%:*}" 244 245 case "$type" in 246 string|int|boolean|double) 247 local cur 248 _json_get_var cur JSON_CUR 249 _json_add_generic "$type" "$name" "$val" "$cur" 250 ;; 251 esac 252 done 253 } 254 255 json_get_index() { 256 local __dest="$1" 257 local __cur __parent __seq 258 _json_get_var __cur JSON_CUR 259 _json_get_var __parent "U_$__cur" 260 if [ "${__parent%%[0-9]*}" != "J_A" ]; then 261 [ -n "$_json_no_warning" ] || \ 262 echo "WARNING: Not inside an array" >&2 263 return 1 264 fi 265 __seq="S_$__parent" 266 eval "export -- \"$__dest=\${$__seq}\"; [ -n \"\${$__seq+x}\" ]" 267 } 268 269 # functions read access to json variables 270 271 json_compact() { 272 JSON_NONEWLINE=1 273 JSON_INDENT= 274 } 275 276 json_pretty() { 277 JSON_NONEWLINE= 278 JSON_INDENT=1 279 } 280 281 json_load() { 282 eval "`jshn -r "$1"`" 283 } 284 285 json_load_file() { 286 eval "`jshn -R "$1"`" 287 } 288 289 json_dump() { 290 jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} ${JSON_NONEWLINE:+-n} ${JSON_INDENT:+-i} -w 291 } 292 293 json_get_type() { 294 # target=$2 295 local __dest="$1" 296 local __cur 297 298 _json_get_var __cur JSON_CUR 299 local __var="${JSON_PREFIX}T_${__cur}_${2//[^a-zA-Z0-9_]/_}" 300 eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]" 301 } 302 303 json_get_keys() { 304 local __dest="$1" 305 local _tbl_cur 306 307 if [ -n "$2" ]; then 308 json_get_var _tbl_cur "$2" 309 else 310 _json_get_var _tbl_cur JSON_CUR 311 fi 312 local __var="${JSON_PREFIX}K_${_tbl_cur}" 313 eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]" 314 } 315 316 json_get_values() { 317 local _v_dest="$1" 318 local _v_keys _v_val _select= 319 local _json_no_warning=1 320 321 unset "$_v_dest" 322 [ -n "$2" ] && { 323 json_select "$2" || return 1 324 _select=1 325 } 326 327 json_get_keys _v_keys 328 set -- $_v_keys 329 while [ "$#" -gt 0 ]; do 330 json_get_var _v_val "$1" 331 __jshn_raw_append "$_v_dest" "$_v_val" 332 shift 333 done 334 [ -n "$_select" ] && json_select .. 335 336 return 0 337 } 338 339 json_get_var() { 340 local __dest="$1" 341 local __cur 342 343 _json_get_var __cur JSON_CUR 344 local __var="${JSON_PREFIX}${__cur}_${2//[^a-zA-Z0-9_]/_}" 345 eval "export -- \"$__dest=\${$__var:-$3}\"; [ -n \"\${$__var+x}\${3+x}\" ]" 346 } 347 348 json_get_vars() { 349 while [ "$#" -gt 0 ]; do 350 local _var="$1"; shift 351 if [ "$_var" != "${_var#*:}" ]; then 352 json_get_var "${_var%%:*}" "${_var%%:*}" "${_var#*:}" 353 else 354 json_get_var "$_var" "$_var" 355 fi 356 done 357 } 358 359 json_select() { 360 local target="$1" 361 local type 362 local cur 363 364 [ -z "$target" ] && { 365 _json_set_var JSON_CUR "J_V" 366 return 0 367 } 368 [[ "$target" == ".." ]] && { 369 _json_get_var cur JSON_CUR 370 _json_get_var cur "U_$cur" 371 _json_set_var JSON_CUR "$cur" 372 return 0 373 } 374 json_get_type type "$target" 375 case "$type" in 376 object|array) 377 json_get_var cur "$target" 378 _json_set_var JSON_CUR "$cur" 379 ;; 380 *) 381 [ -n "$_json_no_warning" ] || \ 382 echo "WARNING: Variable '$target' does not exist or is not an array/object" >&2 383 return 1 384 ;; 385 esac 386 } 387 388 json_is_a() { 389 # target=$1 390 # type=$2 391 local type 392 393 json_get_type type "$1" 394 [ "$type" = "$2" ] 395 } 396 397 json_for_each_item() { 398 [ "$#" -ge 2 ] || return 0 399 local function="$1"; shift 400 local target="$1"; shift 401 local type val 402 403 json_get_type type "$target" 404 case "$type" in 405 object|array) 406 local keys key 407 json_select "$target" 408 json_get_keys keys 409 for key in $keys; do 410 json_get_var val "$key" 411 eval "$function \"\$val\" \"\$key\" \"\$@\"" 412 done 413 json_select .. 414 ;; 415 *) 416 json_get_var val "$target" 417 eval "$function \"\$val\" \"\" \"\$@\"" 418 ;; 419 esac 420 }
This page was automatically generated by LXR 0.3.1. • OpenWrt