[PATCHv2 libubox] sh/jshn.sh: Add JSHN_DEBUG flag

Leonardo Mörlein me at irrelefant.net
Wed Dec 30 02:21:02 EST 2020


This flag can be set to JSHN_DEBUG=1 to print all calls to json_*
to stderr. The variable JSHN_DEBUG_PREFIX can be used optionally
to add a string in front of every debug print.

The json_* commands internally use other json_* commands. As it is
not desired that this inner commands are also printed, a variable
JSHN_DEBUG_DEPTH is used. It is initialized to JSHN_DEBUG_DEPTH=0,
increased on any json_* call and decreased when leaving the json_*
call. Debug prints are only fired if JSHN_DEBUG_DEPTH=0.

Other scripts may abuse this variable to their own needs, if they
do it carefully.

---snip---
JSHN_DEBUG=1
JSHN_DEBUG_PREFIX="json_debug: "
json_init
json_add_string "foo" "bar"
json_add_string "val" "12"
json_dump
---stderr---
json_debug: json_init
json_debug: json_add_string foo bar
json_debug: json_add_string val 12
json_debug: json_dump
---stdout---
{ "foo": "bar", "val": "12" }
---snap---

This is a preparatory commit to eventually allow debugging netifd
protos in a better way.

Signed-off-by: Leonardo Mörlein <me at irrelefant.net>
---
 sh/jshn.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 67 insertions(+), 2 deletions(-)

diff --git a/sh/jshn.sh b/sh/jshn.sh
index 7b0155d..3cc07fb 100644
--- a/sh/jshn.sh
+++ b/sh/jshn.sh
@@ -1,5 +1,18 @@
 # functions for parsing and generating json
 
