--- /dev/null
+#!/bin/sh
+
+# [ -n "$include_json" ] && return 0
+# include_json="$0"
+
+. "${_EXEC:-.}/cgilite/db23.sh"
+
+json_except() {
+ printf '%s\n' "$@" >&2;
+ printf 'Exc: %s\n' "$json_document" >&2
+}
+
+json_space() {
+ while true; do case "$json_document" in
+ [" ${BR}${CR} "]*) json_document="${json_document#?}";;
+ *) break ;;
+ esac; done
+}
+
+json_string() {
+ local string json_document="$json_document" end=0
+
+ json_space
+ case $json_document in
+ \"*) json_document="${json_document#?}"
+ ;;
+ *) json_except "Expected string specifyer starting with (\")"
+ return 1
+ ;;
+ esac
+ while [ "$json_document" ]; do case $json_document in
+ \\?*)
+ string="${string}${json_document%"${json_document#??}"}"
+ json_document="${json_document#??}"
+ ;;
+ \"*)
+ json_document="${json_document#?}"
+ end=1
+ break
+ ;;
+ *)
+ string="${string}${json_document%"${json_document#?}"}"
+ json_document="${json_document#?}"
+ ;;
+ esac; done
+
+ if [ $end -eq 0 ]; then
+ json_except "Document ended mid-string"
+ return 1
+ fi
+
+ printf "%s %s\n" "$(STRING "$string")" "$json_document"
+}
+
+json_key() {
+ local key json_document="$json_document"
+
+ json_space
+ case $json_document in
+ \"*)
+ key="$(json_string)" || return 1
+ json_document="${key#* }"
+ key="${key%% *}"
+ ;;
+ *) json_except "Expected key specifyer starting with '\"'"
+ return 1
+ ;;
+ esac
+ json_space
+ case $json_document in
+ :*) json_document="${json_document#?}"
+ ;;
+ *) json_except "Expected value separator \":\""
+ return 1
+ ;;
+ esac
+
+ printf '%s %s\n' "$key" "$json_document"
+}
+
+json_number() {
+ local number json_document="$json_document"
+
+ json_space
+ number="${json_document%%[" ${BR}${CR} ,}]"]*}"
+ json_document="${json_document#"$number"}"
+ if ! number="$(printf %f "$number")"; then
+ json_except "Invalid number format"
+ return 1
+ fi
+
+ printf '%s %s\n' "num:${number%.000000}" "$json_document"
+}
+
+json_value() {
+ local value json_document="$json_document"
+
+ json_space
+ case $json_document in
+ \"*)
+ value="$(json_string)" || return 1
+ json_document="${value#* }"
+ value="str:${value%% *}"
+ ;;
+ [+-.0-9]*)
+ value="$(json_number)" || return 1
+ json_document="${value#* }"
+ value="${value%% *}"
+ ;;
+ "{"*)
+ value="$(json_object)" || return 1
+ json_document="${value#* }"
+ value="obj:${value%% *}"
+ ;;
+ "["*)
+ value="$(json_array)" || return 1
+ json_document="${value#* }"
+ value="arr:${value%% *}"
+ ;;
+ null*)
+ json_document="${json_document#null}"
+ value="null"
+ ;;
+ true*)
+ json_document="${json_document#true}"
+ value="true"
+ ;;
+ false*)
+ json_document="${json_document#false}"
+ value="false"
+ ;;
+ esac
+
+ printf "%s %s\n" "$value" "$json_document"
+}
+
+json_array() {
+ local struct="$(DB2 new)" value json_document="$json_document"
+
+ json_space
+ case $json_document in
+ "["*) json_document="${json_document#?}"
+ ;;
+ *) json_except "Expected array starting with \"[\""
+ return 1
+ ;;
+ esac
+
+ json_space
+ case $json_document in
+ "]"*)
+ printf "%s %s\n" "" "${json_document#?}"
+ return 0
+ ;;
+ esac
+
+ while :; do
+ json_space
+
+ value="$(json_value)" || return 1
+ json_document="${value#* }"
+ value="$(UNSTRING "${value%% *}")"
+
+ struct="$(DB2 "$struct" append "@" "$value")" \
+ || struct="$(DB2 "$struct" set "@" "$value")"
+
+ json_space
+ case $json_document in
+ ,*) json_document="${json_document#?}"
+ ;;
+ "]"*) json_document="${json_document#?}"
+ break
+ ;;
+ *) json_except "Unexpected character mid-array"
+ return 1
+ ;;
+ esac
+ done
+
+ printf "%s %s\n" "$(STRING "$struct")" "$json_document"
+}
+
+json_object() {
+ local struct="$(DB2 new)" key value json_document="$json_document"
+
+ json_space
+ case $json_document in
+ "{"*) json_document="${json_document#?}"
+ ;;
+ *) json_except "Expected object starting with \"{\""
+ return 1
+ ;;
+ esac
+
+ json_space
+ case $json_document in
+ "}"*)
+ printf "%s %s\n" "" "${json_document#?}"
+ return 0
+ ;;
+ esac
+
+ while :; do
+ json_space
+
+ key="$(json_key)" || return 1
+ json_document="${key#* }"
+ key="$(UNSTRING "${key%% *}")"
+
+ value="$(json_value)" || return 1
+ json_document="${value#* }"
+ value="$(UNSTRING "${value%% *}")"
+
+ struct="$(DB2 "$struct" set "$key" "$value")"
+
+ json_space
+ case $json_document in
+ ,*) json_document="${json_document#?}"
+ ;;
+ "}"*) json_document="${json_document#?}"
+ break
+ ;;
+ *) json_except "Unexpected character mid-object"
+ return 1
+ ;;
+ esac
+ done
+
+ printf "%s %s\n" "$(STRING "$struct")" "$json_document"
+}
+
+json_load() {
+ local json_document="$1"
+
+ json_value
+}