Fix $XAPP_DESCRIPTOR_PATH parser bug
[ric-plt/xapp-frame-cpp.git] / test / parse_gcov.sh
1 #!/usr/bin/env bash
2 # vim: ts=4 sw=4 noet :
3
4 #==================================================================================
5 #       Copyright (c) 2020 Nokia
6 #       Copyright (c) 2020 AT&T Intellectual Property.
7 #
8 #   Licensed under the Apache License, Version 2.0 (the "License");
9 #   you may not use this file except in compliance with the License.
10 #   You may obtain a copy of the License at
11 #
12 #       http://www.apache.org/licenses/LICENSE-2.0
13 #
14 #   Unless required by applicable law or agreed to in writing, software
15 #   distributed under the License is distributed on an "AS IS" BASIS,
16 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 #   See the License for the specific language governing permissions and
18 #   limitations under the License.
19 #==================================================================================
20
21 #
22 #       Parse the .gcov file and discount any unexecuted lines which are in if()
23 #       blocks which are testing the result of alloc/malloc calls, or testing for
24 #       nil pointers.  The feeling is that these might not be possible to drive
25 #       and shoudn't contribute to coverage deficiencies.
26 #
27 #       In verbose mode, the .gcov file is written to stdout and any unexecuted
28 #       line which is discounted is marked with ===== replacing the ##### marking
29 #       that gcov wrote.
30 #
31 #       The return value is 0 for pass; non-zero for fail.
32 #
33 function discount_ck {
34         typeset f="$1"
35
36         mct=80                                                  # force minimum coverage threshold for passing
37
38         if [[ ! -f $f ]]
39         then
40                 if [[ -f ${f##*/} ]]
41                 then
42                         f=${f##*/}
43                 else
44                         echo "cant find: $f"
45                         return
46                 fi
47         fi
48
49         awk -v module_cov_target=$mct \
50                 -v cfail=${cfail:-WARN} \
51                 -v show_all=$show_all \
52                 -v full_name="${1}"  \
53                 -v module="${f%.*}"  \
54                 -v chatty=$chatty \
55                 -v replace_flags=$replace_flags \
56         '
57         function spit_line( ) {
58                 if( chatty ) {
59                         printf( "%s\n", $0 )
60                 }
61         }
62
63         /-:/ {                                          # skip unexecutable lines
64                 spit_line()
65                 seq++                                   # allow blank lines in a sequence group
66                 next
67         }
68
69         {
70                 nexec++                                 # number of executable lines
71         }
72
73         /#####:/ {
74                 unexec++;
75                 if( $2+0 != seq+1 ) {
76                         prev_malloc = 0
77                         prev_if = 0
78                         seq = 0
79                         spit_line()
80                         next
81                 }
82
83                 if( prev_if && prev_malloc ) {
84                         if( prev_malloc ) {
85                                 #printf( "allow discount: %s\n", $0 )
86                                 if( replace_flags ) {
87                                         gsub( "#####", "    1", $0 )
88                                         //gsub( "#####", "=====", $0 )
89                                 }
90                                 discount++;
91                         }
92                 }
93
94                 seq++;;
95                 spit_line()
96                 next;
97         }
98
99         /if[(].*alloc.*{/ {                     # if( (x = malloc( ... )) != NULL ) or if( (p = sym_alloc(...)) != NULL )
100                 seq = $2+0
101                 prev_malloc = 1
102                 prev_if = 1
103                 spit_line()
104                 next
105         }
106
107         /if[(].* == NULL/ {                             # a nil check likely not easily forced if it wasnt driven
108                 prev_malloc = 1
109                 prev_if = 1
110                 spit_line()
111                 seq = $2+0
112                 next
113         }
114
115         /if[(]/ {
116                 if( seq+1 == $2+0 && prev_malloc ) {            // malloc on previous line
117                         prev_if = 1
118                 } else {
119                         prev_malloc = 0
120                         prev_if = 0
121                 }
122                 spit_line()
123                 next
124         }
125
126         /alloc[(]/ {
127                 seq = $2+0
128                 prev_malloc = 1
129                 spit_line()
130                 next
131         }
132
133         {
134                 spit_line()
135         }
136
137         END {
138                 net = unexec - discount
139                 orig_cov = ((nexec-unexec)/nexec)*100           # original coverage
140                 adj_cov = ((nexec-net)/nexec)*100                       # coverage after discount
141                 pass_fail = adj_cov < module_cov_target ? cfail : "PASS"
142                 rc = adj_cov < module_cov_target ? 1 : 0
143                 if( pass_fail == cfail || show_all ) {
144                         if( chatty ) {
145                                 printf( "[%s] %s executable=%d unexecuted=%d discounted=%d net_unex=%d  cov=%d%% ==> %d%%  target=%d%%\n",
146                                         pass_fail, full_name ? full_name : module, nexec, unexec, discount, net, orig_cov, adj_cov, module_cov_target )
147                         } else {
148                                 printf( "[%s] %d%% (%d%%) %s\n", pass_fail, adj_cov, orig_cov, full_name ? full_name : module )
149                         }
150                 }
151
152                 exit( rc )
153         }
154         ' $f
155 }
156
157 # ----------------------------------------------------------------------
158 show_all=1                      # turn off to hide passing modules (-q)
159 chatty=0                        # -v turns on to provide more info when we do speak
160
161 while [[ $1 == "-"* ]]
162 do
163         case $1 in 
164                 -q)     show_all=0;;
165                 -v)     chatty=1;;
166
167                 *)      echo "unrecognised option: $1"
168                         echo "usage: $0 [-q] gcov-file-list"
169                         exit 1
170                         ;;
171         esac
172         shift
173 done
174
175
176 while [[ -n $1 ]]
177 do
178         discount_ck $1
179         shift
180 done