-/* Coverage analysis.
+/* Implementation of coverage analysis.
Copyright (C) 2008,2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
# include <config.h>
#endif
-#include "dwarflint-coverage.h"
+#include "dwarflint-coverage.hh"
+extern "C"
+{
+#include "../lib/system.h"
+}
+
#include <stdbool.h>
#include <assert.h>
-#include <system.h>
#include <string.h>
#include <inttypes.h>
-static size_t
-coverage_find (struct coverage const *cov, uint64_t start)
+
+namespace
{
- assert (cov->size > 0);
+ template <class X>
+ decltype (((X *)0)->ranges)
+ coverage_find (X *cov, uint64_t start)
+ {
+ assert (cov->size > 0);
- size_t a = 0;
- size_t b = cov->size;
+ size_t a = 0;
+ size_t b = cov->size;
- while (a < b)
- {
- size_t i = (a + b) / 2;
- struct cov_range const *r = cov->ranges + i;
+ while (a < b)
+ {
+ size_t i = (a + b) / 2;
+ cov_range const *r = cov->ranges + i;
- if (r->start > start)
- b = i;
- else if (r->start < start)
- a = i + 1;
- else
- return i;
- }
+ if (r->start > start)
+ b = i;
+ else if (r->start < start)
+ a = i + 1;
+ else
+ return cov->ranges + i;
+ }
- return a;
+ return cov->ranges + a;
+ }
}
void
return;
}
- struct cov_range *r = cov->ranges + coverage_find (cov, start);
+ struct cov_range *r = coverage_find (cov, start);
struct cov_range *insert = &nr;
struct cov_range *coalesce = &nr;
if (cov->size == 0 || begin == end)
return false;
- struct cov_range *r = cov->ranges + coverage_find (cov, begin);
+ struct cov_range *r = coverage_find (cov, begin);
struct cov_range *erase_begin = NULL, *erase_end = r; // end exclusive
bool overlap = false;
if (cov->size == 0)
return false;
- struct cov_range const *r = cov->ranges + coverage_find (cov, start);
+ struct cov_range const *r = coverage_find (cov, start);
uint64_t end = start + length;
if (r < cov->ranges + cov->size)
if (start >= r->start)
return false;
}
+namespace
+{
+ bool overlaps (uint64_t start, uint64_t end,
+ struct cov_range const *r)
+ {
+ return (start >= r->start && start < r->start + r->length)
+ || (end > r->start && end <= r->start + r->length)
+ || (start < r->start && end > r->start + r->length);
+ }
+}
+
bool
coverage_is_overlap (struct coverage const *cov,
uint64_t start, uint64_t length)
return false;
uint64_t end = start + length;
- bool overlaps (struct cov_range const *r)
- {
- return (start >= r->start && start < r->start + r->length)
- || (end > r->start && end <= r->start + r->length)
- || (start < r->start && end > r->start + r->length);
- }
- struct cov_range const *r = cov->ranges + coverage_find (cov, start);
+ struct cov_range const *r = coverage_find (cov, start);
- if (r < cov->ranges + cov->size && overlaps (r))
+ if (r < cov->ranges + cov->size && overlaps (start, end, r))
return true;
if (r > cov->ranges)
- return overlaps (r - 1);
+ return overlaps (start, end, r - 1);
return false;
}
if (cov->size == 0)
return hole (start, length, data);
- uint64_t end (size_t i)
- {
- return cov->ranges[i].start + cov->ranges[i].length;
- }
-
if (start < cov->ranges[0].start)
if (!hole (start, cov->ranges[0].start - start, data))
return false;
for (size_t i = 0; i < cov->size - 1; ++i)
{
- uint64_t end_i = end (i);
+ uint64_t end_i = cov->ranges[i].end ();
if (!hole (end_i, cov->ranges[i+1].start - end_i, data))
return false;
}
- if (start + length > end (cov->size - 1))
+ if (start + length > cov->back ().end ())
{
- uint64_t end_last = end (cov->size - 1);
+ uint64_t end_last = cov->back ().end ();
return hole (end_last, start + length - end_last, data);
}
free (cov->ranges);
}
-struct coverage *
+coverage *
coverage_clone (struct coverage const *cov)
{
- struct coverage *ret = xmalloc (sizeof (*ret));
+ coverage *ret = (coverage *)xmalloc (sizeof (*ret));
WIPE (*ret);
coverage_add_all (ret, cov);
return ret;
}
void
-coverage_add_all (struct coverage *restrict cov,
- struct coverage const *restrict other)
+coverage_add_all (struct coverage *__restrict__ cov,
+ struct coverage const *__restrict__ other)
{
for (size_t i = 0; i < other->size; ++i)
coverage_add (cov, other->ranges[i].start, other->ranges[i].length);
}
bool
-coverage_remove_all (struct coverage *restrict cov,
- struct coverage const *restrict other)
+coverage_remove_all (struct coverage *__restrict__ cov,
+ struct coverage const *__restrict__ other)
{
bool ret = false;
for (size_t i = 0; i < other->size; ++i)
--- /dev/null
+/* Coverage analysis, C++ support.
+
+ Copyright (C) 2008,2009 Red Hat, Inc.
+ This file is part of Red Hat elfutils.
+
+ Red Hat elfutils 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; version 2 of the License.
+
+ Red Hat elfutils 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 Red Hat elfutils; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+ Red Hat elfutils is an included package of the Open Invention Network.
+ An included package of the Open Invention Network is a package for which
+ Open Invention Network licensees cross-license their patents. No patent
+ license is granted, either expressly or impliedly, by designation as an
+ included package. Should you wish to participate in the Open Invention
+ Network licensing program, please visit www.openinventionnetwork.com
+ <http://www.openinventionnetwork.com>. */
+
+#ifndef DWARFLINT_COVERAGE_HH
+#define DWARFLINT_COVERAGE_HH
+
+#include <string>
+#include <sstream>
+#include "dwarflint-coverage.h"
+
+namespace cov
+{
+ class _format_base
+ {
+ protected:
+ std::string const &_m_delim;
+ std::ostringstream _m_os;
+ bool _m_seen;
+
+ inline bool fmt (uint64_t start, uint64_t length)
+ {
+ if (_m_seen)
+ _m_os << _m_delim;
+ _m_os << "[" << start << ", " << start + length << ")";
+ _m_seen = true;
+ return true;
+ }
+
+ static bool
+ wrap_fmt (uint64_t start, uint64_t length, void *data)
+ {
+ _format_base *self = static_cast <_format_base *> (data);
+ return self->fmt (start, length);
+ }
+
+ _format_base (std::string const &delim)
+ : _m_delim (delim),
+ _m_seen (false)
+ {
+ _m_os << std::hex;
+ }
+
+ public:
+ operator std::string ()
+ {
+ return _m_os.str ();
+ }
+ };
+
+ struct format_ranges
+ : public _format_base
+ {
+ format_ranges (coverage const &cov, std::string const &delim = ", ")
+ : _format_base (delim)
+ {
+ coverage_find_ranges (&cov, &wrap_fmt, this);
+ }
+ };
+
+ struct format_holes
+ : public _format_base
+ {
+ format_holes (coverage const &cov, uint64_t start, uint64_t length,
+ std::string const &delim = ", ")
+ : _format_base (delim)
+ {
+ coverage_find_holes (&cov, start, length, &wrap_fmt, this);
+ }
+ };
+}
+
+#endif//DWARFLINT_COVERAGE_HH