File: cpptests.sh

package info (click to toggle)
coccinelle 1.3.0.deb-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,888 kB
  • sloc: ml: 96,585; ansic: 23,664; sh: 1,695; perl: 1,576; makefile: 1,002; python: 922; lisp: 832; cpp: 655; awk: 70; csh: 12
file content (371 lines) | stat: -rwxr-xr-x 12,099 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#!/bin/bash

# Run this script in cpptests/ to get a report on the tests.

# shellcheck disable=SC2086
set -e
#set -x

spatch=../spatch.opt
declare -A FAILED_RUN
declare -A FAILED_PP
declare -A FAILED_CP
declare -A TEST_CASE_BROKEN
declare -A TEST_CASE_FAILS
declare -A REFTAGS
declare -A REFTOTEST

cat_tags_file() {
cat << EOF
access_specifiers_0.cocci v20240610:language/access
access_specifiers_1.cocci v20240610:language/access
access_specifiers_1_class.cocci v20240610:language/access v20240610:language/class
access_specifiers_2.cocci v20240610:language/access
access_specifiers_3.cocci v20240610:language/access
access_specifiers_4.cocci v20240610:language/access
addremvec.cocci v20240610:language/template_parameters#Template_arguments
aggregate_initialization.cocci v20240610:language/aggregate_initialization#Syntax
attributeu.cocci v20240610:language/attributes
auto.cocci v20240610:language/auto
autoloop.cocci v20240610:language/range-for
bool1.cocci v20240610:language/function
bracket.cocci v20240610:language/aggregate_initialization#Syntax
bracketed_expression_assignment.cocci v20240610:language/aggregate_initialization#Syntax
braced_init_list.cocci v20240610:language/explicit_cast#Explanation
braced_init_list_return.cocci v20240610:language/return
braced_init_list_assign.cocci v20240610:language/initialization#Initializer
braced_init_list_arg.cocci v20240610:language/initialization#Initializer v20240610:language/function
cdstr.cocci v20240610:language/constructor
snip_field_bad.cocci v20240610:language/class
snip_field_and_keep_access_specifier.cocci v20240610:language/class v20240610:language/access
classfinal.cocci v20240610:language/final
complexcpp.cocci v20240610:numeric/complex v20240610:header/complex
cuda1.cocci v20240610:language/operator_other#Built-in_function_call_operator
cuda.cocci v20240610:language/function#Function_definition
cuda_noattr.cocci v20240610:language/operator_other#Built-in_function_call_operator
decl_andand_ref.cocci v20240610:language/reference#Rvalue_references
decl_and_ref.cocci v20240610:language/reference#Rvalue_references
decl_ptr_ref.cocci v20240610:language/pointer#Pointers
decltype.cocci v20240610:language/decltype
decltype_matches_type.cocci v20240610:language/decltype
delete_array.cocci v20240610:language/delete#Syntax
delete.cocci v20240610:language/delete#Syntax
destructor_constructor_parse v20240610:language/access v20240610:language/class v20240610:language/destructor
destructor_constructor_parse_smpl v20240610:language/access v20240610:language/class v20240610:language/destructor
emptytmp.cocci v20240610:language/template_parameters#Template_arguments
endcolon.cocci v20240610:language/qualified_lookup
endline.cocci v20240610:language/template_parameters#Template_arguments v20240610:language/qualified_lookup
enumcpp.cocci v20240610:language/enum
fieldtmp.cocci v20240610:language/operator_member_access
finalclass.cocci v20240610:language/final#Syntax
forc.cocci v20240610:language/template_parameters#Template_arguments
forrange2.cocci v20240610:language/range-for
forrange.cocci v20240610:language/range-for
inh1.cocci v20240610:language/derived_class
init3tst.cocci v20240610:language/aggregate_initialization#Syntax
instfour.cocci v20240610:language/template_parameters#Template_arguments
instruct.cocci v20240610:language/using_declaration v20240610:preprocessor/impl
list_and_aggregate_initialization_isomorphism_off.cocci v20240610:language/aggregate_initialization#Syntax
list_and_aggregate_initialization_isomorphism_on.cocci v20240610:language/aggregate_initialization#Syntax
list_initialization.cocci v20240610:language/aggregate_initialization#Syntax
local_macro_fn_def_and_call.cocci v20240610:preprocessor
macro_stmt_when_fn_type.cocci v20240610:preprocessor
match_bracket_expressions_assignment_broken.cocci v20240610:language/aggregate_initialization#Syntax
miniclass.cocci v20240610:language/class
namespace_alias_definition.cocci v20240610:language/namespace_alias
namespace_nested1.cocci v20240610:language/namespace
namespace_nested2.cocci v20240610:language/namespace
namespace_nested3.cocci v20240610:language/namespace
namespace_nested4.cocci v20240610:language/namespace
new2.cocci v20240610:language/new#Syntax
new3.cocci v20240610:language/new#Syntax
new.cocci v20240610:language/new#Syntax
newsimple.cocci v20240610:language/new#Syntax
noexcept.cocci v20240610:language/noexcept_spec
notpp.cocci v20240610:keyword/not
opeq.cocci v20240610:language/operators
protocpp.cocci v20240610:language/reference#Rvalue_references
qualclass.cocci v20240610:language/derived_class v20240610:language/qualified_lookup
qual.cocci v20240610:language/qualified_lookup
sizet.cocci v20240610:cpp/types/size_t
snip_field.cocci v20240610:language/class
tempinstfour.cocci v20240610:language/template_parameters#Template_arguments
templates1.cocci v20240610:language/template_parameters#Template_arguments
template_test.cocci v20240610:language/template_parameters#Template_arguments
templates_partial_specialization v20240610:language/template_parameters#Template_arguments v20240610:language/partial_specialization
tmpinit.cocci v20240610:language/template_parameters#Template_arguments
tmpinst2.cocci v20240610:language/template_parameters#Template_arguments
tmpinst4.cocci v20240610:language/template_parameters#Template_arguments
tmpinst5.cocci v20240610:language/template_parameters#Template_arguments
try_catch1.cocci v20240610:language/try v20240610:language/catch
try_catch2.cocci v20240610:language/try v20240610:language/catch
try_catch.cocci v20240610:language/try v20240610:language/catch
using1.cocci v20240610:language/using_declaration
using2.cocci v20240610:language/using_declaration
using3.cocci v20240610:language/using_declaration
using4.cocci v20240610:language/using_declaration
usingtest.cocci v20240610:language/using_declaration
usingtype.cocci v20240610:language/using_declaration
vconstr.cocci v20240610:language/virtual v20240610:language/destructor
virtual_constructor.cocci v20240610:language/virtual v20240610:language/destructor
while_init_condition.cocci v20240610:language/while
while_init_condition_smpl.cocci v20240610:language/while
EOF
}

