diff -uNr a/vtools/Makefile b/vtools/Makefile --- a/vtools/Makefile 67cefb8f1983138b975a6ec3402c6718e3fa8855201d2c41f4f4cd68284a21fc853cc56ce1d03b61a1d93df3ddcde48979b1a7ede00d077e31f39bd647daf1ed +++ b/vtools/Makefile false @@ -1,14 +0,0 @@ - -vdiff: - gprbuild -Pvdiff.gpr - -vpatch: - gprbuild -Pvpatch.gpr - -vflow: - gprbuild -Pvflow.gpr - -clean: - gprclean -Pvdiff.gpr - gprclean -Pvpatch.gpr - gprclean -Pvflow.gpr diff -uNr a/vtools/manifest b/vtools/manifest --- a/vtools/manifest 47bb2feba0952de6c08f9f9c644500bf867571c2c5058c70475811c6de72fa3f8297ca90155e12da32901569d9da2d8e4d084635e72cc85c0902f1aaf7753929 +++ b/vtools/manifest b2e3eb274b80a94c295a07f158fffdc7d757ca22d729d9171b6e6141d3652f643bb7a9868c01516aff282ed0106bd27c24ac87139154995e1122424daf38ee96 @@ -17,3 +17,4 @@ 617638 bvt vtools_vsh_ada_vfilter Add an implementation of vfilter in Ada. 619714 bvt vtools_vsh_shellcheck A round of shellcheck on the v.sh source. 620790 bvt vtools_ascii_visualization Add "vtree" command, work towards pipeable output. +621251 bvt vtools_vsh_ascii_fix2 vflow: remove early exit, DFS-based toposorting; v.sh: correct error checking and reporting in v.sh, fix vtree indentation, better error reporting in case of conflicts; makefile: remove. diff -uNr a/vtools/src/vflow.adb b/vtools/src/vflow.adb --- a/vtools/src/vflow.adb e6faf838d6886b05028f7483b7ff738584217d570a2a894fbe91380614a576f25952120f7fa5c1dff3bd6b16e53364cb5859ed2407412ab121c1c76d0826044c +++ b/vtools/src/vflow.adb 5ee6bcb685f193971ff5990bf189e36b52cd113e289cf46248fcd29da401a00114e4e22235f2f4d492a202546c6622a73976ed524ba9cd1f0f9dce8a6fcf3a11 @@ -221,9 +221,46 @@ N_Selected : Natural := 0; Finished : Boolean := False; Has_Loops : Boolean := False; + + DFS_Stack : Vpatch_List := (others => 0); + Stack_Head : Natural := 0; + + procedure Push (V : Vpatch_Index) is + begin + DFS_Stack(Stack_Head) := V; + Stack_Head := Stack_Head + 1; + end Push; + + function Pop return Boolean is + begin + if Stack_Head = 0 then + return False; + end if; + Stack_Head := Stack_Head - 1; + DFS_Stack(Stack_Head) := 0; + return True; + end Pop; + + function Matches_Last_Added (V : Vpatch_Index) return Boolean is + begin + if Stack_Head = 0 then + return True; + else + return Vpatch_Dependencies(V, DFS_Stack(Stack_Head - 1)) = True; + end if; + end Matches_Last_Added; + + procedure Add_Vpatch (V : Vpatch_Index) is + begin + Free_Vpatches(V) := False; + Vpatch_Order(N_Selected) := V; + N_Selected := N_Selected + 1; + Finished := False; + end Add_Vpatch; begin while not Finished loop Finished := True; + for I in Free_Vpatches'Range loop if Free_Vpatches(I) then declare @@ -237,16 +274,20 @@ end if; end loop; - -- All dependencies present, can add this vpatch: - if All_Satisfied then - Free_Vpatches(I) := False; - Vpatch_Order(N_Selected) := I; - N_Selected := N_Selected + 1; - Finished := False; + -- All dependencies present, can add this vpatch, if the last + -- vpatch added is in the antecedent set. + if All_Satisfied and Matches_Last_Added(I) then + Add_Vpatch(I); + Push(I); end if; end; end if; end loop; + + -- If this branch is exhausted, search the siblings. + if Finished then + Finished := not Pop; + end if; end loop; -- Check if there are still free vpatches (there is a loop): @@ -346,7 +387,6 @@ end Add_Dependencies; procedure Print_Flow_Or_Conflicts is - Has_Conflicts : Boolean := False; begin for I in Vpatch_Conflicts'Range(1) loop for J in Vpatch_Conflicts'Range(2) loop @@ -354,15 +394,10 @@ and Vpatch_Conflicts(I,J) then Put_Line("C " & Integer'Image(I)); Put_Line("C " & Integer'Image(J)); - Has_Conflicts := True; end if; end loop; end loop; - if Has_Conflicts then - return; - end if; - for I in Vpatch_Order'Range loop if Selected_Vpatches(Vpatch_Order(I)) then Put_Line("P " & Integer'Image(Vpatch_Order(I))); diff -uNr a/vtools/v.sh b/vtools/v.sh --- a/vtools/v.sh ba8feba74997e15453711dd8c414240605d87674dabd3feac0fdba6a97cb2beefbf0ef03b28b02d4b1d9ae251c58c9400b02f6359c1a3d76ad351e31c6f4caae +++ b/vtools/v.sh e64bb2725e055aaa4e7ce33a909209d55686fb42e4105fb0d383cf5d80145104333673486cf1dfbb2a42e6e2743cf9466d17fe7f799b40aaa708b5421afd854e @@ -140,19 +140,25 @@ } vpatchflowerr() { + set +e awk 'BEGIN {err=0; ok=0;} err == 0 && $1 == "C" {err=1; ech=$1;} err == 0 && $1 == "L" {err=2; ech=$1;} err == 0 && $1 == "P" {ok=1;} END {if (err != 0) exit err; if (ok != 1) exit 3; exit 0;}' <"$topo" exitcode="$?" + set -e if [ "$exitcode" -eq "1" ]; then - >&2 printf "\nConflicting leaves selected:\n" - >&2 awk '$1 == "C" {print $2}' < "$topo" | vpatchnames | sort | uniq + >&2 printf "Conflicting leaves selected:\n" + awk '$1 == "C" {print $2}' < "$topo" | vpatchnames | sort | uniq >&2 + >&2 printf "Available heads:\n" + awk ' +($1 == "I" || $1 == "d" ) {non_terminals[$3]=1;} +($1 == "P") {if (!($2 in non_terminals)) {print $2;}}' < "$topo" | vpatchnames >&2 fail elif [ "$exitcode" -eq "2" ]; then - >&2 printf "\nConflicting leaves selected:\n" - >&2 awk '{print $2}' < "$topo" | vpatchnames + >&2 printf "Loop among vpatches:\n" + awk '{print $2}' < "$topo" | vpatchnames >&2 fail elif [ "$exitcode" -eq "3" ]; then >&2 echo "Unknown error. Investigate in $vgpgdir:" @@ -276,17 +282,23 @@ vpatchflow "$@" awk -v VF="$vpatches" ' +function max(a,b) { return (a > b) ? a : b;} function repeat(s,n) {i=0; while (i++ < n) {printf("%s",s);}} -FILENAME==VF {n[$2]=$1} -FILENAME=="-" && ($1 == "I" || $1 == "d" ) {a[$2]++;b[$3]=1;} +FILENAME==VF {names[$2]=$1} +FILENAME=="-" && ($1 == "I" || $1 == "d" ) {non_terminals[$3]=1;} +FILENAME=="-" && ($1 == "d") {if (!($2 in n_ante)) n_ante[$2] = 0; dir_ante[$2][n_ante[$2]] = $3; n_ante[$2]++;} FILENAME=="-" && ($1 == "P" || $1 == "p") { - if (!($2 in a)) {a[$2]=0}; - repeat(" ", a[$2]); - printf("%s%s%s\n",n[$2], ($2 in b) ? "" : " (*)", ($1 == "P") ? " +" : "" ); + level[$2] = 0; + if ($2 in n_ante) { + for (i = 0; i < n_ante[$2]; i++) { + level[$2] = max(level[$2], level[dir_ante[$2][i]]+1); + } + } + repeat(" ", level[$2]); + printf("%s%s%s\n",names[$2], ($2 in non_terminals) ? "" : " (*)", ($1 == "P") ? " +" : "" ); }' "$vpatches" - <"$topo" exit_success fi - >&2 echo "Unknown command: $1" fail