#!/bin/bash
#
# review - Review the diff between expected output and actual output in Units
#
# Copyright (C) 2016 Masatake YAMATO
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
print_help()
{
echo Usage:
printf " %-20s %-30s %s\n" "$0" "help|--help|-h" "show this message"
printf " %-20s %-30s %s\n" "$0" "[list] [-b]" "list failed Units and Tmain"
help_list
printf " %-20s %-30s %s\n" "$0" "inspect [-b]" "inspect difference interactively"
help_inspect
exit $1
}
is_known_bug()
{
[[ $1 == *.b ]]
return $?
}
do_list ()
{
local d
local n
local a
local including_known_bugs
for a in "$@"; do
case $a in
(-b)
including_known_bugs=-b
;;
(-*)
echo "unknown option: ${a}" 1>&2
exit 1
;;
(*)
echo "unexpected argument ${a}" 1>&2
exit 1
;;
esac
done
for d in $(find Units -name "DIFF.tmp"); do
n=$(dirname "$d")
if (( ! is_known_bug $(basename "$n") ) || [[ -n ${including_known_bugs} ]] ) \
&& [[ -e "$n"/expected.tags ]]; then
echo ${n}
fi
done
for d in $(find Tmain -name "*-diff.txt"); do
n=$(dirname "$d")
echo ${n}
done | sort -u
}
help_list()
{
printf " %-20s %-30s %s\n" "" "-b" "list .b (known bug) marked cases"
}
units_inspect_cmd_accept ()
{
local from=./Units/$1/FILTERED.tmp
local to=./Units/$1/expected.tags
local r
if [[ ! -e "${from}" ]]; then
echo "./Units/$1/FILTERED.tmp is not found" 1>&2
echo "Remove DIFF.tmp?"
read -p "[Y/n] "
if [[ "$REPLY" == Y ]]; then
rm ./Units/$t/DIFF.tmp
echo "Removed: DIFF.tmp"
r=1
else
echo "Kept: DIFF.tmp"
r=0
fi
return $r
fi
echo "Do you really want do following shell command?"
echo
echo " mv \"$from\"" '\'
echo " \"$to\" "
echo
read -p "[Y/n] "
if [[ "$REPLY" == Y ]]; then
mv "$from" "$to"
echo "Renamed: $from => $to"
r=0
echo "Remove DIFF.tmp, too?"
read -p "[Y/n] "
if [[ "$REPLY" == Y ]]; then
rm ./Units/$t/DIFF.tmp
echo "Removed: DIFF.tmp"
else
echo "Kept: DIFF.tmp"
fi
else
echo "Aborted"
r=1
fi
return $r
}
units_inspect_cmd_skip ()
{
echo "SKIPPING $1" 1>&2
}
inspect_cmd_show_generic ()
{
local tcase=$1
local file=$2
shift 2
local f=./Units/${tcase}/${file}
if [[ -r "$f" ]]; then
"$@" "$f"
else
echo "No ${file}" 1>&2
fi
echo '---'
echo '# ' "$f"
}
units_inspect_cmd_show_diff ()
{
local cmd=cat
if which colordiff > /dev/null 2>&1; then
cmd=colordiff
elif which pygmentize > /dev/null 2>&1; then
cmd="pygmentize -l diff"
fi
inspect_cmd_show_generic $1 DIFF.tmp cat | ${cmd}
}
units_inspect_show_args_ctags ()
{
inspect_cmd_show_generic $1 args.ctags cat
}
pygmentize_or_cat ()
{
# It seems that pygmentize ignores the empty lines at the head of input.
if [ -z "$(head -1 $1)" ]; then
cat -n $1
elif which pygmentize > /dev/null 2>&1; then
pygmentize -O "style=colorful,linenos=1" $1 2>/dev/null || cat -n $1
else
cat -n $1
fi
}
units_inspect_show_input ()
{
local tcase=$1
inspect_cmd_show_generic $tcase $(basename ./Units/${tcase}/input.*) pygmentize_or_cat
}
units_inspect_show_expected_tags ()
{
local tcase=$1
(
shopt -s extglob
inspect_cmd_show_generic $tcase $(basename ./Units/${tcase}/expected.tags?(-*)) "cat" "-n"
)
}
inspect_cmd_quit ()
{
echo "BYE" 1>&2
exit 0
}
inspect_cmd_unknown()
{
echo "unknown command: $REPLY" 1>&2
echo "Just return to show menu" 1>&2
}
help_inspect ()
{
printf " %-20s %-30s %s\n" "" "-b" "inspect .b (known bug) marked cases"
}
do_units_inspect()
{
local next=0
local r
local t=$1
select r in 'ccept' 'kip (or )' 'hell' 'iff' 'show args.tags' 'show nput' 'xpected tags' 'uit'; do
case $r-$REPLY in
("ccept"-*|-a)
if units_inspect_cmd_accept "$t"; then
next=1
fi
;;
("kip (or )"-*|-s|-!|-skip|-n|-next)
units_inspect_cmd_skip "$t"
next=1
;;
("hell"-*|-S)
inspect_cmd_shell Units "$t"
;;
("iff"-*|-d|-=|-diff)
units_inspect_cmd_show_diff "$t"
;;
("uit"-*|-q|-quit)
inspect_cmd_quit
;;
("show args.tags"-*|-c|-A|-args.ctags)
units_inspect_show_args_ctags "$t"
;;
("show nput"-*|-i|-input)
units_inspect_show_input "$t"
;;
("xpected tags"-*|-e|-expected.tags)
units_inspect_show_expected_tags "$t"
;;
(*)
inspect_cmd_unknown
;;
esac
if [[ $next == 1 ]]; then
break
fi
done
}
function inspect_cmd_shell
{
local prefix=$1
local t=$2
(
cd $prefix/$t
PS1="review> " bash
)
}
function tmain_inspect_run
{
local t=$1
make tmain UNITS=$(basename $t .d)
}
do_tmain_inspect()
{
local next=0
local r
local t=$1
select r in 'ext' 'hell' 'un' 'uit'; do
case $r-$REPLY in
("ext"-*|-n)
next=1
;;
("hell"-*|-S)
inspect_cmd_shell Tmain "$t"
;;
("un"-*|-R)
tmain_inspect_run "$t"
;;
("uit"-*|-q|-quit)
inspect_cmd_quit
;;
esac
if [[ $next == 1 ]]; then
break
fi
done
}
count ()
{
echo $#
}
do_inspect ()
{
local a
local t0
local t
local including_known_bugs
for a in "$@"; do
case $a in
(-b)
including_known_bugs=-b
;;
(-*)
echo "unknown option: ${a}" 1>&2
exit 1
;;
(*)
echo "unexpected argument ${a}" 1>&2
exit 1
;;
esac
done
local T=$(do_list ${including_known_bugs});
local total=$(count $T)
local i=1
for t0 in $T; do
PS3="[$i/$total [ $t0 ]]? "
i=$(( i + 1 ))
t=${t0#Units/}
t=${t#Tmain/}
if [[ "$t0" =~ ^Units ]]; then
do_units_inspect "$t"
else
do_tmain_inspect "$t"
fi
done
}
main ()
{
local action
while [[ $# -gt 0 ]]; do
case $1 in
(help|--help|-h)
print_help 0
;;
(list)
action=$1
shift
break
;;
(inspect)
action=$1
shift
break
;;
(*)
print_help 1 1>&2
;;
esac
done
if [[ -z "$action" ]]; then
action=inspect
fi
if ! [[ -d ./Units ]]; then
echo "$0: cannot find ./Units directory" 1>&2
exit 1
fi
if ! [[ -d ./Tmain ]]; then
echo "$0: cannot find ./Tmain directory" 1>&2
exit 1
fi
do_${action} "$@"
}
main "$@"