#! /usr/bin/env python
#
# A report generator for gcov 3.4
#
# This routine generates a format that is similar to the format generated
# by the Python coverage.py module.  This code is similar to the
# data processing performed by lcov's geninfo command.  However, we
# don't worry about parsing the *.gcna files, and backwards compatibility for
# older versions of gcov is not supported.
#
# Outstanding issues
#   - verify that gcov 3.4 or newer is being used
#   - verify support for symbolic links
#
# gcovr is a FAST project.  For documentation, bug reporting, and
# updates, see https://software.sandia.gov/trac/fast/wiki/gcovr
#
# _________________________________________________________________________
#
# FAST: Utilities for Agile Software Development
# Copyright (c) 2008 Sandia Corporation.
# This software is distributed under the BSD License.
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
# For more information, see the FAST README.txt file.
#
# $Revision: 2839 $
# $Date: 2013-05-27 11:13:17 -0700 (Mon, 27 May 2013) $
# _________________________________________________________________________
#

import copy
import glob
import os
import re
import subprocess
import sys
import time
import xml.dom.minidom

from optparse import OptionParser
from string import Template
from os.path import normpath

__version__ = "2.5-prerelease"
src_revision = "$Revision: 2839 $"
gcov_cmd = "gcov"

output_re = re.compile("[Cc]reating [`'](.*)'$")
source_re = re.compile("cannot open (source|graph) file")

starting_dir = os.getcwd()


def version_str():
    ans = __version__
    m = re.match('\$Revision:\s*(\S+)\s*\$', src_revision)
    if m:
        ans = ans + " (r%s)" % (m.group(1))
    return ans

#
# Container object for coverage statistics
#
class CoverageData(object):

    def __init__(self, fname, uncovered, uncovered_exceptional, covered, branches, noncode):
        self.fname=fname
        # Shallow copies are cheap & "safe" because the caller will
        # throw away their copies of covered & uncovered after calling
        # us exactly *once*
        self.uncovered = copy.copy(uncovered)
        self.uncovered_exceptional = copy.copy(uncovered_exceptional)
        self.covered   = copy.copy(covered)
        self.noncode   = copy.copy(noncode)
        # But, a deep copy is required here
        self.all_lines = copy.deepcopy(uncovered)
        self.all_lines.update(uncovered_exceptional)
        self.all_lines.update(covered.keys())
        self.branches = copy.deepcopy(branches)

    def update(self, uncovered, uncovered_exceptional, covered, branches, noncode):
        self.all_lines.update(uncovered)
        self.all_lines.update(uncovered_exceptional)
        self.all_lines.update(covered.keys())
        self.uncovered.update(uncovered)
        self.uncovered_exceptional.update(uncovered_exceptional)
        self.noncode.intersection_update(noncode)
        for k in covered.keys():
            self.covered[k] = self.covered.get(k,0) + covered[k]
        for k in branches.keys():
            for b in branches[k]:
                d = self.branches.setdefault(k, {})
                d[b] = d.get(b, 0) + branches[k][b]
        self.uncovered.difference_update(self.covered.keys())
        self.uncovered_exceptional.difference_update(self.covered.keys())

    def uncovered_str(self, exceptional):
        if options.show_branch:
            # Don't do any aggregation on branch results
            tmp = []
            for line in self.branches.keys():
                for branch in self.branches[line]:
                    if self.branches[line][branch] == 0:
                        tmp.append(line)
                        break

            tmp.sort()
            return ",".join([str(x) for x in tmp]) or ""
        
        if exceptional:
            tmp = list(self.uncovered_exceptional)
        else:
            tmp = list(self.uncovered)
        if len(tmp) == 0:
            return ""

        tmp.sort()
        first = None
        last = None
        ranges=[]
        for item in tmp:
            if last is None:
                first=item
                last=item
            elif item == (last+1):
                last=item
            else:
                if len(self.noncode.intersection(range(last+1,item))) \
                       == item - last - 1:
                    last = item
                    continue
                
                if first==last:
                    ranges.append(str(first))
                else:
                    ranges.append(str(first)+"-"+str(last))
                first=item
                last=item
        if first==last:
            ranges.append(str(first))
        else:
            ranges.append(str(first)+"-"+str(last))
        return ",".join(ranges)

    def coverage(self):
        if ( options.show_branch ):
            total = 0
            cover = 0
            for line in self.branches.keys():
                for branch in self.branches[line].keys():
                    total += 1
                    cover += self.branches[line][branch] > 0 and 1 or 0
        else:
            total = len(self.all_lines)
            cover = len(self.covered)
            
        percent = total and str(int(100.0*cover/total)) or "--"
        return (total, cover, percent)

    def summary(self):
        tmp = options.filter.sub('',self.fname)
        if not self.fname.endswith(tmp):
            # Do no truncation if the filter does not start matching at
            # the beginning of the string
            tmp = self.fname
        tmp = tmp.ljust(40)
        if len(tmp) > 40:
            tmp=tmp+"\n"+" "*40

        (total, cover, percent) = self.coverage()
        uncovered_lines = self.uncovered_str(False) 
        if not options.show_branch: 
            t = self.uncovered_str(True) 
            if len(t): 
                uncovered_lines += " [* " + t + "]"; 
        return ( total, cover,
                 tmp + str(total).rjust(8) + str(cover).rjust(8) + \
                 percent.rjust(6) + "%   " + uncovered_lines )


