diff options
Diffstat (limited to 'meta-oe/recipes-support/lcov/files/0002-geninfo-Add-intermediate-JSON-format-support.patch')
-rw-r--r-- | meta-oe/recipes-support/lcov/files/0002-geninfo-Add-intermediate-JSON-format-support.patch | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/lcov/files/0002-geninfo-Add-intermediate-JSON-format-support.patch b/meta-oe/recipes-support/lcov/files/0002-geninfo-Add-intermediate-JSON-format-support.patch new file mode 100644 index 0000000000..7b180635cd --- /dev/null +++ b/meta-oe/recipes-support/lcov/files/0002-geninfo-Add-intermediate-JSON-format-support.patch | |||
@@ -0,0 +1,247 @@ | |||
1 | From e13b2b6f8443da660cafa0679c3b16240843ce9f Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Oberparleiter <oberpar@linux.ibm.com> | ||
3 | Date: Fri, 24 May 2019 17:16:56 +0200 | ||
4 | Subject: [PATCH 2/2] geninfo: Add intermediate JSON format support | ||
5 | |||
6 | This change adds support for parsing the output of gcov's intermediate | ||
7 | JSON file format as implemented by GCC version 9. | ||
8 | |||
9 | Note: The way that the intermediate file format support is implemented | ||
10 | in geninfo removes the need to parse .gcno files directly. Since geninfo | ||
11 | does not include support for parsing GCC 9 .gcno files, using the | ||
12 | intermediate format is the only option for geninfo to collect coverage | ||
13 | data generated by GCC version 9. | ||
14 | |||
15 | Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com> | ||
16 | --- | ||
17 | bin/geninfo | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++- | ||
18 | 1 file changed, 160 insertions(+), 2 deletions(-) | ||
19 | |||
20 | Upstream-Status: Backport | ||
21 | Download URL: https://github.com/linux-test-project/lcov/commit/75fbae1cfc5027f818a0bb865bf6f96fab3202da | ||
22 | |||
23 | diff --git a/bin/geninfo b/bin/geninfo | ||
24 | index 0276666..cceb782 100755 | ||
25 | --- a/bin/geninfo | ||
26 | +++ b/bin/geninfo | ||
27 | @@ -59,6 +59,9 @@ use File::Copy qw(copy); | ||
28 | use Getopt::Long; | ||
29 | use Digest::MD5 qw(md5_base64); | ||
30 | use Cwd qw/abs_path/; | ||
31 | +use PerlIO::gzip; | ||
32 | +use JSON qw(decode_json); | ||
33 | + | ||
34 | if( $^O eq "msys" ) | ||
35 | { | ||
36 | require File::Spec::Win32; | ||
37 | @@ -474,7 +477,8 @@ if ($rc_intermediate eq "0") { | ||
38 | $intermediate = 1; | ||
39 | } elsif (lc($rc_intermediate) eq "auto") { | ||
40 | # Use intermediate format if supported by gcov | ||
41 | - $intermediate = $gcov_caps->{'intermediate-format'} ? 1 : 0; | ||
42 | + $intermediate = ($gcov_caps->{'intermediate-format'} || | ||
43 | + $gcov_caps->{'json-format'}) ? 1 : 0; | ||
44 | } else { | ||
45 | die("ERROR: invalid value for geninfo_intermediate: ". | ||
46 | "'$rc_intermediate'\n"); | ||
47 | @@ -2084,6 +2088,48 @@ sub read_intermediate_text($$) | ||
48 | } | ||
49 | |||
50 | |||
51 | +# | ||
52 | +# read_intermediate_json(gcov_filename, data, basedir_ref) | ||
53 | +# | ||
54 | +# Read gcov intermediate JSON format in GCOV_FILENAME and add the resulting | ||
55 | +# data to DATA in the following format: | ||
56 | +# | ||
57 | +# data: source_filename -> file_data | ||
58 | +# file_data: GCOV JSON data for file | ||
59 | +# | ||
60 | +# Also store the value for current_working_directory to BASEDIR_REF. | ||
61 | +# | ||
62 | + | ||
63 | +sub read_intermediate_json($$$) | ||
64 | +{ | ||
65 | + my ($gcov_filename, $data, $basedir_ref) = @_; | ||
66 | + my $fd; | ||
67 | + my $text; | ||
68 | + my $json; | ||
69 | + | ||
70 | + open($fd, "<:gzip", $gcov_filename) or | ||
71 | + die("ERROR: Could not read $gcov_filename: $!\n"); | ||
72 | + local $/; | ||
73 | + $text = <$fd>; | ||
74 | + close($fd); | ||
75 | + | ||
76 | + $json = decode_json($text); | ||
77 | + if (!defined($json) || !exists($json->{"files"}) || | ||
78 | + ref($json->{"files"} ne "ARRAY")) { | ||
79 | + die("ERROR: Unrecognized JSON output format in ". | ||
80 | + "$gcov_filename\n"); | ||
81 | + } | ||
82 | + | ||
83 | + $$basedir_ref = $json->{"current_working_directory"}; | ||
84 | + | ||
85 | + for my $file (@{$json->{"files"}}) { | ||
86 | + my $filename = $file->{"file"}; | ||
87 | + | ||
88 | + $data->{$filename} = $file; | ||
89 | + } | ||
90 | +} | ||
91 | + | ||
92 | + | ||
93 | # | ||
94 | # intermediate_text_to_info(fd, data, srcdata) | ||
95 | # | ||
96 | @@ -2173,6 +2219,104 @@ sub intermediate_text_to_info($$$) | ||
97 | } | ||
98 | |||
99 | |||
100 | +# | ||
101 | +# intermediate_json_to_info(fd, data, srcdata) | ||
102 | +# | ||
103 | +# Write DATA in info format to file descriptor FD. | ||
104 | +# | ||
105 | +# data: filename -> file_data: | ||
106 | +# file_data: GCOV JSON data for file | ||
107 | +# | ||
108 | +# srcdata: filename -> [ excl, brexcl, checksums ] | ||
109 | +# excl: lineno -> 1 for all lines for which to exclude all data | ||
110 | +# brexcl: lineno -> 1 for all lines for which to exclude branch data | ||
111 | +# checksums: lineno -> source code checksum | ||
112 | +# | ||
113 | +# Note: To simplify processing, gcov data is not combined here, that is counts | ||
114 | +# that appear multiple times for the same lines/branches are not added. | ||
115 | +# This is done by lcov/genhtml when reading the data files. | ||
116 | +# | ||
117 | + | ||
118 | +sub intermediate_json_to_info($$$) | ||
119 | +{ | ||
120 | + my ($fd, $data, $srcdata) = @_; | ||
121 | + my $branch_num = 0; | ||
122 | + | ||
123 | + return if (!%{$data}); | ||
124 | + | ||
125 | + print($fd "TN:$test_name\n"); | ||
126 | + for my $filename (keys(%{$data})) { | ||
127 | + my ($excl, $brexcl, $checksums); | ||
128 | + my $file_data = $data->{$filename}; | ||
129 | + | ||
130 | + if (defined($srcdata->{$filename})) { | ||
131 | + ($excl, $brexcl, $checksums) = @{$srcdata->{$filename}}; | ||
132 | + } | ||
133 | + | ||
134 | + print($fd "SF:$filename\n"); | ||
135 | + | ||
136 | + # Function data | ||
137 | + if ($func_coverage) { | ||
138 | + for my $d (@{$file_data->{"functions"}}) { | ||
139 | + my $line = $d->{"start_line"}; | ||
140 | + my $count = $d->{"execution_count"}; | ||
141 | + my $name = $d->{"name"}; | ||
142 | + | ||
143 | + next if (!defined($line) || !defined($count) || | ||
144 | + !defined($name) || $excl->{$line}); | ||
145 | + | ||
146 | + print($fd "FN:$line,$name\n"); | ||
147 | + print($fd "FNDA:$count,$name\n"); | ||
148 | + } | ||
149 | + } | ||
150 | + | ||
151 | + # Line data | ||
152 | + for my $d (@{$file_data->{"lines"}}) { | ||
153 | + my $line = $d->{"line_number"}; | ||
154 | + my $count = $d->{"count"}; | ||
155 | + my $c; | ||
156 | + my $branches = $d->{"branches"}; | ||
157 | + my $unexec = $d->{"unexecuted_block"}; | ||
158 | + | ||
159 | + next if (!defined($line) || !defined($count) || | ||
160 | + $excl->{$line}); | ||
161 | + | ||
162 | + if (defined($unexec) && $unexec && $count == 0) { | ||
163 | + $unexec = 1; | ||
164 | + } else { | ||
165 | + $unexec = 0; | ||
166 | + } | ||
167 | + | ||
168 | + if ($checksum && exists($checksums->{$line})) { | ||
169 | + $c = ",".$checksums->{$line}; | ||
170 | + } else { | ||
171 | + $c = ""; | ||
172 | + } | ||
173 | + print($fd "DA:$line,$count$c\n"); | ||
174 | + | ||
175 | + $branch_num = 0; | ||
176 | + # Branch data | ||
177 | + if ($br_coverage && !$brexcl->{$line}) { | ||
178 | + for my $b (@$branches) { | ||
179 | + my $brcount = $b->{"count"}; | ||
180 | + | ||
181 | + if (!defined($brcount) || $unexec) { | ||
182 | + $brcount = "-"; | ||
183 | + } | ||
184 | + print($fd "BRDA:$line,0,$branch_num,". | ||
185 | + "$brcount\n"); | ||
186 | + | ||
187 | + $branch_num++; | ||
188 | + } | ||
189 | + } | ||
190 | + | ||
191 | + } | ||
192 | + | ||
193 | + print($fd "end_of_record\n"); | ||
194 | + } | ||
195 | +} | ||
196 | + | ||
197 | + | ||
198 | sub get_output_fd($$) | ||
199 | { | ||
200 | my ($outfile, $file) = @_; | ||
201 | @@ -2243,6 +2387,8 @@ sub process_intermediate($$$) | ||
202 | my $srcdata; | ||
203 | my $is_graph = 0; | ||
204 | my ($out, $err, $rc); | ||
205 | + my $json_basedir; | ||
206 | + my $json_format; | ||
207 | |||
208 | info("Processing %s\n", abs2rel($file, $dir)); | ||
209 | |||
210 | @@ -2296,6 +2442,12 @@ sub process_intermediate($$$) | ||
211 | unlink($gcov_filename); | ||
212 | } | ||
213 | |||
214 | + for my $gcov_filename (glob("*.gcov.json.gz")) { | ||
215 | + read_intermediate_json($gcov_filename, \%data, \$json_basedir); | ||
216 | + unlink($gcov_filename); | ||
217 | + $json_format = 1; | ||
218 | + } | ||
219 | + | ||
220 | if (!%data) { | ||
221 | warn("WARNING: GCOV did not produce any data for $file\n"); | ||
222 | return; | ||
223 | @@ -2304,6 +2456,8 @@ sub process_intermediate($$$) | ||
224 | # Determine base directory | ||
225 | if (defined($base_directory)) { | ||
226 | $base = $base_directory; | ||
227 | + } elsif (defined($json_basedir)) { | ||
228 | + $base = $json_basedir; | ||
229 | } else { | ||
230 | $base = $fdir; | ||
231 | |||
232 | @@ -2331,7 +2485,11 @@ sub process_intermediate($$$) | ||
233 | |||
234 | # Generate output | ||
235 | $fd = get_output_fd($output_filename, $file); | ||
236 | - intermediate_text_to_info($fd, \%data, $srcdata); | ||
237 | + if ($json_format) { | ||
238 | + intermediate_json_to_info($fd, \%data, $srcdata); | ||
239 | + } else { | ||
240 | + intermediate_text_to_info($fd, \%data, $srcdata); | ||
241 | + } | ||
242 | close($fd); | ||
243 | |||
244 | chdir($cwd); | ||
245 | -- | ||
246 | 2.17.1 | ||
247 | |||