read_tags_file() {
	while read cf tags;
	do
		if test $cf = '#'; then continue; fi
		tn=${cf/.cocci/};
		REFTAGS[$tn]=$tags
		#echo ${REFTAGS[$cf]}
	done < <( cat_tags_file )
}

populate_ref_to_test_array() {
	for tn in ${!REFTAGS[*]}; do
	for tag in ${REFTAGS[$tn]}; do
		if [[ $tag =~ v20240610: ]] ; then
			url='https://en.cppreference.com/w/cpp/'${tag/v20240610:/};
			REFTOTEST[$url]+=" $tn"
		fi
	done
	done
}

check_tags_sanity() {
	local rc=0;
	local UNTAGGED_TEST_FILES=''
	for cf in *.cocci; do
		tn=${cf/.cocci/};
		if test -z "${REFTAGS[$tn]}"; then UNTAGGED_TEST_FILES+=" $cf"; fi
	done
	local ORPHANED_TEST_LINES=''
	for tn in ${!REFTAGS[*]}; do
		if ! test -f $tn.cocci ; then ORPHANED_TEST_LINES+=" $tn"; fi
	done
	if test -n "${UNTAGGED_TEST_FILES}"; then echo "ERROR: Untagged test files: ${UNTAGGED_TEST_FILES}"; rc=1; fi
	if test -n "${ORPHANED_TEST_LINES}"; then echo "ERROR: Orphaned test lines: ${ORPHANED_TEST_LINES}"; rc=1; fi
	if test "${rc}" != 0; then exit $rc; fi
}

read_tags_file
populate_ref_to_test_array
check_tags_sanity

for cf in *.cocci; do
	tn=${cf/.cocci/};
	if ! ( head -n1 $cf | grep -q -- --c++ ) ; then echo "you forgot --c++ flag in $cf file"; false; fi # --c++ is required
	set +e
	$spatch --test $tn
	FAILED_RUN[$tn]=$?
	set -e
	set +e
	$spatch --parse-cocci $tn.cocci
	FAILED_PP[$tn]=$?
	set -e
	set +e
	( $spatch --c++ --parse-c $tn.cpp && $spatch --c++ --parse-c $tn.cpp | grep -q '100.*good.or.passed' );
	FAILED_CP[$tn]=$?;
	set -e
	if test ${FAILED_RUN[$tn]} = 0; then
		cmpfile=$tn.cmp
		set +e
		$spatch --sp-file $tn.cocci $tn.cpp -o $cmpfile
		TEST_CASE_BROKEN[$tn]=$?
		cmp $tn.res $cmpfile
		TEST_CASE_FAILS[$tn]=$?
		set -e
	fi
	rm -f $cmpfile
	set -e
done

function maybe_html_arrow()
{
	if test -n "$WANT_HTML"; then echo '&rarr;'; else echo '->'; fi
}

function file_title()
{
	echo "<CODE CLASS=\"H4\">$1</CODE>"
}

function header() {
	local PRE='' POST=''
	if test -n "$WANT_HTML"; then
		PRE+="<H2>";
		POST+="</H2>";
		if test "$1" = '-n'; then shift; else POST+="<BR>"; fi
	else
		if test "$1" = '-n'; then PRE+='-n'; fi
	fi
	echo "$PRE" "$@" "$POST"
}