+JSHN_DEBUG_DEPTH=0
+
+_json_debug() {
+	JSHN_DEBUG_DEPTH="$((JSHN_DEBUG_DEPTH+1))"
+	if [ -n "$JSHN_DEBUG" ] && [ "$JSHN_DEBUG" -eq 1 ] && [ "$JSHN_DEBUG_DEPTH" -eq 1 ]; then
+		echo "${JSHN_DEBUG_PREFIX}$*" 1>&2
+	fi
+}
+
+_json_debug_end() {
+	JSHN_DEBUG_DEPTH="$((JSHN_DEBUG_DEPTH-1))"
+}
+
 _json_get_var() {
 	# dest=$1
 	# var=$2
@@ -93,14 +106,17 @@ _json_close_table() {
 }
 
 json_set_namespace() {
+	_json_debug json_set_namespace "$@"
 	local _new="$1"
 	local _old="$2"
 
 	[ -n "$_old" ] && _set_var "$_old" "$JSON_PREFIX"
 	JSON_PREFIX="$_new"
+	_json_debug_end
 }
 
 json_cleanup() {
+	_json_debug json_cleanup "$@"
 	local unset tmp
 
 	_json_get_var unset JSON_UNSET
@@ -118,86 +134,116 @@ json_cleanup() {
 		${JSON_PREFIX}JSON_SEQ \
 		${JSON_PREFIX}JSON_CUR \
 		${JSON_PREFIX}JSON_UNSET
+	_json_debug_end
 }
 
 json_init() {
+	_json_debug json_init "$@"
 	json_cleanup
 	export -n ${JSON_PREFIX}JSON_SEQ=0
 	export -- \
 		${JSON_PREFIX}JSON_CUR="J_V" \
 		${JSON_PREFIX}K_J_V=
+	_json_debug_end
 }
 
 json_add_object() {
+	_json_debug json_add_object "$@"
 	_json_add_table "$1" object T
+	_json_debug_end
 }
 
 json_close_object() {
+	_json_debug json_close_object "$@"
 	_json_close_table
+	_json_debug_end
 }
 
 json_add_array() {
+	_json_debug json_add_array "$@"
 	_json_add_table "$1" array A
+	_json_debug_end
 }
 
 json_close_array() {
+	_json_debug json_close_array "$@"
 	_json_close_table
+	_json_debug_end
 }
 
 json_add_string() {
+	_json_debug json_add_string "$@"
 	local cur
 	_json_get_var cur JSON_CUR
 	_json_add_generic string "$1" "$2" "$cur"
+	_json_debug_end
 }
 
 json_add_int() {
+	_json_debug json_add_int "$@"
 	local cur
 	_json_get_var cur JSON_CUR
 	_json_add_generic int "$1" "$2" "$cur"
+	_json_debug_end
 }
 
 json_add_boolean() {
+	_json_debug json_add_boolean "$@"
 	local cur
 	_json_get_var cur JSON_CUR
 	_json_add_generic boolean "$1" "$2" "$cur"
+	_json_debug_end
 }
 
 json_add_double() {
+	_json_debug json_add_double "$@"
 	local cur
 	_json_get_var cur JSON_CUR
 	_json_add_generic double "$1" "$2" "$cur"
+	_json_debug_end
 }
 
 json_add_null() {
+	_json_debug json_add_null "$@"
 	local cur
 	_json_get_var cur JSON_CUR
 	_json_add_generic null "$1" "" "$cur"
+	_json_debug_end
 }
 
 # functions read access to json variables
 
 json_load() {
+	_json_debug json_load "$@"
 	eval "`jshn -r "$1"`"
+	_json_debug_end
 }
 
 json_load_file() {
+	_json_debug json_load_file "$@"
 	eval "`jshn -R "$1"`"
+	_json_debug_end
 }
 
 json_dump() {
-	jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} -w 
+	_json_debug json_dump "$@"
+	jshn "$@" ${JSON_PREFIX:+-p "$JSON_PREFIX"} -w
+	_json_debug_end
 }
 
 json_get_type() {
+	_json_debug json_get_type "$@"
 	local __dest="$1"
 	local __cur
 
 	_json_get_var __cur JSON_CUR
+	_json_debug_end
 	local __var="${JSON_PREFIX}T_${__cur}_${2//[^a-zA-Z0-9_]/_}"
 	eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
 }
 
 json_get_keys() {
+	_json_debug json_get_keys "$@"
 	local __dest="$1"
 	local _tbl_cur
 
@@ -206,11 +252,13 @@ json_get_keys() {
 	else
 		_json_get_var _tbl_cur JSON_CUR
 	fi
+	_json_debug_end
 	local __var="${JSON_PREFIX}K_${_tbl_cur}"
 	eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]"
 }
 
 json_get_values() {
+	_json_debug json_get_values "$@"
 	local _v_dest="$1"
 	local _v_keys _v_val _select=
 	local _json_no_warning=1
@@ -230,19 +278,23 @@ json_get_values() {
 	done
 	[ -n "$_select" ] && json_select ..
 
+	_json_debug_end
 	return 0
 }
 
 json_get_var() {
+	_json_debug json_get_var "$@"
 	local __dest="$1"
 	local __cur
 
 	_json_get_var __cur JSON_CUR
+	_json_debug_end
 	local __var="${JSON_PREFIX}${__cur}_${2//[^a-zA-Z0-9_]/_}"
 	eval "export -- \"$__dest=\${$__var:-$3}\"; [ -n \"\${$__var+x}\${3+x}\" ]"
 }
 
 json_get_vars() {
+	_json_debug json_get_vars "$@"
 	while [ "$#" -gt 0 ]; do
 		local _var="$1"; shift
 		if [ "$_var" != "${_var#*:}" ]; then
@@ -251,21 +303,25 @@ json_get_vars() {
 			json_get_var "$_var" "$_var"
 		fi
 	done
+	_json_debug_end
 }
 
 json_select() {
+	_json_debug json_select "$@"
 	local target="$1"
 	local type
 	local cur
 
 	[ -z "$1" ] && {
 		_json_set_var JSON_CUR "J_V"
+		_json_debug_end
 		return 0
 	}
 	[[ "$1" == ".." ]] && {
 		_json_get_var cur JSON_CUR
 		_json_get_var cur "U_$cur"
 		_json_set_var JSON_CUR "$cur"
+		_json_debug_end
 		return 0
 	}
 	json_get_type type "$target"
@@ -277,20 +333,28 @@ json_select() {
 		*)
 			[ -n "$_json_no_warning" ] || \
 				echo "WARNING: Variable '$target' does not exist or is not an array/object"
+			_json_debug_end
 			return 1
 		;;
 	esac
+	_json_debug_end
 }
 
 json_is_a() {
+	_json_debug json_is_a "$@"
 	local type
 
 	json_get_type type "$1"
+	_json_debug_end
 	[ "$type" = "$2" ]
 }
 
 json_for_each_item() {
-	[ "$#" -ge 2 ] || return 0
+	_json_debug json_for_each_item "$@"
+	if [ "$#" -lt 2 ]; then
+		_json_debug_end
+		return 0
+	fi
 	local function="$1"; shift
 	local target="$1"; shift
 	local type val
@@ -312,4 +376,5 @@ json_for_each_item() {
 			eval "$function \"\$val\" \"\" \"\$@\""
 		;;
 	esac
+	_json_debug_end
 }
-- 
2.29.2

v2:
- A case in json_for_each_item() where _json_debug_end was not
  called is fixed.
- Return code of e.g. json_is_a(), json_get_var(), json_get_keys()
  and json_get_type() are now correctly returned.




More information about the openwrt-devel mailing list