def resolve_symlinks(orig_path):
    """
    Return the normalized absolute path name with all symbolic links resolved
    """
    drive,tmp = os.path.splitdrive(os.path.abspath(orig_path))
    if not drive:
        drive = os.path.sep
    parts = tmp.split(os.path.sep)
    actual_path = [drive]
    while parts:
        actual_path.append(parts.pop(0))
        if not os.path.islink(os.path.join(*actual_path)):
            continue
        actual_path[-1] = os.readlink(os.path.join(*actual_path))
        tmp_drive, tmp_path = os.path.splitdrive(
            resolve_symlinks(os.path.join(*actual_path)) )
        if tmp_drive:
            drive = tmp_drive
        actual_path = [drive] + tmp_path.split(os.path.sep)
    return os.path.join(*actual_path)


def path_startswith(path, base):
    return path.startswith(base) and (
        len(base) == len(path) or path[len(base)] == os.path.sep )


class PathAliaser(object):
    def __init__(self):
        self.aliases = {}
        self.master_targets = set()
        self.preferred_name = {}

    def master_path(self, path):
        match_found = False
        while True:
            for base, alias in self.aliases.items():
                if path_startswith(path, base):
                    path = alias + path[len(base):]
                    match_found = True
                    break
            for master_base in self.master_targets:
                if path_startswith(path, master_base):
                    return path, master_base, True
            if match_found:
                sys.stderr.write(
                    "(ERROR) violating fundamental assumption while walking "
                    "directory tree.\n\tPlease report this to the gcovr "
                    "developers.\n" )
            return path, None, match_found

    def unalias_path(self, path):
        path = resolve_symlinks(path)
        path, master_base, known_path = self.master_path(path)
        if not known_path:
            return path
        # Try and resolve the preferred name for this location
        if master_base in self.preferred_name:
            return self.preferred_name[master_base] + path[len(master_base):]
        return path

    def add_master_target(self, master):
        self.master_targets.add(master)

    def add_alias(self, target, master):
        self.aliases[target] = master

    def set_preferred(self, master, preferred):
        self.preferred_name[master] = preferred

aliases = PathAliaser()

