github.com/sercand/please@v13.4.0+incompatible/src/test/gcov_coverage.go (about) 1 // Code for parsing gcov coverage output. 2 3 package test 4 5 import ( 6 "bytes" 7 "fmt" 8 "strconv" 9 "strings" 10 11 "github.com/thought-machine/please/src/core" 12 ) 13 14 // gcovPlaceholder is used to mark empty coverage files for C++ tests when coverage is disabled for them. 15 var gcovPlaceholder = []byte{'g', 'c', 'o', 'v'} 16 17 func parseGcovCoverageResults(target *core.BuildTarget, coverage *core.TestCoverage, data []byte) error { 18 if bytes.Equal(data, gcovPlaceholder) { 19 return nil // Coverage is disabled, not an error. 20 } 21 // The data we have is a sequence of .gcov files smashed together. 22 lines := bytes.Split(data, []byte{'\n'}) 23 if len(lines) == 0 { 24 return fmt.Errorf("Empty coverage file") 25 } 26 currentFilename := "" 27 for lineno, line := range lines { 28 fields := bytes.Split(line, []byte{':'}) 29 if len(fields) < 3 { 30 continue 31 } 32 if bytes.Equal(fields[2], []byte("Source")) { 33 if len(fields) < 4 { 34 return fmt.Errorf("Bad source on line %d: %s", lineno, string(line)) 35 } 36 currentFilename = string(fields[3]) 37 continue 38 } 39 covLine, err := strconv.Atoi(strings.TrimSpace(string(fields[1]))) 40 if err != nil { 41 return fmt.Errorf("Bad line number on line %d: %s", lineno, string(line)) 42 } else if covLine > 0 { 43 coverage.Files[currentFilename] = append(coverage.Files[currentFilename], translateGcovCount(bytes.TrimSpace(fields[0]))) 44 } 45 } 46 return nil 47 } 48 49 // translateGcovCount coverts gcov's format to ours. 50 // AFAICT the format is: 51 // -: Not executable 52 // #####: Not covered 53 // 32: line was hit 32 times 54 func translateGcovCount(gcov []byte) core.LineCoverage { 55 if len(gcov) > 0 && gcov[0] == '-' { 56 return core.NotExecutable 57 } else if i, err := strconv.Atoi(string(gcov)); err == nil && i > 0 { 58 return core.Covered 59 } 60 return core.Uncovered 61 } 62 63 // looksLikeGcovCoverageResults returns true if the given data appears to be gcov results. 64 func looksLikeGcovCoverageResults(data []byte) bool { 65 return bytes.HasPrefix(data, []byte(" -: 0:Source:")) || bytes.Equal(data, gcovPlaceholder) 66 }