function to_href() {
	if test $# = 0 ; then cat ; else echo "${1}"; fi | \
		sed 's/^\(.\+\)$/\<A HREF="\1"\>\1\<\/A\>/g'
}

function to_href2() {
	echo -n '<A HREF="'$1'">'$2'</A>'
}

function maybe_to_href() {
	if test -n "$WANT_HTML"; then to_href $@; else echo $@; fi
}

function maybe_to_anchor_href() {
	if test -n "$WANT_HTML"; then
		while read -d ' ' td; do
			#if test -z "$tn" ; then continue; fi
			tn=${td//\*/}
			#echo -n "bu:$tn"
			to_href2 "#${tn}" "${td}"; echo -n ' '
		done | sed 's/$/<BR>/g'
	else
		cat
	fi
}

function cat_all_as_pre() {
	for f in $1.cocci $1.cpp $1.res; do
		#echo "<BR>"
		file_title "$f"; echo -n ':'
		#echo "<BR>"
		! txt2html --prebegin 0 --bold_delimiter '' --italic_delimiter '' --underline_delimiter '' --extract "$f" # TODO: new2.res and a few others are missing
		true # the above can fail
		#echo "<BR>"
	done
}

function test_reference() {
	if test -n "$WANT_HTML"; then
		tr -d ' ' | \
		while read tn; do \
			#echo "<BR>"
			echo -n "<A ID=\"$tn\">"'</A>';
			echo '<H3>Test: '
			to_href2 "#$tn" "${tn}";
			echo '</H3>'
			#echo "<BR>"
			cat_all_as_pre $tn
		done
	else
		tr -d '\n' | cat
	fi
}

print_results() {
if test -n "$WANT_HTML"; then
	echo '<!DOCTYPE HTML><HTML><HEAD><TITLE>C++ Tests</TITLE>
<HEAD>
<STYLE>
BODY { COLOR: BLACK; BACKGROUND: WHITE; }
H1 { BACKGROUND: SILVER; COLOR: BLACK; }
H2 { BACKGROUND: SILVER; COLOR: BLACK; }
H3 { BACKGROUND: LIGHTGRAY; COLOR: BLACK; }
H4 { BACKGROUND: LIGHTGRAY; COLOR: BLACK; }
CODE.H4 { BACKGROUND: LIGHTGRAY; COLOR: BLACK; }
</STYLE>
</HEAD>
<BODY>
<H1> Coccinelle C++ Tests Results Summary</H1>
';
fi
echo
header -n 'CPPREFERENCE AND TESTS: '
for rn in ${!REFTOTEST[*]}; do
	if test "${REFTOTEST[$rn]}" != ''; then
		echo -n "	`maybe_to_href $rn` `maybe_html_arrow` "
		for tn in ${REFTOTEST[$rn]}; do
			echo -n ${tn};
			if test "${FAILED_PP[$tn]}" != 0 -o "${TEST_CASE_FAILS[$tn]}" != 0 -o "${FAILED_RUN[$tn]}" != 0; then echo -n '* '; else echo -n ' '; fi
		done | maybe_to_anchor_href
		echo
	fi
done | sort
echo
header -n 'TEST CASE BROKEN (spatch ... exits non-zero): '
for tn in ${!TEST_CASE_BROKEN[*]}; do
	if test ${TEST_CASE_BROKEN[$tn]} != 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'TEST FAILS (patches differ): '
for tn in ${!TEST_CASE_FAILS[*]}; do
	if test ${TEST_CASE_FAILS[$tn]} != 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'PASSED SPATCH PARSE: '
for tn in ${!FAILED_PP[*]}; do
	if test ${FAILED_PP[$tn]} = 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'FAILED SPATCH PARSE: '
for tn in ${!FAILED_PP[*]}; do
	if test ${FAILED_PP[$tn]} != 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'PASSED SOURCE PARSE: '
for tn in ${!FAILED_CP[*]}; do
	if test ${FAILED_CP[$tn]} = 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'FAILED SOURCE PARSE: '
for tn in ${!FAILED_CP[*]}; do
	if test ${FAILED_CP[$tn]} != 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'PASSED TEST RUNS: '
for tn in ${!FAILED_RUN[*]}; do
	if test ${FAILED_RUN[$tn]} = 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'FAILED TEST RUNS: '
for tn in ${!FAILED_RUN[*]}; do
	if test ${FAILED_RUN[$tn]} != 0; then
		echo "$tn "
	fi
done | sort | maybe_to_anchor_href
echo
header -n 'SOURCES FOR ALL TESTS:'
for tn in ${!REFTAGS[*]}; do
	echo "$tn "
done | sort | test_reference
echo
if test -n "$WANT_HTML"; then echo '<BODY><HTML>';fi
}

while getopts "o:" NAME; do
	case $NAME in
		o) WANT_HTML=$OPTARG;
			which txt2html
		;;
		# TODO: add -h
		*) false;;
	esac
done
shift $((OPTIND-1))

if test -n "$WANT_HTML"; then
	# TODO: Or MD?
	print_results > "$WANT_HTML"
else
	print_results
fi