# This is UGLY.  Here's why: UNIX resolves symbolic links by walking the
# entire directory structure.  What that means is that relative links
# are always relative to the actual directory inode, and not the
# "virtual" path that the user might have traversed (over symlinks) on
# the way to that directory.  Here's the canonical example:
#
#   a / b / c / testfile
#   a / d / e --> ../../a/b
#   m / n --> /a
#   x / y / z --> /m/n/d
#
# If we start in "y", we will see the following directory structure:
#   y
#   |-- z
#       |-- e
#           |-- c
#               |-- testfile
#
# The problem is that using a simple traversal based on the Python
# documentation:
#
#    (os.path.join(os.path.dirname(path), os.readlink(result)))
#
# will not work: we will see a link to /m/n/d from /x/y, but completely
# miss the fact that n is itself a link.  If we then naively attempt to
# apply the "c" relative link, we get an intermediate path that looks
# like "/m/n/d/e/../../a/b", which would get normalized to "/m/n/a/b"; a
# nonexistant path.  The solution is that we need to walk the original
# path, along with the full path of all links 1 directory at a time and
# check for embedded symlinks.
#
def link_walker(path):
    targets = [os.path.abspath(path)]
    while targets:
        target_dir = targets.pop(0)
        actual_dir = resolve_symlinks(target_dir)
        #print "target dir: %s  (%s)" % (target_dir, actual_dir)
        master_name, master_base, visited = aliases.master_path(actual_dir)
        if visited:
            #print "  ...root already visited as %s" % master_name
            aliases.add_alias(target_dir, master_name)
            continue
        if master_name != target_dir:
            aliases.set_preferred(master_name, target_dir)
            aliases.add_alias(target_dir, master_name)
        aliases.add_master_target(master_name)
        #print "  ...master name = %s" % master_name
        #print "  ...walking %s" % target_dir
        for root, dirs, files in os.walk(target_dir, topdown=True):
            #print "    ...reading %s" % root
            for d in dirs:
                tmp = os.path.abspath(os.path.join(root, d))
                #print "    ...checking %s" % tmp
                if os.path.islink(tmp):
                    #print "      ...buffering link %s" % tmp
                    targets.append(tmp)
            yield root, dirs, files


def search_file(expr, path):
    """
    Given a search path, recursively descend to find files that match a
    regular expression.
    """
    ans = []
    pattern = re.compile(expr)
    if path is None or path == ".":
        path = os.getcwd()
    elif not os.path.exists(path):
        raise IOError("Unknown directory '"+path+"'")
    for root, dirs, files in link_walker(path):
        for name in files:
            if pattern.match(name):
                name = os.path.join(root,name)
                if os.path.islink(name):
                    ans.append( os.path.abspath(os.readlink(name)) )
                else:
                    ans.append( os.path.abspath(name) )
    return ans


#
# Get the list of datafiles in the directories specified by the user
#
def get_datafiles(flist, options):
    allfiles=[]
    for dir in flist:
        if options.verbose:
            sys.stdout.write( "Scanning directory %s for gcda/gcno files...\n"
                              % (dir, ) )
        files = search_file(".*\.gc(da|no)$", dir)
        # gcno files will *only* produce uncovered results; however,
        # that is useful information for the case where a compilation
        # unit is never actually exercised by the test code.  So, we
        # will process gcno files, but ONLY if there is no corresponding
        # gcda file.
        gcda_files = [file for file in files if file.endswith('gcda')]
        tmp = set(gcda_files)
        gcno_files = [ file for file in files if
                       file.endswith('gcno') and file[:-2]+'da' not in tmp ]
        if options.verbose:
            sys.stdout.write(
                "Found %d files (and will process %d)\n" %
                ( len(files), len(gcda_files) + len(gcno_files) ) )
        allfiles.extend(gcda_files)
        allfiles.extend(gcno_files)
    return allfiles


