xref: /Universal-ctags/misc/review (revision 95e1755d31c626ac21df6551840ac4b375a571d6)
1#!/bin/bash
2#
3# review - Review the diff between expected output and actual output in Units
4#
5# Copyright (C) 2016 Masatake YAMATO
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19#
20
21print_help()
22{
23    echo Usage:
24    printf "	%-20s %-30s %s\n" "$0" "help|--help|-h" "show this message"
25    printf "	%-20s %-30s %s\n" "$0" "[list] [-b]" "list failed Units and Tmain"
26    help_list
27    printf "	%-20s %-30s %s\n" "$0" "inspect [-b]" "inspect difference interactively"
28    help_inspect
29    exit $1
30}
31
32is_known_bug()
33{
34    [[ $1 == *.b ]]
35    return $?
36}
37
38do_list ()
39{
40    local d
41    local n
42    local a
43    local including_known_bugs
44
45    for a in "$@"; do
46	case $a in
47	    (-b)
48		including_known_bugs=-b
49		;;
50	    (-*)
51		echo "unknown option: ${a}" 1>&2
52		exit 1
53		;;
54	    (*)
55		echo "unexpected argument ${a}" 1>&2
56		exit 1
57		;;
58	esac
59    done
60
61    for d in $(find Units -name "DIFF.tmp"); do
62	n=$(dirname "$d")
63	if (( ! is_known_bug $(basename "$n") ) || [[ -n ${including_known_bugs} ]] ) \
64	       && [[ -e "$n"/expected.tags ]]; then
65	    echo ${n}
66	fi
67    done
68
69    for d in $(find Tmain -name "*-diff.txt"); do
70	n=$(dirname "$d")
71	echo ${n}
72    done | sort -u
73}
74
75help_list()
76{
77    printf "	%-20s %-30s %s\n" "" "-b" "list .b (known bug) marked cases"
78}
79
80units_inspect_cmd_accept ()
81{
82    local from=./Units/$1/FILTERED.tmp
83    local to=./Units/$1/expected.tags
84    local r
85
86    if [[ ! -e "${from}" ]]; then
87	echo "./Units/$1/FILTERED.tmp is not found" 1>&2
88	echo "Remove DIFF.tmp?"
89	read -p "[Y/n] "
90	if [[ "$REPLY" == Y ]]; then
91	    rm ./Units/$t/DIFF.tmp
92	    echo "Removed: DIFF.tmp"
93	    r=1
94	else
95	    echo "Kept: DIFF.tmp"
96	    r=0
97	fi
98	return $r
99    fi
100
101    echo "Do you really want do following shell command?"
102    echo
103    echo "   mv \"$from\"" '\'
104    echo "      \"$to\" "
105    echo
106    read -p "[Y/n] "
107
108    if [[ "$REPLY" == Y ]]; then
109	mv "$from" "$to"
110	echo "Renamed: $from => $to"
111	r=0
112
113	echo "Remove DIFF.tmp, too?"
114	read -p "[Y/n] "
115	if [[ "$REPLY" == Y ]]; then
116	    rm ./Units/$t/DIFF.tmp
117	    echo "Removed: DIFF.tmp"
118	else
119	    echo "Kept: DIFF.tmp"
120	fi
121    else
122	echo "Aborted"
123	r=1
124    fi
125
126    return $r
127}
128
129units_inspect_cmd_skip ()
130{
131    echo "SKIPPING $1" 1>&2
132}
133
134inspect_cmd_show_generic ()
135{
136    local tcase=$1
137    local file=$2
138    shift 2
139    local f=./Units/${tcase}/${file}
140
141    if [[ -r "$f" ]]; then
142	"$@" "$f"
143    else
144	echo "No ${file}" 1>&2
145    fi
146    echo '---'
147    echo '# ' "$f"
148}
149
150units_inspect_cmd_show_diff ()
151{
152    local cmd=cat
153
154    if which colordiff > /dev/null 2>&1; then
155	cmd=colordiff
156    elif which pygmentize > /dev/null 2>&1; then
157	cmd="pygmentize -l diff"
158    fi
159
160    inspect_cmd_show_generic $1 DIFF.tmp cat | ${cmd}
161}
162
163units_inspect_show_args_ctags ()
164{
165    inspect_cmd_show_generic $1 args.ctags cat
166}
167
168pygmentize_or_cat ()
169{
170    # It seems that pygmentize ignores the empty lines at the head of input.
171    if [ -z "$(head -1 $1)" ]; then
172	cat -n $1
173    elif which pygmentize > /dev/null 2>&1; then
174	pygmentize -O "style=colorful,linenos=1" $1 2>/dev/null || cat -n $1
175    else
176	cat -n $1
177    fi
178}
179
180units_inspect_show_input ()
181{
182    local tcase=$1
183
184    inspect_cmd_show_generic $tcase $(basename ./Units/${tcase}/input.*) pygmentize_or_cat
185}
186
187units_inspect_show_expected_tags ()
188{
189    local tcase=$1
190
191    (
192	shopt -s extglob
193	inspect_cmd_show_generic $tcase $(basename ./Units/${tcase}/expected.tags?(-*)) "cat" "-n"
194    )
195}
196
197inspect_cmd_quit ()
198{
199    echo "BYE" 1>&2
200    exit 0
201}
202
203inspect_cmd_unknown()
204{
205    echo "unknown command: $REPLY" 1>&2
206    echo "Just return to show menu" 1>&2
207}
208
209help_inspect ()
210{
211    printf "	%-20s %-30s %s\n" "" "-b" "inspect .b (known bug) marked cases"
212}
213
214do_units_inspect()
215{
216    local next=0
217    local r
218    local t=$1
219
220    select r in '<a>ccept' '<s>kip (or <n>)' '<S>hell' '<d>iff' 'show args.<c>tags' 'show <i>nput' '<e>xpected tags' '<q>uit'; do
221	case $r-$REPLY in
222	    ("<a>ccept"-*|-a)
223		if units_inspect_cmd_accept "$t"; then
224		    next=1
225		fi
226		;;
227	    ("<s>kip (or <n>)"-*|-s|-!|-skip|-n|-next)
228		units_inspect_cmd_skip "$t"
229		next=1
230		;;
231	    ("<S>hell"-*|-S)
232		inspect_cmd_shell Units "$t"
233		;;
234	    ("<d>iff"-*|-d|-=|-diff)
235		units_inspect_cmd_show_diff "$t"
236		;;
237	    ("<q>uit"-*|-q|-quit)
238		inspect_cmd_quit
239		;;
240	    ("show args.<c>tags"-*|-c|-A|-args.ctags)
241		units_inspect_show_args_ctags "$t"
242		;;
243	    ("show <i>nput"-*|-i|-input)
244		units_inspect_show_input "$t"
245		;;
246	    ("<e>xpected tags"-*|-e|-expected.tags)
247		units_inspect_show_expected_tags "$t"
248		;;
249	    (*)
250		inspect_cmd_unknown
251		;;
252	esac
253	if [[ $next == 1 ]]; then
254	    break
255	fi
256    done
257}
258
259function inspect_cmd_shell
260{
261    local prefix=$1
262    local t=$2
263
264    (
265	cd $prefix/$t
266	PS1="review> " bash
267    )
268}
269
270function tmain_inspect_run
271{
272    local t=$1
273    make tmain UNITS=$(basename $t .d)
274}
275
276do_tmain_inspect()
277{
278    local next=0
279    local r
280    local t=$1
281
282    select r in '<n>ext' '<S>hell' '<R>un' '<q>uit'; do
283	case $r-$REPLY in
284	    ("<n>ext"-*|-n)
285		next=1
286		;;
287	    ("<S>hell"-*|-S)
288		inspect_cmd_shell Tmain "$t"
289		;;
290	    ("<R>un"-*|-R)
291		tmain_inspect_run "$t"
292		;;
293	    ("<q>uit"-*|-q|-quit)
294		inspect_cmd_quit
295		;;
296	esac
297	if [[ $next == 1 ]]; then
298	    break
299	fi
300    done
301}
302
303count ()
304{
305    echo $#
306}
307
308do_inspect ()
309{
310    local a
311    local t0
312    local t
313    local including_known_bugs
314
315    for a in "$@"; do
316	case $a in
317	    (-b)
318		including_known_bugs=-b
319		;;
320	    (-*)
321		echo "unknown option: ${a}" 1>&2
322		exit 1
323		;;
324	    (*)
325		echo "unexpected argument ${a}" 1>&2
326		exit 1
327		;;
328	esac
329    done
330
331    local T=$(do_list ${including_known_bugs});
332    local total=$(count $T)
333    local i=1
334    for t0 in $T; do
335	PS3="[$i/$total [ $t0 ]]? "
336	i=$(( i + 1 ))
337	t=${t0#Units/}
338	t=${t#Tmain/}
339
340	if [[ "$t0" =~ ^Units ]]; then
341	    do_units_inspect "$t"
342	else
343	    do_tmain_inspect "$t"
344	fi
345    done
346}
347
348main ()
349{
350    local action
351
352    while [[ $# -gt 0 ]]; do
353	case $1 in
354	    (help|--help|-h)
355		print_help 0
356		;;
357	    (list)
358		action=$1
359		shift
360		break
361		;;
362	    (inspect)
363		action=$1
364		shift
365		break
366		;;
367	    (*)
368		print_help 1 1>&2
369		;;
370	esac
371    done
372
373    if  [[ -z "$action" ]]; then
374	action=inspect
375    fi
376
377    if ! [[ -d ./Units ]]; then
378	echo "$0: cannot find ./Units directory" 1>&2
379	exit 1
380    fi
381
382    if ! [[ -d ./Tmain ]]; then
383	echo "$0: cannot find ./Tmain directory" 1>&2
384	exit 1
385    fi
386
387    do_${action} "$@"
388}
389
390main "$@"
391