diff --git a/bj-1line.sh b/bj-1line.sh index 0a8fd88..990e7ed 100755 --- a/bj-1line.sh +++ b/bj-1line.sh @@ -1,2 +1,2 @@ # (C) Isaac Freeman (memotype@gmail.com). See https://github.com/memotype/bj.sh -bj()([[ $1 = - ]]||exec<<<"$1";shift;c=;rd(){ l=$c;IFS= read -rN1 c;};pr(){ printf %s "${o[@]}";};st(){ p=$1;[[ $p ]]||o=();while rd;do [[ $p&&! $q ]]&&o+=("$l");case $c in \\)rd||break;[[ $p&&$q ]]||o+=("$l${c::!p}");;\")break;;*)[[ $p ]]||o+=("$c");;esac;done;};co(){ n=0 b=1;while rd;do [[ $q ]]||o+=("$l");case $c in \")[[ $1||! $q ]]&&st 1||{ st;k=$(pr);};;[|{)((b++));;]|\})((--b))||{ [[ $q ]]&&exit 1;o+=("$c");break;};;:)[[ ! $1&&$q&&$k = "$q" ]]&&return;;,)((0$1&&b == 1))&&{ ((n++));[[ $n = "$q" ]]&&break;};;esac;done;};for q in "$@" "";do shift&&[[ ! $q ]]&&return 2;x=0;o=();while rd;do case $c in [[:space:]])! :;;\")st;;[tfn0-9-])while o+=("$c")&&rd&&[[ $c =~ [-+.0-9Ea-z] ]];do :;done;;{)co;;[)[[ $q = 0 ]]||co 1;;*)return 2;;esac&&{ x=1;break;};done;done;pr;((x));) +bj()([[ $1 = - ]]||exec<<<"$1";shift;c=;rd(){ l=$c;IFS= read -rN1 c;};pr(){ printf %s "${o[@]}";};st(){ p=$1;[[ $p ]]||o=();while rd;do [[ $p&&! $q ]]&&o+=("$l");case $c in \\)rd||break;[[ $p&&$q ]]||o+=("$l${c::!p}");;\")break;;*)[[ $p ]]||o+=("$c");;esac;done;};co(){ n= b=1;while rd;do [[ $q ]]||o+=("$l");case $c in \")[[ $1||! $q ]]&&st 1||{ st;k=$(pr);};;[|{)((b++));;]|\})((--b))||{ [[ $q ]]&&exit 1;o+=("$c");break;};;:)[[ $1$b = 1&&$q&&$k = "$q" ]]&&break;;,)((0$1&&b == 1))&&{ ((n++));[[ $n = "$q" ]]&&break;};;esac;done;};for q in "$@" "";do shift&&[[ ! $q ]]&&return 2;x=0;o=();while rd;do case $c in [[:space:]])! :;;\")st;;[tfn0-9-])while o+=("$c")&&rd&&[[ $c =~ [-+.0-9Ea-z] ]];do :;done;;{)co;;[)[[ $q = 0 ]]||co 1;;*)return 2;;esac&&x=1&&break;done;done;pr;((x));) diff --git a/bj-80-col.sh b/bj-80-col.sh index 47b5de6..89ccc24 100755 --- a/bj-80-col.sh +++ b/bj-80-col.sh @@ -2,10 +2,10 @@ bj()([[ $1 = - ]]||exec<<<"$1";shift;c=;rd(){ l=$c;IFS= read -rN1 c;};pr(){ \ printf %s "${o[@]}";};st(){ p=$1;[[ $p ]]||o=();while rd;do [[ $p&&! $q ]]&&o+=\ ("$l");case $c in \\)rd||break;[[ $p&&$q ]]||o+=("$l${c::!p}");;\")break;;*)[[ \ -$p ]]||o+=("$c");;esac;done;};co(){ n=0 b=1;while rd;do [[ $q ]]||o+=("$l") +$p ]]||o+=("$c");;esac;done;};co(){ n= b=1;while rd;do [[ $q ]]||o+=("$l") case $c in \")[[ $1||! $q ]]&&st 1||{ st;k=$(pr);};;[|{)((b++));;]|\})((--b))|| -{ [[ $q ]]&&exit 1;o+=("$c");break;};;:)[[ ! $1&&$q&&$k = "$q" ]]&&return;;,) +{ [[ $q ]]&&exit 1;o+=("$c");break;};;:)[[ $1$b = 1&&$q&&$k = "$q" ]]&&break;;,) ((0$1&&b == 1))&&{ ((n++));[[ $n = "$q" ]]&&break;};;esac;done;};for q in "$@" \ "";do shift&&[[ ! $q ]]&&return 2;x=0;o=();while rd;do case $c in [[:space:]]) ! :;;\")st;;[tfn0-9-])while o+=("$c")&&rd&&[[ $c =~ [-+.0-9Ea-z] ]];do :;done;; -{)co;;[)[[ $q = 0 ]]||co 1;;*)return 2;;esac&&{ x=1;break;};done;done;pr;((x));) +{)co;;[)[[ $q = 0 ]]||co 1;;*)return 2;;esac&&x=1&&break;done;done;pr;((x));) diff --git a/bj-90-col.sh b/bj-90-col.sh index 3c3453f..b19f9db 100755 --- a/bj-90-col.sh +++ b/bj-90-col.sh @@ -2,9 +2,9 @@ bj()([[ $1 = - ]]||exec<<<"$1";shift;c=;rd(){ l=$c;IFS= read -rN1 c;};pr(){ printf %s \ "${o[@]}";};st(){ p=$1;[[ $p ]]||o=();while rd;do [[ $p&&! $q ]]&&o+=("$l");case $c in \\) rd||break;[[ $p&&$q ]]||o+=("$l${c::!p}");;\")break;;*)[[ $p ]]||o+=("$c");;esac;done;} -co(){ n=0 b=1;while rd;do [[ $q ]]||o+=("$l");case $c in \")[[ $1||! $q ]]&&st 1||{ st;k\ -=$(pr);};;[|{)((b++));;]|\})((--b))||{ [[ $q ]]&&exit 1;o+=("$c");break;};;:)[[ ! $1&&$q&& -$k = "$q" ]]&&return;;,)((0$1&&b == 1))&&{ ((n++));[[ $n = "$q" ]]&&break;};;esac;done;} -for q in "$@" "";do shift&&[[ ! $q ]]&&return 2;x=0;o=();while rd;do case $c in \ +co(){ n= b=1;while rd;do [[ $q ]]||o+=("$l");case $c in \")[[ $1||! $q ]]&&st 1||{ st;k\ +=$(pr);};;[|{)((b++));;]|\})((--b))||{ [[ $q ]]&&exit 1;o+=("$c");break;};;:)[[ $1$b = 1&& +$q&&$k = "$q" ]]&&break;;,)((0$1&&b == 1))&&{ ((n++));[[ $n = "$q" ]]&&break;};;esac;done +};for q in "$@" "";do shift&&[[ ! $q ]]&&return 2;x=0;o=();while rd;do case $c in \ [[:space:]])! :;;\")st;;[tfn0-9-])while o+=("$c")&&rd&&[[ $c =~ [-+.0-9Ea-z] ]];do :;done -;;{)co;;[)[[ $q = 0 ]]||co 1;;*)return 2;;esac&&{ x=1;break;};done;done;pr;((x));) +;;{)co;;[)[[ $q = 0 ]]||co 1;;*)return 2;;esac&&x=1&&break;done;done;pr;((x));) diff --git a/bj.sh b/bj.sh index eb9feef..66527f8 100755 --- a/bj.sh +++ b/bj.sh @@ -54,7 +54,7 @@ bj() ( # Scan an object or list. $1 is set when scanning a list. co() { : : "=== co()" - n=0 b=1 + n= b=1 while rd; do : : "--- l=$l= c=$c= q=$q= b=$b= ---" [[ $q ]] || o+=("$l") @@ -69,8 +69,9 @@ bj() ( break } ;; - # Found the key, just return and let the main loop parse from here - :) [[ ! $1 && $q && $k = "$q" ]] && return ;; + # $1 is set for lists, so $1$b is 1 only at direct object depth. + # Found the key, just stop and let the main loop parse from here. + :) [[ $1$b = 1 && $q && $k = "$q" ]] && break ;; ,) ((0$1 && b == 1)) && { ((n++)) @@ -102,7 +103,7 @@ bj() ( {) co ;; [) [[ $q = 0 ]] || co 1 ;; #]) *) return 2 ;; - esac && { x=1; break; } + esac && x=1 && break done done diff --git a/test.sh b/test.sh index 6d3cf3c..f6e8d95 100755 --- a/test.sh +++ b/test.sh @@ -121,6 +121,15 @@ runtest '["x]y"]' '{"a":["x]y"]}' a runtest 'c' '["a,b","c"]' 1 runtest 'c' '["a]b","c"]' 1 +# Object keys must only match at the current container depth +runtest top '{"outer":{"target":"nested"},"target":"top"}' target +runteststatus 1 '' '{"outer":{"target":"nested"},"other":0}' target +runtest top '{"items":[{"target":"nested"}],"target":"top"}' target +runteststatus 1 '' '{"items":[{"target":"nested"}],"other":0}' target +runtest top '{"target":"top","outer":{"target":"nested"}}' target +runtest direct \ + '{"level":{"child":{"target":"nested"},"target":"direct"}}' level target + # Numbers tests runtest "4.2e10" '[0, -1, 4.2e10]' 2 runtest "-1" '[0, -1, 4.2e10]' 1