def process_gcov_data(file, covdata, options):
    INPUT = open(file,"r")
    #
    # Get the filename
    #
    line = INPUT.readline()
    segments=line.split(':',3)
    if len(segments) != 4 or not segments[2].lower().strip().endswith('source'):
        raise RuntimeError('Fatal error parsing gcov file, line 1: \n\t"%s"' % line.rstrip())
    currdir = os.getcwd()
    os.chdir(starting_dir)
    fname = aliases.unalias_path(os.path.abspath((segments[-1]).strip()))
    os.chdir(currdir)
    if options.verbose:
        sys.stdout.write("Parsing coverage data for file %s\n" % fname)
    #
    # Return if the filename does not match the filter
    #
    if not options.filter.match(fname):
        if options.verbose:
            sys.stdout.write("  Filtering coverage data for file %s\n" % fname)
        return
    #
    # Return if the filename matches the exclude pattern
    #
    for i in range(0,len(options.exclude)):
        if options.exclude[i].match(options.filter.sub('',fname)) or \
               options.exclude[i].match(fname) or \
               options.exclude[i].match(os.path.abspath(fname)):
            if options.verbose:
                sys.stdout.write("  Excluding coverage data for file %s\n" % fname)
            return
    #
    # Parse each line, and record the lines
    # that are uncovered
    #
    noncode = set()
    uncovered = set()
    uncovered_exceptional = set()
    covered = {}
    branches = {}
    #first_record=True
    lineno = 0
    for line in INPUT:
        segments=line.split(":",2)
        #print "HERE", segments
        tmp = segments[0].strip()
        if len(segments) > 1:
            try:
                lineno = int(segments[1].strip())
            except:
                pass # keep previous line number!
            
        if tmp[0] == '#':
            uncovered.add( lineno )
        elif tmp[0] == '=':
            uncovered_exceptional.add( lineno )
        elif tmp[0] in "0123456789":
            covered[lineno] = int(segments[0].strip())
        elif tmp[0] == '-':
            # remember certain non-executed lines
            code = segments[2].strip()
            if len(code) == 0 or code == "{" or code == "}" or \
               code.startswith("//") or code == 'else':
                noncode.add( lineno )
        elif tmp.startswith('branch'):
            fields = line.split()
            try:
                count = int(fields[3])
                branches.setdefault(lineno, {})[int(fields[1])] = count
            except:
                # We ignore branches that were "never executed"
                pass
        elif tmp.startswith('call'):
            pass
        elif tmp.startswith('function'):
            pass
        elif tmp[0] == 'f':
            pass
            #if first_record:
                #first_record=False
                #uncovered.add(prev)
            #if prev in uncovered:
                #tokens=re.split('[ \t]+',tmp)
                #if tokens[3] != "0":
                    #uncovered.remove(prev)
            #prev = int(segments[1].strip())
            #first_record=True
        else:
            sys.stderr.write(
                "(WARNING) Unrecognized GCOV output: '%s'\n"
                "\tThis is indicitive of a gcov output parse error.\n"
                "\tPlease report this to the gcovr developers." % tmp )
    ##print 'uncovered',uncovered
    ##print 'covered',covered
    ##print 'branches',branches
    ##print 'noncode',noncode
    #
    # If the file is already in covdata, then we
    # remove lines that are covered here.  Otherwise,
    # initialize covdata
    #
    if not fname in covdata:
        covdata[fname] = CoverageData(fname,uncovered,uncovered_exceptional,covered,branches,noncode)
    else:
        covdata[fname].update(uncovered,uncovered_exceptional,covered,branches,noncode)
    INPUT.close()

