File: cov_types.H

package info (click to toggle)
ggcov 0.9-14
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 4,400 kB
  • ctags: 4,055
  • sloc: cpp: 17,077; sh: 12,380; ansic: 7,743; php: 1,644; perl: 1,509; makefile: 259; yacc: 23
file content (413 lines) | stat: -rw-r--r-- 10,304 bytes parent folder | download | duplicates (4)
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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
/*
 * ggcov - A GTK frontend for exploring gcov coverage data
 * Copyright (c) 2002-2004 Greg Banks <gnb@users.sourceforge.net>
 * 
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _ggcov_cov_types_H_
#define _ggcov_cov_types_H_ 1

#include "common.h"
#include "list.H"

#if HAVE_STDINT_H
typedef uint64_t  	    	count_t;
#define COV_COUNT_MAX	    	UINT64_MAX
#else
typedef unsigned long long int  count_t;
#define COV_COUNT_MAX	    	18446744073709551615ULL
#endif

class cov_file_t;
class cov_function_t;
class cov_block_t;
class cov_arc_t;
struct cov_callnode_t;
struct cov_callarc_t;
struct cov_read_state_t;

struct cov_location_t
{
    char *filename;
    unsigned long lineno;

    int operator==(const cov_location_t &o) const
    {
    	return ((o.lineno == lineno) && !safe_strcmp(o.filename, filename));
    }
    int operator!=(const cov_location_t &o) const
    {
    	return ((o.lineno != lineno) || safe_strcmp(o.filename, filename));
    }
    cov_location_t &operator++()
    {
    	++lineno;
	return *this;
    }
    const char *describe() const;
};

struct cov_location_var
{
    cov_location_t loc_;

    // default c'tor
    cov_location_var()
    {
    	loc_.filename = 0;
    	loc_.lineno = 0;
    }
    // copy c'tor
    cov_location_var(const cov_location_var &o)
    {
    	loc_.filename = (o.loc_.filename != 0 ? g_strdup(o.loc_.filename) : 0);
    	loc_.lineno = o.loc_.lineno;
    }
    // c'tor from cov_location
    cov_location_var(const cov_location_t &o)
    {
    	loc_.filename = (o.filename != 0 ? g_strdup(o.filename) : 0);
    	loc_.lineno = o.lineno;
    }
    ~cov_location_var()
    {
    	if (loc_.filename != 0)
	    g_free(loc_.filename);
    }

    void set(const char *filename, unsigned long lineno)
    {
    	if (loc_.filename != 0)
	    g_free(loc_.filename);
    	loc_.filename = (filename != 0 ? g_strdup(filename) : 0);
    	loc_.lineno = lineno;
    }
    void set(char *filename, unsigned long lineno)
    {
    	if (loc_.filename != 0)
	    g_free(loc_.filename);
    	loc_.filename = filename;
    	loc_.lineno = lineno;
    }
    void invalidate()
    {
    	if (loc_.filename != 0)
	    g_free(loc_.filename);
    	loc_.filename = 0;
    	loc_.lineno = 0;
    }

    // cast to cov_location_t
    operator const cov_location_t() const
    {
    	return loc_;
    }
    
    int operator==(const cov_location_t &o) const
    {
    	return (loc_ == o);
    }
    int operator!=(const cov_location_t &o) const
    {
    	return (loc_ != o);
    }

    const char *describe() const
    {
    	return loc_.describe();
    }
};

struct cov
{
    enum status_t
    {
	COVERED,
	PARTCOVERED,
	UNCOVERED,
	UNINSTRUMENTED,
	SUPPRESSED
    };
    enum _constants
    {
	NUM_STATUS=5
    };

private:
    cov() { }    /* prevent instantiation */
};

class cov_stats_t
{
public:
    /*
     * c'tor zeroes out counters, rather than relying on
     * global operator new, because cov_stats_t is mostly
     * used as an auto or member variable, not allocated.
     */
    cov_stats_t()
    {
    	memset(this, 0, sizeof(*this));
    }
    
    void
    clear()
    {
    	memset(this, 0, sizeof(*this));
    }

    void
    accumulate(const cov_stats_t *st)
    {
    	unsigned int i;
	unsigned long *uthis = (unsigned long *)this;
	unsigned long *ust = (unsigned long *)st;
	
	for (i = 0 ; i < sizeof(*this)/sizeof(unsigned long) ; i++)
	    *uthis++ += *ust++;
    }
    
    /* there are no partial blocks; blocks are the unit of coverage */
    unsigned long blocks_executed() const
    {
    	return blocks_[cov::COVERED];
    }
    unsigned long blocks_total() const
    {
	return blocks_[cov::COVERED] +
	       blocks_[cov::UNCOVERED];
    }
    unsigned long blocks_suppressed() const
    {
    	return blocks_[cov::SUPPRESSED];
    }
    const unsigned long *blocks_by_status() const
    {
    	return blocks_;
    }
    double blocks_fraction() const
    {
    	unsigned long n = blocks_executed();
	unsigned long d = blocks_total();
	return (d == 0 ? 0.0 : (double)n / (double)d);
    }
    /* for sorting objects: -1 forces uninstrumented last */
    double blocks_sort_fraction() const
    {
    	unsigned long n = blocks_executed();
	unsigned long d = blocks_total();
	return (d == 0 ? -1.0 : (double)n / (double)d);
    }

