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_ */
|