#
# Process a datafile (generated by running the instrumented application)
# and run gcov with the corresponding arguments
#
# This is trickier than it sounds: The gcda/gcno files are stored in the
# same directory as the object files; however, gcov must be run from the
# same directory where gcc/g++ was run.  Normally, the user would know
# where gcc/g++ was invoked from and could tell gcov the path to the
# object (and gcda) files with the --object-directory command.
# Unfortunately, we do everything backwards: gcovr looks for the gcda
# files and then has to infer the original gcc working directory.
#
# In general, (but not always) we can assume that the gcda file is in a
# subdirectory of the original gcc working directory, so we will first
# try ".", and on error, move up the directory tree looking for the
# correct working directory (letting gcov's own error codes dictate when
# we hit the right directory).  This covers 90+% of the "normal" cases.
# The exception to this is if gcc was invoked with "-o ../[...]" (i.e.,
# the object directory was a peer (not a parent/child) of the cwd.  In
# this case, things are really tough.  We accept an argument
# (--object-directory) that SHOULD BE THE SAME as the one povided to
# gcc.  We will then walk that path (backwards) in the hopes of
# identifying the original gcc working directory (there is a bit of
# trial-and-error here)
#
def process_datafile(filename, covdata, options):
    #
    # Launch gcov
    #
    abs_filename = os.path.abspath(filename)
    (dirname,fname) = os.path.split(abs_filename)
    #(name,ext) = os.path.splitext(base)

    potential_wd = []
    errors=[]
    Done = False

    if options.objdir:
        src_components = abs_filename.split(os.sep)
        components = normpath(options.objdir).split(os.sep)
        idx = 1
        while idx <= len(components):
            if idx > len(src_components):
                break
            if components[-1*idx] != src_components[-1*idx]:
                break
            idx += 1
        if idx > len(components):
            pass # a parent dir; the normal process will find it
        elif components[-1*idx] == '..':
            dirs = [ os.path.join(src_components[:len(src_components)-idx+1]) ]
            while idx <= len(components) and components[-1*idx] == '..':
                tmp = []
                for d in dirs:
                    for f in os.listdir(d):
                        x = os.path.join(d,f)
                        if os.path.isdir(x):
                            tmp.append(x)
                dirs = tmp
                idx += 1
            potential_wd = dirs
        else:
            if components[0] == '':
                # absolute path
                tmp = [ options.objdir ]
            else:
                # relative path: check relative to both the cwd and the
                # gcda file
                tmp = [ os.path.join(x, options.objdir) for x in
                        [os.path.dirname(abs_filename), os.getcwd()] ]
            potential_wd = [ testdir for testdir in tmp
                             if os.path.isdir(testdir) ]
            if len(potential_wd) == 0:
                errors.append("ERROR: cannot identify the location where GCC "
                              "was run using --object-directory=%s\n" %
                              options.objdir)
            # Revert to the normal 
            #sys.exit(1)

    # no objdir was specified (or it was a parent dir); walk up the dir tree
    if len(potential_wd) == 0:
        wd = os.path.split(abs_filename)[0]
        while True:
            potential_wd.append(wd)
            wd = os.path.split(wd)[0]
            if wd == potential_wd[-1]:
                break

    cmd = [ gcov_cmd, abs_filename,
            "--branch-counts", "--branch-probabilities", "--preserve-paths", 
            '--object-directory', dirname ]

    # NB: We are lazy English speakers, so we will only parse English output
    env = dict(os.environ)
    env['LC_ALL'] = 'en_US'
    

    while len(potential_wd) > 0 and not Done:
        # NB: either len(potential_wd) == 1, or all entires are absolute
        # paths, so we don't have to chdir(starting_dir) at every
        # iteration.
        os.chdir(potential_wd.pop(0)) 
        
        
        #if options.objdir:
        #    cmd.extend(["--object-directory", Template(options.objdir).substitute(filename=filename, head=dirname, tail=base, root=name, ext=ext)])

        if options.verbose:
            sys.stdout.write("Running gcov: '%s' in '%s'\n" % ( ' '.join(cmd), os.getcwd() ))
        (out, err) = subprocess.Popen( cmd, env=env,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE ).communicate()
        out=out.decode('utf-8')
        err=err.decode('utf-8')

        # find the files that gcov created
        gcov_files = {'active':[], 'filter':[], 'exclude':[]}
        for line in out.splitlines():
            found = output_re.search(line.strip())
            if found is not None:
                fname = found.group(1)
                if not options.gcov_filter.match(fname):
                    if options.verbose:
                        sys.stdout.write("Filtering gcov file %s\n" % fname)
                    gcov_files['filter'].append(fname)
                    continue
                exclude=False
                for i in range(0,len(options.gcov_exclude)):
                    if options.gcov_exclude[i].match(options.gcov_filter.sub('',fname)) or \
                           options.gcov_exclude[i].match(fname) or \
                           options.gcov_exclude[i].match(os.path.abspath(fname)):
                        exclude=True
                        break
                if not exclude:
                    gcov_files['active'].append(fname)
                elif options.verbose:
                    sys.stdout.write("Excluding gcov file %s\n" % fname)
                    gcov_files['exclude'].append(fname)

        if source_re.search(err):
            # gcov tossed errors: try the next potential_wd
            errors.append(err)
        else:
            # Process *.gcov files
            for fname in gcov_files['active']:
                process_gcov_data(fname, covdata, options)
            Done = True

        if not options.keep:
            for group in gcov_files.values():
                for fname in group:
                    if os.path.exists(fname):
                        # Only remove files that actually exist.
                        os.remove(fname)

    os.chdir(starting_dir)
    if options.delete:
        if not abs_filename.endswith('gcno'):
            os.remove(abs_filename)
        
    if not Done:
        sys.stderr.write(
            "(WARNING) GCOV produced the following errors processing %s:\n"
            "\t   %s" 
            "\t(gcovr could not infer a working directory that resolved it.)\n"
            % ( filename, "\t   ".join(errors) ) )