    unsigned long lines_executed() const
    {
	return lines_[cov::COVERED] +
	       lines_[cov::PARTCOVERED];
    }
    unsigned long lines_full() const
    {
    	return lines_[cov::COVERED];
    }
    unsigned long lines_partial() const
    {
    	return lines_[cov::PARTCOVERED];
    }
    unsigned long lines_total() const
    {
	return lines_[cov::COVERED] +
	       lines_[cov::PARTCOVERED] +
	       lines_[cov::UNCOVERED];
    }
    unsigned long lines_suppressed() const
    {
    	return lines_[cov::SUPPRESSED];
    }
    const unsigned long *lines_by_status() const
    {
    	return lines_;
    }
    double lines_fraction() const
    {
    	unsigned long n = lines_executed();
	unsigned long d = lines_total();
	return (d == 0 ? 0.0 : (double)n / (double)d);
    }
    /* for sorting objects: -1 forces uninstrumented last */
    double lines_sort_fraction() const
    {
    	unsigned long n = lines_executed();
	unsigned long d = lines_total();
	return (d == 0 ? -1.0 : (double)n / (double)d);
    }

    unsigned long functions_executed() const
    {
	return functions_[cov::COVERED] +
	       functions_[cov::PARTCOVERED];
    }
    unsigned long functions_full() const
    {
    	return functions_[cov::COVERED];
    }
    unsigned long functions_partial() const
    {
    	return functions_[cov::PARTCOVERED];
    }
    unsigned long functions_total() const
    {
	return functions_[cov::COVERED] +
	       functions_[cov::PARTCOVERED] +
	       functions_[cov::UNCOVERED];
    }
    unsigned long functions_suppressed() const
    {
    	return functions_[cov::SUPPRESSED];
    }
    const unsigned long *functions_by_status() const
    {
    	return functions_;
    }
    double functions_fraction() const
    {
    	unsigned long n = functions_executed();
	unsigned long d = functions_total();
	return (d == 0 ? 0.0 : (double)n / (double)d);
    }
    /* for sorting objects: -1 forces uninstrumented last */
    double functions_sort_fraction() const
    {
    	unsigned long n = functions_executed();
	unsigned long d = functions_total();
	return (d == 0 ? -1.0 : (double)n / (double)d);
    }

    /* calls happen on block boundaries hence cannot be partial */
    unsigned long calls_executed() const
    {
    	return calls_[cov::COVERED];
    }
    unsigned long calls_total() const
    {
	return calls_[cov::COVERED] +
	       calls_[cov::UNCOVERED];
    }
    unsigned long calls_suppressed() const
    {
    	return calls_[cov::SUPPRESSED];
    }
    const unsigned long *calls_by_status() const
    {
    	return calls_;
    }
    double calls_fraction() const
    {
    	unsigned long n = calls_executed();
	unsigned long d = calls_total();
	return (d == 0 ? 0.0 : (double)n / (double)d);
    }
    /* for sorting objects: -1 forces uninstrumented last */
    double calls_sort_fraction() const
    {
    	unsigned long n = calls_executed();
	unsigned long d = calls_total();
	return (d == 0 ? -1.0 : (double)n / (double)d);
    }


    /*
     * Branches happen on block boundaries hence cannot be partial,
     * but for storage purposes we use [PARTCOVERED]=test executed
     * but branch not taken and [COVERED]=branch taken.
     */
    unsigned long branches_executed() const
    {
    	return branches_[cov::COVERED] +
	       branches_[cov::PARTCOVERED];
    }
    unsigned long branches_taken() const
    {
    	return branches_[cov::COVERED];
    }
    unsigned long branches_total() const
    {
	return branches_[cov::COVERED] +
	       branches_[cov::PARTCOVERED] +
	       branches_[cov::UNCOVERED];
    }
    unsigned long branches_suppressed() const
    {
    	return branches_[cov::SUPPRESSED];
    }
    const unsigned long *branches_by_status() const
    {
    	return branches_;
    }
    double branches_fraction() const
    {
    	unsigned long n = branches_executed();
	unsigned long d = branches_total();
	return (d == 0 ? 0.0 : (double)n / (double)d);
    }
    /* for sorting objects: -1 forces uninstrumented last */
    double branches_sort_fraction() const
    {
    	unsigned long n = branches_executed();
	unsigned long d = branches_total();
	return (d == 0 ? -1.0 : (double)n / (double)d);
    }

    /* Used in calculating status for aggregated objects like functions */
    cov::status_t status_by_blocks()
    {
	unsigned long ntot = blocks_total();

    	if (!ntot)
	    return (blocks_[cov::SUPPRESSED] ? cov::SUPPRESSED : cov::UNINSTRUMENTED);
	else if (blocks_[cov::COVERED] == ntot)
    	    return cov::COVERED;
	else if (blocks_[cov::UNCOVERED] == ntot)
    	    return cov::UNCOVERED;
	else
    	    return cov::PARTCOVERED;
    }
    cov::status_t status_by_lines()
    {
	unsigned long ntot = lines_total();

    	if (!ntot)
	    return (lines_[cov::SUPPRESSED] ? cov::SUPPRESSED : cov::UNINSTRUMENTED);
	else if (lines_[cov::COVERED] == ntot)
    	    return cov::COVERED;
	else if (lines_[cov::UNCOVERED] == ntot)
    	    return cov::UNCOVERED;
	else
    	    return cov::PARTCOVERED;
    }

private:
    unsigned long blocks_[cov::NUM_STATUS];
    unsigned long lines_[cov::NUM_STATUS];
    unsigned long functions_[cov::NUM_STATUS];
    unsigned long calls_[cov::NUM_STATUS];
    unsigned long branches_[cov::NUM_STATUS];
    
    friend class cov_block_t;
    friend class cov_function_t;
    friend class cov_file_t;
};


#endif /* _ggcov_cov_types_H_ */