jshn.sh 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. # functions for parsing and generating json
  2. _json_get_var() {
  3. # dest=$1
  4. # var=$2
  5. eval "$1=\"\$${JSON_PREFIX}$2\""
  6. }
  7. _json_set_var() {
  8. # var=$1
  9. local ___val="$2"
  10. eval "${JSON_PREFIX}$1=\"\$___val\""
  11. }
  12. __jshn_raw_append() {
  13. # var=$1
  14. local value="$2"
  15. local sep="${3:- }"
  16. eval "export -- \"$1=\${$1:+\${$1}\${value:+\$sep}}\$value\""
  17. }
  18. _jshn_append() {
  19. # var=$1
  20. local _a_value="$2"
  21. eval "${JSON_PREFIX}$1=\"\${${JSON_PREFIX}$1} \$_a_value\""
  22. }
  23. _get_var() {
  24. # var=$1
  25. # value=$2
  26. eval "$1=\"\$$2\""
  27. }
  28. _set_var() {
  29. # var=$1
  30. local __val="$2"
  31. eval "$1=\"\$__val\""
  32. }
  33. _json_inc() {
  34. # var=$1
  35. # dest=$2
  36. let "${JSON_PREFIX}$1 += 1" "$2 = ${JSON_PREFIX}$1"
  37. }
  38. _json_add_generic() {
  39. # type=$1
  40. # name=$2
  41. # value=$3
  42. # cur=$4
  43. local var
  44. if [ "${4%%[0-9]*}" = "J_A" ]; then
  45. _json_inc "S_$4" var
  46. else
  47. var="${2//[^a-zA-Z0-9_]/_}"
  48. [[ "$var" == "$2" ]] || export -- "${JSON_PREFIX}N_${4}_${var}=$2"
  49. fi
  50. export -- \
  51. "${JSON_PREFIX}${4}_$var=$3" \
  52. "${JSON_PREFIX}T_${4}_$var=$1"
  53. _jshn_append "JSON_UNSET" "${4}_$var"
  54. _jshn_append "K_$4" "$var"
  55. }
  56. _json_add_table() {
  57. # name=$1
  58. # type=$2
  59. # itype=$3
  60. local cur seq
  61. _json_get_var cur JSON_CUR
  62. _json_inc JSON_SEQ seq
  63. local table="J_$3$seq"
  64. _json_set_var "U_$table" "$cur"
  65. export -- "${JSON_PREFIX}K_$table="
  66. unset "${JSON_PREFIX}S_$table"
  67. _json_set_var JSON_CUR "$table"
  68. _jshn_append "JSON_UNSET" "$table"
  69. _json_add_generic "$2" "$1" "$table" "$cur"
  70. }
  71. _json_close_table() {
  72. local _s_cur
  73. _json_get_var _s_cur JSON_CUR
  74. _json_get_var "${JSON_PREFIX}JSON_CUR" "U_$_s_cur"
  75. }
  76. json_set_namespace() {
  77. local _new="$1"
  78. local _old="$2"
  79. [ -n "$_old" ] && _set_var "$_old" "$JSON_PREFIX"
  80. JSON_PREFIX="$_new"
  81. }
  82. json_cleanup() {
  83. local unset tmp
  84. _json_get_var unset JSON_UNSET
  85. for tmp in $unset J_V; do
  86. unset \
  87. ${JSON_PREFIX}U_$tmp \
  88. ${JSON_PREFIX}K_$tmp \
  89. ${JSON_PREFIX}S_$tmp \
  90. ${JSON_PREFIX}T_$tmp \
  91. ${JSON_PREFIX}N_$tmp \
  92. ${JSON_PREFIX}$tmp
  93. done
  94. unset \
  95. ${JSON_PREFIX}JSON_SEQ \
  96. ${JSON_PREFIX}JSON_CUR \
  97. ${JSON_PREFIX}JSON_UNSET
  98. }
  99. json_init() {
  100. json_cleanup
  101. export -n ${JSON_PREFIX}JSON_SEQ=0
  102. export -- \
  103. ${JSON_PREFIX}JSON_CUR="J_V" \
  104. ${JSON_PREFIX}K_J_V=
  105. }
  106. json_add_object() {
  107. _json_add_table "$1" object T
  108. }
  109. json_close_object() {
  110. _json_close_table
  111. }
  112. json_add_array() {
  113. _json_add_table "$1" array A
  114. }
  115. json_close_array() {
  116. _json_close_table
  117. }
  118. json_add_string() {
  119. local cur
  120. _json_get_var cur JSON_CUR
  121. _json_add_generic string "$1" "$2" "$cur"
  122. }
  123. json_add_int() {
  124. local cur
  125. _json_get_var cur JSON_CUR
  126. _json_add_generic int "$1" "$2" "$cur"
  127. }
  128. json_add_boolean() {
  129. local cur
  130. _json_get_var cur JSON_CUR
  131. _json_add_generic boolean "$1" "$2" "$cur"
  132. }
  133. json_add_double() {
  134. local cur
  135. _json_get_var cur JSON_CUR
  136. _json_add_generic double "$1" "$2" "$cur"
  137. }
  138. json_add_null() {
  139. local cur
  140. _json_get_var cur JSON_CUR
  141. _json_add_generic null "$1" "" "$cur"
  142. }
  143. # functions read access to json variables
  144. json_load() {
  145. eval "`jshn -r "$1"`"
  146. }
  147. json_load_file() {
  148. eval "`jshn -R "$1"`"
  149. }
  150. json_dump() {
  151. jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} -w
  152. }
  153. json_get_type() {
  154. local __dest="$1"
  155. local __cur
  156. _json_get_var __cur JSON_CUR
  157. local __var="${JSON_PREFIX}T_${__cur}_${2//[^a-zA-Z0-9_]/_}"
  158. eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
  159. }
  160. json_get_keys() {
  161. local __dest="$1"
  162. local _tbl_cur
  163. if [ -n "$2" ]; then
  164. json_get_var _tbl_cur "$2"
  165. else
  166. _json_get_var _tbl_cur JSON_CUR
  167. fi
  168. local __var="${JSON_PREFIX}K_${_tbl_cur}"
  169. eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
  170. }
  171. json_get_values() {
  172. local _v_dest="$1"
  173. local _v_keys _v_val _select=
  174. local _json_no_warning=1
  175. unset "$_v_dest"
  176. [ -n "$2" ] && {
  177. json_select "$2" || return 1
  178. _select=1
  179. }
  180. json_get_keys _v_keys
  181. set -- $_v_keys
  182. while [ "$#" -gt 0 ]; do
  183. json_get_var _v_val "$1"
  184. __jshn_raw_append "$_v_dest" "$_v_val"
  185. shift
  186. done
  187. [ -n "$_select" ] && json_select ..
  188. return 0
  189. }
  190. json_get_var() {
  191. local __dest="$1"
  192. local __cur
  193. _json_get_var __cur JSON_CUR
  194. local __var="${JSON_PREFIX}${__cur}_${2//[^a-zA-Z0-9_]/_}"
  195. eval "export -- \"$__dest=\${$__var:-$3}\"; [ -n \"\${$__var+x}\${3+x}\" ]"
  196. }
  197. json_get_vars() {
  198. while [ "$#" -gt 0 ]; do
  199. local _var="$1"; shift
  200. if [ "$_var" != "${_var#*:}" ]; then
  201. json_get_var "${_var%%:*}" "${_var%%:*}" "${_var#*:}"
  202. else
  203. json_get_var "$_var" "$_var"
  204. fi
  205. done
  206. }
  207. json_select() {
  208. local target="$1"
  209. local type
  210. local cur
  211. [ -z "$1" ] && {
  212. _json_set_var JSON_CUR "J_V"
  213. return 0
  214. }
  215. [[ "$1" == ".." ]] && {
  216. _json_get_var cur JSON_CUR
  217. _json_get_var cur "U_$cur"
  218. _json_set_var JSON_CUR "$cur"
  219. return 0
  220. }
  221. json_get_type type "$target"
  222. case "$type" in
  223. object|array)
  224. json_get_var cur "$target"
  225. _json_set_var JSON_CUR "$cur"
  226. ;;
  227. *)
  228. [ -n "$_json_no_warning" ] || \
  229. echo "WARNING: Variable '$target' does not exist or is not an array/object"
  230. return 1
  231. ;;
  232. esac
  233. }
  234. json_is_a() {
  235. local type
  236. json_get_type type "$1"
  237. [ "$type" = "$2" ]
  238. }
  239. json_for_each_item() {
  240. [ "$#" -ge 2 ] || return 0
  241. local function="$1"; shift
  242. local target="$1"; shift
  243. local type val
  244. json_get_type type "$target"
  245. case "$type" in
  246. object|array)
  247. local keys key
  248. json_select "$target"
  249. json_get_keys keys
  250. for key in $keys; do
  251. json_get_var val "$key"
  252. eval "$function \"\$val\" \"\$key\" \"\$@\""
  253. done
  254. json_select ..
  255. ;;
  256. *)
  257. json_get_var val "$target"
  258. eval "$function \"\$val\" \"\" \"\$@\""
  259. ;;
  260. esac
  261. }