#
# Produce the classic gcovr text report
#
def print_text_report(covdata):
    def _num_uncovered(key):
        (total, covered, percent) = covdata[key].coverage()
        return total - covered
    def _percent_uncovered(key):
        (total, covered, percent) = covdata[key].coverage()
        if covered:
            return -1.0*covered/total
        else:
            return total or 1e6
    def _alpha(key):
        return key

    if options.output:
        OUTPUT = open(options.output,'w')
    else:
        OUTPUT = sys.stdout
    total_lines=0
    total_covered=0
    # Header
    OUTPUT.write("-"*78 + '\n')
    a = options.show_branch and "Branches" or "Lines"
    b = options.show_branch and "Taken" or "Exec"
    c = "Missing"
    OUTPUT.write("File".ljust(40) + a.rjust(8) + b.rjust(8)+ "  Cover   " + c + "\n") 
    OUTPUT.write("-"*78 + '\n')

    # Data
    keys = list(covdata.keys())
    keys.sort(key=options.sort_uncovered and _num_uncovered or \
              options.sort_percent and _percent_uncovered or _alpha)
    for key in keys:
        (t, n, txt) = covdata[key].summary()
        total_lines += t
        total_covered += n
        OUTPUT.write(txt + '\n')

    # Footer & summary
    OUTPUT.write("-"*78 + '\n')
    percent = total_lines and str(int(100.0*total_covered/total_lines)) or "--"
    OUTPUT.write("TOTAL".ljust(40) + str(total_lines).rjust(8) + \
          str(total_covered).rjust(8) + str(percent).rjust(6)+"%" + '\n')
    OUTPUT.write("-"*78 + '\n')

    # Close logfile
    if options.output:
        OUTPUT.close()

