libubox: Add ability to find ordinal position inside a table master
authorPhilip Prindeville <philipp@redfish-solutions.com>
Fri, 14 Nov 2025 19:04:01 +0000 (12:04 -0700)
committerÁlvaro Fernández Rojas <noltari@gmail.com>
Mon, 8 Dec 2025 13:59:11 +0000 (14:59 +0100)
When adding anonymous objects to an array, the only way to select
those objects (as in "json_select", i.e. moving the cursor) is to
select them via their ordinality.

This function returns a selectable index to those objects.

Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
Link: https://github.com/openwrt/libubox/pull/33
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
sh/jshn.sh
tests/shunit2/tests.sh

index 66ca9524a041ebd71cbad044d9a9fc595393296b..8402b5495fb6d3e753bd20a0ffe607f3fbccec85 100644 (file)
@@ -197,6 +197,20 @@ json_add_fields() {
        done
 }
 
+json_get_index() {
+       local __dest="$1"
+       local __cur __parent __seq
+       _json_get_var __cur JSON_CUR
+       _json_get_var __parent "U_$__cur"
+       if [ "${__parent%%[0-9]*}" != "J_A" ]; then
+               [ -n "$_json_no_warning" ] || \
+                       echo "WARNING: Not inside an array" >&2
+               return 1
+       fi
+       __seq="S_$__parent"
+       eval "export -- \"$__dest=\${$__seq}\"; [ -n \"\${$__seq+x}\" ]"
+}
+
 # functions read access to json variables
 
 json_compact() {
index 8d0a644636d99d086e71a9229db176731c0492f7..21807edaa8a6faec80e88b6abdc0be9a9f967c5c 100755 (executable)
@@ -469,6 +469,43 @@ test_jshn_append_via_json_script() {
        json_add_string "second" "value2"
        json_get_keys keys
        assertEquals "first second" "$keys"
+       set -u
+}
+
+test_jshn_get_index() {
+       JSON_PREFIX="${JSON_PREFIX:-}"
+       . ../../sh/jshn.sh
+
+       set +u
+
+       local index
+
+       json_init
+
+       json_add_object "DHCP4"
+
+       json_add_array "networks"
+
+       json_add_object ""
+       json_get_index index
+       json_add_int "id" 1
+       json_add_string "subnet" "192.168.1.0/24"
+       json_close_object
+
+       json_add_object ""
+       json_add_int "id" 2
+       json_add_string "subnet" "192.168.2.0/24"
+       json_close_object
+
+       json_select "$index" # revisit first anonymous object
+       json_add_int "valid-lifetime" 3600
+       json_select .. # pop back into array
+
+       json_close_array # networks
+
+       json_close_object # DHCP4
+
+       assertEquals '{ "DHCP4": { "networks": [ { "id": 1, "subnet": "192.168.1.0\/24", "valid-lifetime": 3600 }, { "id": 2, "subnet": "192.168.2.0\/24" } ] } }' "$(json_dump)"
 
        set -u
 }