#
# Produce an XML report in the Cobertura format
#
def print_xml_report(covdata):
    branchTotal = 0
    branchCovered = 0
    lineTotal = 0
    lineCovered = 0

    options.show_branch = True
    for key in covdata.keys():
        (total, covered, percent) = covdata[key].coverage()
        branchTotal += total
        branchCovered += covered

    options.show_branch = False
    for key in covdata.keys():
        (total, covered, percent) = covdata[key].coverage()
        lineTotal += total
        lineCovered += covered
    
    impl = xml.dom.minidom.getDOMImplementation()
    docType = impl.createDocumentType(
        "coverage", None,
        "http://cobertura.sourceforge.net/xml/coverage-03.dtd" )
    doc = impl.createDocument(None, "coverage", docType)
    root = doc.documentElement
    root.setAttribute( "line-rate", lineTotal == 0 and '0.0' or
                       str(float(lineCovered) / lineTotal) )
    root.setAttribute( "branch-rate", branchTotal == 0 and '0.0' or
                       str(float(branchCovered) / branchTotal) )
    root.setAttribute( "timestamp", str(int(time.time())) )
    root.setAttribute( "version", "gcovr %s" % (version_str(),) )

    # Generate the <sources> element: this is either the root directory
    # (specified by --root), or the CWD.
    sources = doc.createElement("sources")
    root.appendChild(sources)

    # Generate the coverage output (on a per-package basis)
    packageXml = doc.createElement("packages")
    root.appendChild(packageXml)
    packages = {}
    source_dirs = set()

    keys = list(covdata.keys())
    keys.sort()
    for f in keys:
        data = covdata[f]
        dir = options.filter.sub('',f)
        if f.endswith(dir):
            src_path = f[:-1*len(dir)]
            if len(src_path) > 0:
                while dir.startswith(os.path.sep):
                    src_path += os.path.sep
                    dir = dir[len(os.path.sep):]
                source_dirs.add(src_path)
        else:
            # Do no truncation if the filter does not start matching at
            # the beginning of the string
            dir = f
        (dir, fname) = os.path.split(dir)
        
        package = packages.setdefault(
            dir, [ doc.createElement("package"), {},
                   0, 0, 0, 0 ] )
        c = doc.createElement("class")
        lines = doc.createElement("lines")
        c.appendChild(lines)

        class_lines = 0
        class_hits = 0
        class_branches = 0
        class_branch_hits = 0
        for line in data.all_lines:
            hits = data.covered.get(line, 0)
            class_lines += 1
            if hits > 0:
                class_hits += 1
            l = doc.createElement("line")
            l.setAttribute("number", str(line))
            l.setAttribute("hits", str(hits))
            branches = data.branches.get(line)
            if branches is None:
                l.setAttribute("branch", "false")
            else:
                b_hits = 0
                for v in branches.values():
                    if v > 0:
                        b_hits += 1
                coverage = 100*b_hits/len(branches)
                l.setAttribute("branch", "true")
                l.setAttribute( "condition-coverage",
                                "%i%% (%i/%i)" %
                                (coverage, b_hits, len(branches)) )
                cond = doc.createElement('condition')
                cond.setAttribute("number", "0")
                cond.setAttribute("type", "jump")
                cond.setAttribute("coverage", "%i%%" % ( coverage ) )
                class_branch_hits += b_hits
                class_branches += float(len(branches))
                conditions = doc.createElement("conditions")
                conditions.appendChild(cond)
                l.appendChild(conditions)
                
            lines.appendChild(l)

        className = fname.replace('.', '_')
        c.setAttribute("name", className)
        c.setAttribute("filename", os.path.join(dir, fname))
        c.setAttribute("line-rate", str(class_hits / (1.0*class_lines or 1.0)))
        c.setAttribute( "branch-rate",
                        str(class_branch_hits / (1.0*class_branches or 1.0)) )
        c.setAttribute("complexity", "0.0")

        package[1][className] = c
        package[2] += class_hits
        package[3] += class_lines
        package[4] += class_branch_hits
        package[5] += class_branches

    for packageName, packageData in packages.items():
        package = packageData[0];
        packageXml.appendChild(package)
        classes = doc.createElement("classes")
        package.appendChild(classes)
        classNames = list(packageData[1].keys())
        classNames.sort()
        for className in classNames:
            classes.appendChild(packageData[1][className])
        package.setAttribute("name", packageName.replace(os.sep, '.'))
        package.setAttribute("line-rate", str(packageData[2]/(1.0*packageData[3] or 1.0)))
        package.setAttribute( "branch-rate", str(packageData[4] / (1.0*packageData[5] or 1.0) ))
        package.setAttribute("complexity", "0.0")


    # Populate the <sources> element: this is either the root directory
    # (specified by --root), or relative directories based
    # on the filter, or the CWD
    if options.root is not None:
        source = doc.createElement("source")
        source.appendChild(doc.createTextNode(options.root.strip()))
        sources.appendChild(source)
    elif len(source_dirs) > 0:
        cwd = os.getcwd()
        for d in source_dirs:
            source = doc.createElement("source")
            if d.startswith(cwd):
                reldir = d[len(cwd):].lstrip(os.path.sep)
            elif cwd.startswith(d):
                i = 1
                while normpath(d) != normpath(os.path.join(*tuple([cwd]+['..']*i))):
                    i += 1
                reldir = os.path.join(*tuple(['..']*i))
            else:
                reldir = d
            source.appendChild(doc.createTextNode(reldir.strip()))
            sources.appendChild(source)
    else:
        source = doc.createElement("source")
        source.appendChild(doc.createTextNode('.'))
        sources.appendChild(source)

    if options.prettyxml:
        import textwrap
        lines = doc.toprettyxml(" ").split('\n')
        for i in xrange(len(lines)):
            n=0
            while n < len(lines[i]) and lines[i][n] == " ":
                n += 1
            lines[i] = "\n".join(textwrap.wrap(lines[i], 78, break_long_words=False, break_on_hyphens=False, subsequent_indent=" "+ n*" "))
        xmlString = "\n".join(lines)
        #print textwrap.wrap(doc.toprettyxml(" "), 80)
    else:
        xmlString = doc.toprettyxml(indent="")
    if options.output is None:
        sys.stdout.write(xmlString+'\n')
    else:
        OUTPUT = open(options.output, 'w')
        OUTPUT.write(xmlString +'\n')
        OUTPUT.close()


##
## MAIN
##

#
# Create option parser
#
parser = OptionParser()
parser.add_option("--version",
        help="Print the version number, then exit",
        action="store_true",
        dest="version",
        default=False)
parser.add_option("-v","--verbose",
        help="Print progress messages",
        action="store_true",
        dest="verbose",
        default=False)
parser.add_option('--object-directory',
        help="Specify the directory that contains the gcov data files.  gcovr must be able to identify the path between the *.gcda files and the directory where gcc was originally run.  Normally, gcovr can guess correctly.  This option overrides gcovr's normal path detection and can specify either the path from gcc to the gcda file (i.e. what was passed to gcc's '-o' option), or the path from the gcda file to gcc's original working directory.",
        action="store",
        dest="objdir",
        default=None)
parser.add_option("-o","--output",
        help="Print output to this filename",
        action="store",
        dest="output",
        default=None)
parser.add_option("-k","--keep",
        help="Keep the temporary *.gcov files generated by gcov.  By default, these are deleted.",
        action="store_true",
        dest="keep",
        default=False)
parser.add_option("-d","--delete",
        help="Delete the coverage files after they are processed.  These are generated by the users's program, and by default gcovr does not remove these files.",
        action="store_true",
        dest="delete",
        default=False)
parser.add_option("-f","--filter",
        help="Keep only the data files that match this regular expression",
        action="store",
        dest="filter",
        default=None)
parser.add_option("-e","--exclude",
        help="Exclude data files that match this regular expression",
        action="append",
        dest="exclude",
        default=[])
parser.add_option("--gcov-filter",
        help="Keep only gcov data files that match this regular expression",
        action="store",
        dest="gcov_filter",
        default=None)
parser.add_option("--gcov-exclude",
        help="Exclude gcov data files that match this regular expression",
        action="append",
        dest="gcov_exclude",
        default=[])
parser.add_option("-r","--root",
        help="Defines the root directory.  This is used to filter the files, and to standardize the output.",
        action="store",
        dest="root",
        default=None)
parser.add_option("-x","--xml",
        help="Generate XML instead of the normal tabular output.",
        action="store_true",
        dest="xml",
        default=False)
parser.add_option("--xml-pretty",
        help="Generate pretty XML instead of the normal dense format.",
        action="store_true",
        dest="prettyxml",
        default=False)
parser.add_option("-b","--branches",
        help="Tabulate the branch coverage instead of the line coverage.",
        action="store_true",
        dest="show_branch",
        default=None)
parser.add_option("-u","--sort-uncovered",
        help="Sort entries by increasing number of uncovered lines.",
        action="store_true",
        dest="sort_uncovered",
        default=None)
parser.add_option("-p","--sort-percentage",
        help="Sort entries by decreasing percentage of covered lines.",
        action="store_true",
        dest="sort_percent",
        default=None)
parser.usage="gcovr [options]"
parser.description="A utility to run gcov and generate a simple report that summarizes the coverage"
#
# Process options
#
(options, args) = parser.parse_args(args=sys.argv)
if options.version:
    sys.stdout.write(
        "gcovr %s\n"
        "\n"
        "Copyright (2008) Sandia Corporation. Under the terms of Contract\n"
        "DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government\n"
        "retains certain rights in this software.\n"
        % (version_str(),) )
    sys.exit(0)
if options.objdir:
    tmp = options.objdir.replace('/',os.sep).replace('\\',os.sep)
    while os.sep+os.sep in tmp:
        tmp = tmp.replace(os.sep+os.sep, os.sep)
    if normpath(options.objdir) != tmp:
        sys.stderr.write(
            "(WARNING) relative referencing in --object-directory.\n"
            "\tthis could cause strange errors when gcovr attempts to\n"
            "\tidentify the original gcc working directory.\n")
#
# Setup filters
#
for i in range(0,len(options.exclude)):
    options.exclude[i] = re.compile(options.exclude[i])
if options.filter is not None:
    options.filter = re.compile(options.filter)
elif options.root is not None:
    if not options.root:
        sys.stderr.write(
            "(ERROR) empty --root option.\n"
            "\tRoot specifies the path to the root directory of your project.\n"
            "\tThis option cannot be an empty string.\n")
        sys.exit(1)
    options.filter = re.compile(re.escape(os.path.abspath(options.root)+os.sep))
if options.filter is None:
    options.filter = re.compile('')
#
for i in range(0,len(options.gcov_exclude)):
    options.gcov_exclude[i] = re.compile(options.gcov_exclude[i])
if options.gcov_filter is not None:
    options.gcov_filter = re.compile(options.gcov_filter)
else:
    options.gcov_filter = re.compile('')
#
# Get data files
#
if len(args) == 1:
    datafiles = get_datafiles(["."], options)
else:
    datafiles = get_datafiles(args[1:], options)
#
# Get coverage data
#
covdata = {}
for file in datafiles:
    process_datafile(file,covdata,options)
if options.verbose:
    sys.stdout.write("Gathered coveraged data for "+str(len(covdata))+" files\n")
#
# Print report
#
if options.xml or options.prettyxml:
    print_xml_report(covdata)
else:
    print_text_report(covdata)
