Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kcov for openSUSE:Factory checked in 
at 2023-04-30 16:08:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kcov (Old)
 and      /work/SRC/openSUSE:Factory/.kcov.new.1533 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kcov"

Sun Apr 30 16:08:04 2023 rev:6 rq:1083736 version:41

Changes:
--------
--- /work/SRC/openSUSE:Factory/kcov/kcov.changes        2022-09-30 
17:58:46.865375158 +0200
+++ /work/SRC/openSUSE:Factory/.kcov.new.1533/kcov.changes      2023-04-30 
16:08:16.092332797 +0200
@@ -1,0 +2,16 @@
+Mon Apr 24 12:39:15 UTC 2023 - Antoine Belvire <[email protected]>
+
+- Update to 41:
+  * Output the codecov file format.
+  * Fix handling of symlinks.
+  * Add support for RISC-V.
+  * Fix gcc-13 build.
+  * Correct the license for Debian.
+  * Add --cobertura-only output option.
+  * Fix build with binutils >= 2.39.
+  * Clear BFD state between files to avoid breakpoint trashing atomic
+    instructions.
+- Remove kcov-40-binutils-2.39.patch: Fixed upstream.
+- Add -lsframe, -lzstd to build flags: Fix linking.
+
+-------------------------------------------------------------------

Old:
----
  kcov-40-binutils-2.39.patch
  v40.tar.gz

New:
----
  v41.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kcov.spec ++++++
--- /var/tmp/diff_new_pack.4VZLWv/_old  2023-04-30 16:08:16.476335140 +0200
+++ /var/tmp/diff_new_pack.4VZLWv/_new  2023-04-30 16:08:16.480335164 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package kcov
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           kcov
-Version:        40
+Version:        41
 Release:        0
 Summary:        Code coverage tool without special compilation options
 License:        GPL-2.0-only
@@ -25,8 +25,6 @@
 URL:            https://github.com/SimonKagstrom/kcov
 Source0:        
https://github.com/SimonKagstrom/kcov/archive/v%{version}.tar.gz
 Patch0:         link_order.patch
-# PATCH-FIX-UPSTREAM kcov-40-binutils-2.39.patch -- Fix build with binutils 
2.39 (gh#SimonKagstrom#381, gh#SimonKagstrom!383)
-Patch1:         kcov-40-binutils-2.39.patch
 BuildRequires:  binutils-devel
 BuildRequires:  c++_compiler
 BuildRequires:  cmake
@@ -50,6 +48,9 @@
 rm -frv external/
 
 %build
+%if 0%{?suse_version} > 1500
+export CFLAGS="%{optflags} -lsframe -lzstd"
+%endif
 %cmake
 %cmake_build
 

++++++ v40.tar.gz -> v41.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/.github/workflows/ci.yml 
new/kcov-41/.github/workflows/ci.yml
--- old/kcov-40/.github/workflows/ci.yml        2021-12-18 09:25:42.000000000 
+0100
+++ new/kcov-41/.github/workflows/ci.yml        2023-02-23 13:55:55.000000000 
+0100
@@ -61,13 +61,13 @@
           sudo .github/workflows/ci-run-tests.sh
 
   build-freebsd:
-    runs-on: macos-10.15
+    runs-on: macos-12
     name: Build and test FreeBSD executable
     steps:
     - uses: actions/checkout@v2
     - name: FreeBSD
       id: test
-      uses: vmactions/[email protected]
+      uses: vmactions/freebsd-vm@v0
       with:
         usesh: true
         sync: rsync
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/.github/workflows/generic-build.sh 
new/kcov-41/.github/workflows/generic-build.sh
--- old/kcov-40/.github/workflows/generic-build.sh      2021-12-18 
09:25:42.000000000 +0100
+++ new/kcov-41/.github/workflows/generic-build.sh      2023-02-23 
13:55:55.000000000 +0100
@@ -18,7 +18,7 @@
   apt-get update
   apt-mark hold php* google* libobjc* libpq* libidn* postgresql* 
python3-httplib2 samba* >/dev/null
   apt-get upgrade -y
-  apt-get install -y binutils-dev libcurl4-openssl-dev libdw-dev libiberty-dev 
gcc g++ make cmake libssl-dev git python python3 $EXTRA_PACKAGES
+  apt-get install -y binutils-dev libcurl4-openssl-dev libdw-dev libiberty-dev 
gcc g++ make cmake libssl-dev git python3 $EXTRA_PACKAGES
   export PATH="${PATH}:${HOME}/kcov/bin"
   mkdir build build-tests
   cd build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/ChangeLog new/kcov-41/ChangeLog
--- old/kcov-40/ChangeLog       2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/ChangeLog       2023-02-23 13:55:55.000000000 +0100
@@ -1,4 +1,21 @@
+Kcov (41):
+       * Add support for RISC-V (rvalue)
+
+       * Fix gcc-13 build (Sergei Trofimovich)
+
+       * Correct the license for Debian (Rui Chen)
+
+       * Add --cobertura-only output option
+
+       * Fix build with binutils >= 2.39 (oreo639)
+
+       * Clear BFD state between files to avoid breakpoint trashing atomic
+          instructions (Andy Caldwell)
+
+    -- Simon Kagstrom <[email protected]>, Thu Feb 23 13:52:46 CET 2023
+
 Kcov (40):
+
        * Make libbfd non-required to avoid GPLv3
 
     -- Simon Kagstrom <[email protected]>, Sat Dec 18 09:25:21 CET 2021
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/INSTALL.md new/kcov-41/INSTALL.md
--- old/kcov-40/INSTALL.md      2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/INSTALL.md      2023-02-23 13:55:55.000000000 +0100
@@ -14,8 +14,11 @@
 
 Ubuntu
 ------
-Install binutils-dev libcurl4-openssl-dev zlib1g-dev libdw-dev libiberty-dev
+Install
 
+```
+  apt-get install binutils-dev libssl-dev libcurl4-openssl-dev zlib1g-dev 
libdw-dev libiberty-dev
+```
 
 Fedora / Centos / RHEL
 ----------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/README.md new/kcov-41/README.md
--- old/kcov-40/README.md       2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/README.md       2023-02-23 13:55:55.000000000 +0100
@@ -101,4 +101,4 @@
 More information
 ----------------
 kcov is written by Simon Kagstrom <[email protected]> and more
-information can be found at [the web 
page](http://simonkagstrom.github.com/kcov/index.html)
+information can be found at [the web 
page](http://simonkagstrom.github.io/kcov/index.html)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/debian/copyright new/kcov-41/debian/copyright
--- old/kcov-40/debian/copyright        2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/debian/copyright        2023-02-23 13:55:55.000000000 +0100
@@ -5,16 +5,16 @@
 Files: *
 Copyright: <years> <put author's name and email here>
            <years> <likewise for another author>
-License: GPL-3.0+
+License: GPL-2.0+
 
 Files: debian/*
 Copyright: 2018 Paul Dreik <[email protected]>
-License: GPL-3.0+
+License: GPL-2.0+
 
-License: GPL-3.0+
+License: GPL-2.0+
  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 3 of the License, or
+ the Free Software Foundation, either version 2 of the License, or
  (at your option) any later version.
  .
  This package is distributed in the hope that it will be useful,
@@ -26,7 +26,7 @@
  along with this program. If not, see <https://www.gnu.org/licenses/>.
  .
  On Debian systems, the complete text of the GNU General
- Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
 
 # Please also look if there are files or directories which have a
 # different copyright/license attached and list them here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/doc/kcov.1 new/kcov-41/doc/kcov.1
--- old/kcov-40/doc/kcov.1      2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/doc/kcov.1      2023-02-23 13:55:55.000000000 +0100
@@ -88,6 +88,11 @@
 exit when the first process exits, i.e., honor the behavior of daemons. The 
default behavior
 is to return to the console when the last process exits.
 .TP
+\fB\-\-cobertura\-only
+Generate only cobertura output, as cov.xml, in the output directory. The 
intended usage is for e.g.,
+vscode coverage gutters, where the output directory can then be pointed to 
somewhere in the project
+directory to get coverage with little droppings.
+.TP
 \fB\-\-python\-parser\fP=\fIPARSER\fP
 Set the python parser to use for Python programs (the default is python). Can 
be used to
 run with Python 3 on systems where Python 2 is the default.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/CMakeLists.txt 
new/kcov-41/src/CMakeLists.txt
--- old/kcov-40/src/CMakeLists.txt      2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/CMakeLists.txt      2023-02-23 13:55:55.000000000 +0100
@@ -39,6 +39,8 @@
     message (FATAL_ERROR "Could NOT find M")
 endif (M_LIBRARY)
 
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
 set (KCOV kcov)
 
 
@@ -94,6 +96,7 @@
 )
 
 set (HAS_LIBBFD "0")
+set (HAS_LIBBFD_DISASM_STYLED "0")
 
 if (CMAKE_TARGET_ARCHITECTURES STREQUAL "i386" OR CMAKE_TARGET_ARCHITECTURES 
STREQUAL "x86_64")
        if (LIBBFD_FOUND)
@@ -106,6 +109,23 @@
                        ${LIBBFD_BFD_LIBRARY}
                        ${LIBBFD_IBERTY_LIBRARY}
                )
+               include(CheckCSourceCompiles)
+               set(CMAKE_REQUIRED_LIBRARIES ${DISASSEMBLER_LIBRARIES})
+               check_c_source_compiles("
+               #define PACKAGE
+               #define PACKAGE_VERSION
+               #include <stdio.h>
+               #include <dis-asm.h>
+
+               int main(int argc, char **argv){
+                       struct disassemble_info info;
+                       init_disassemble_info(&info, stdout, NULL, NULL);
+                       return 0;
+               }
+               " TEST_LIBBFD_DISASM_STYLED)
+               if (TEST_LIBBFD_DISASM_STYLED)
+                       set (HAS_LIBBFD_DISASM_STYLED "1")
+               endif (TEST_LIBBFD_DISASM_STYLED)
        endif (LIBBFD_FOUND)
 endif (CMAKE_TARGET_ARCHITECTURES STREQUAL "i386" OR 
CMAKE_TARGET_ARCHITECTURES STREQUAL "x86_64")
 
@@ -221,6 +241,7 @@
     source-file-cache.cc
     utils.cc
     writers/cobertura-writer.cc
+    writers/codecov-writer.cc
     writers/json-writer.cc
     ${coveralls_SRCS}
     writers/html-writer.cc
@@ -283,7 +304,7 @@
 
 set (KCOV_LIBRARY_PREFIX "/tmp")
 
-set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g -Wall 
-D_GLIBCXX_USE_NANOSLEEP -DKCOV_LIBRARY_PREFIX=${KCOV_LIBRARY_PREFIX} 
-DKCOV_HAS_LIBBFD=${HAS_LIBBFD}")
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g -Wall 
-D_GLIBCXX_USE_NANOSLEEP -DKCOV_LIBRARY_PREFIX=${KCOV_LIBRARY_PREFIX} 
-DKCOV_HAS_LIBBFD=${HAS_LIBBFD} 
-DKCOV_LIBFD_DISASM_STYLED=${HAS_LIBBFD_DISASM_STYLED}")
 
 include_directories(
        include/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/configuration.cc 
new/kcov-41/src/configuration.cc
--- old/kcov-40/src/configuration.cc    2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/configuration.cc    2023-02-23 13:55:55.000000000 +0100
@@ -127,6 +127,7 @@
                { "clang", no_argument, 0, 'c' },
                { "configure", required_argument, 0, 'M' },
                { "clean", no_argument, 0, 'E' },
+               { "cobertura-only", no_argument, 0, 'o' },
                { "exclude-pattern", required_argument, 0, 'x' },
                { "include-pattern", required_argument, 0, 'i' },
                { "exclude-path", required_argument, 0, 'X' },
@@ -177,7 +178,7 @@
                 */
                for (lastArg = 1; lastArg < argc; lastArg++)
                {
-                       if 
(IParserManager::getInstance().matchParser(argv[lastArg]))
+                       if 
(IParserManager::getInstance().matchParser(get_real_path(argv[lastArg])))
                                break;
 
                        bool found = false;
@@ -288,6 +289,9 @@
 
                                setKey("output-interval", 
stoul(std::string(optarg)));
                                break;
+                       case 'o':
+                               setKey("cobertura-only", 1);
+                               break;
                        case 'S':
                        {
                                if (!isInteger(std::string(optarg)))
@@ -526,10 +530,17 @@
                        setKey("binary-path", tmp.first);
                        binaryName = tmp.second;
 
-                       setKey("target-directory",
-                                       fmt("%s/%s.%08zx", 
outDirectory.c_str(), binaryName.c_str(),
-                                                       
(size_t)hash_file(path)));
-
+                       if (!keyAsInt("cobertura-only"))
+                       {
+                               setKey("target-directory",
+                                               fmt("%s/%s.%08zx", 
outDirectory.c_str(), binaryName.c_str(),
+                                                               
(size_t)hash_file(path)));
+                       }
+                       else
+                       {
+                               // No directory structure if only cobertura is 
used
+                               setKey("target-directory", outDirectory);
+                       }
                        if (keyAsInt("running-mode") == 
IConfiguration::MODE_REPORT_ONLY &&
                                !file_exists(keyAsString("target-directory")))
                        {
@@ -626,6 +637,8 @@
                setKey("patchelf-command", "patchelf");
                setKey("coveralls-service-name", "travis-ci");
                setKey("cobertura-full-paths", 0);
+               setKey("codecov-full-paths", 0);
+               setKey("cobertura-only", 0);
        }
 
        void setKey(const std::string &key, const std::string &val)
@@ -664,7 +677,8 @@
        {
                if (key == "low-limit" || key == "high-limit"
                                || key == "bash-use-basic-parser"
-                               || key == "cobertura-full-paths")
+                               || key == "cobertura-full-paths"
+                               || key == "codecov-full-paths")
                {
                        if (!isInteger(value))
                                panic("Value for %s must be integer\n", 
key.c_str());
@@ -692,6 +706,8 @@
                        setKey(key, std::string(value));
                else if (key == "cobertura-full-paths")
                        setKey(key, stoul(std::string(value)));
+               else if (key == "codecov-full-paths")
+                       setKey(key, stoul(std::string(value)));
                else
                        panic("Unknown key %s\n", key.c_str());
        }
@@ -717,6 +733,7 @@
                                                "                         found 
after the :\n"
                                                " --path-strip-level=num  path 
levels to show for common paths (default: %d)\n"
                                                "\n"
+                                               " --cobertura-only        Only 
produce cobertura output in the output dir\n"
                                                " --gcov                  use 
gcov parser instead of DWARF debugging info\n"
                                                " --clang                 use 
Clang Sanitizer-coverage parser\n"
                                                " --system-record         
perform full-system instrumentation\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/engines/ptrace.cc 
new/kcov-41/src/engines/ptrace.cc
--- old/kcov-40/src/engines/ptrace.cc   2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/engines/ptrace.cc   2023-02-23 13:55:55.000000000 +0100
@@ -50,6 +50,8 @@
        unsigned long shift = 8 * offs;
 
        val = (old_data & ~(0xffffffffUL << shift)) | (0xd4200000UL << shift);
+#elif defined(__riscv)
+       val = 0x00100073; /* ebreak */ // No width problem, prefer ebreak than 
c.ebreak for ISA w/o C extension.
 #else
 # error Unsupported architecture
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/engines/ptrace_linux.cc 
new/kcov-41/src/engines/ptrace_linux.cc
--- old/kcov-40/src/engines/ptrace_linux.cc     2021-12-18 09:25:42.000000000 
+0100
+++ new/kcov-41/src/engines/ptrace_linux.cc     2023-02-23 13:55:55.000000000 
+0100
@@ -20,6 +20,7 @@
 enum
 {
        i386_EIP = 12, x86_64_RIP = 16, ppc_NIP = 32, arm_PC = 15, aarch64_PC = 
32, // See Linux arch/arm64/include/asm/ptrace.h
+       riscv_EPC = 0
 };
 
 static void arch_adjustPcAfterBreakpoint(unsigned long *regs);
@@ -40,7 +41,7 @@
        regs[i386_EIP]--;
 #elif defined(__x86_64__)
        regs[x86_64_RIP]--;
-#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
+#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) || 
defined(__riscv)
        // Do nothing
 #else
 # error Unsupported architecture
@@ -61,6 +62,8 @@
        out = regs[aarch64_PC];
 #elif defined(__powerpc__)
        out = regs[ppc_NIP];
+#elif defined(__riscv)
+       out = regs[riscv_EPC];
 #else
 # error Unsupported architecture
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/include/collector.hh 
new/kcov-41/src/include/collector.hh
--- old/kcov-40/src/include/collector.hh        2021-12-18 09:25:42.000000000 
+0100
+++ new/kcov-41/src/include/collector.hh        2023-02-23 13:55:55.000000000 
+0100
@@ -2,6 +2,8 @@
 
 #include <string>
 
+#include <stdint.h>
+
 namespace kcov
 {
        class IFileParser;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/include/reporter.hh 
new/kcov-41/src/include/reporter.hh
--- old/kcov-40/src/include/reporter.hh 2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/include/reporter.hh 2023-02-23 13:55:55.000000000 +0100
@@ -3,6 +3,7 @@
 #include <string>
 
 #include <stddef.h>
+#include <stdint.h>
 
 namespace kcov
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/include/source-file-cache.hh 
new/kcov-41/src/include/source-file-cache.hh
--- old/kcov-40/src/include/source-file-cache.hh        2021-12-18 
09:25:42.000000000 +0100
+++ new/kcov-41/src/include/source-file-cache.hh        2023-02-23 
13:55:55.000000000 +0100
@@ -3,6 +3,8 @@
 #include <vector>
 #include <string>
 
+#include <stdint.h>
+
 namespace kcov
 {
        /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/main.cc new/kcov-41/src/main.cc
--- old/kcov-40/src/main.cc     2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/main.cc     2023-02-23 13:55:55.000000000 +0100
@@ -20,6 +20,7 @@
 
 #include "merge-parser.hh"
 #include "engines/system-mode-file-format.hh"
+#include "writers/codecov-writer.hh"
 #include "writers/html-writer.hh"
 #include "writers/json-writer.hh"
 #include "writers/coveralls-writer.hh"
@@ -189,6 +190,8 @@
                        mergeReporter, base + "kcov-merged/sonarqube.xml");
        IWriter &mergeCoverallsWriter = createCoverallsWriter(mergeParser,
                        mergeReporter);
+       IWriter &mergeCodecovWriter = createCodecovWriter(mergeParser, 
mergeReporter,
+                       base + "kcov-merged/codecov.json");
        (void) mkdir(fmt("%s/kcov-merged", base.c_str()).c_str(), 0755);
 
        output.registerWriter(mergeParser);
@@ -197,6 +200,7 @@
        output.registerWriter(mergeCoberturaWriter);
        output.registerWriter(mergeSonarqubeWriter);
        output.registerWriter(mergeCoverallsWriter);
+       output.registerWriter(mergeCodecovWriter);
 
        output.start();
        output.stop();
@@ -220,8 +224,9 @@
                return 1;
        }
 
-       if (parser->getParserType() == "bash" ||
-               parser->getParserType() == "python")
+       if ((parser->getParserType() == "bash" ||
+               parser->getParserType() == "python") &&
+               !conf.keyAsInt("cobertura-only"))
        {
                // Use the path as the hash for non-compiled languages
                conf.setKey("target-directory",
@@ -256,7 +261,10 @@
                        filter);
        IReporter &mergeReporter = IReporter::create(mergeParser, mergeParser,
                        basicFilter);
-       (void) mkdir(fmt("%s/kcov-merged", base.c_str()).c_str(), 0755);
+       if (!conf.keyAsInt("cobertura-only"))
+       {
+               (void) mkdir(fmt("%s/kcov-merged", base.c_str()).c_str(), 0755);
+       }
 
        // Register writers
        if (runningMode != IConfiguration::MODE_COLLECT_ONLY)
@@ -269,6 +277,8 @@
                                out);
                IWriter &sonarqubeWriter = createSonarqubeWriter(*parser, 
reporter,
                                out + "/sonarqube.xml");
+               IWriter &codecovWriter = createCodecovWriter(*parser, reporter,
+                               out + "/codecov.json");
 
                IWriter &mergeHtmlWriter = createHtmlWriter(mergeParser, 
mergeReporter,
                                base, base + "/kcov-merged", 
conf.keyAsString("merged-name"),
@@ -279,30 +289,45 @@
                                mergeReporter, base + "kcov-merged");
                IWriter &mergeSonarqubeWriter = 
createSonarqubeWriter(mergeParser,
                                mergeReporter, base + 
"kcov-merged/sonarqube.xml");
+               IWriter &mergeCodecovWriter = createCodecovWriter(mergeParser,
+                               mergeReporter, base + 
"kcov-merged/codecov.json");
 
-               // Multiple binaries? Register the merged mode stuff
-               if (countMetadata() > 0)
+               if (!conf.keyAsInt("cobertura-only"))
                {
-                       output.registerWriter(mergeHtmlWriter);
-                       output.registerWriter(mergeJsonWriter);
-                       output.registerWriter(mergeCoberturaWriter);
-                       output.registerWriter(mergeSonarqubeWriter);
-                       output.registerWriter(
-                                       createCoverallsWriter(mergeParser, 
mergeReporter));
+                       // Multiple binaries? Register the merged mode stuff
+                       if (countMetadata() > 0)
+                       {
+                               output.registerWriter(mergeHtmlWriter);
+                               output.registerWriter(mergeJsonWriter);
+                               output.registerWriter(mergeCoberturaWriter);
+                               output.registerWriter(mergeSonarqubeWriter);
+                               output.registerWriter(
+                                               
createCoverallsWriter(mergeParser, mergeReporter));
+                               output.registerWriter(mergeCodecovWriter);
+                       }
+                       else
+                       {
+                               
output.registerWriter(createCoverallsWriter(*parser, reporter));
+                       }
+
+                       output.registerWriter(coberturaWriter);
+                       output.registerWriter(htmlWriter);
+                       output.registerWriter(jsonWriter);
+                       output.registerWriter(sonarqubeWriter);
+                       output.registerWriter(codecovWriter);
                }
                else
                {
-                       output.registerWriter(createCoverallsWriter(*parser, 
reporter));
+                       // Nothing else, if only cobertura is requested
+                       output.registerWriter(coberturaWriter);
                }
-
-               output.registerWriter(htmlWriter);
-               output.registerWriter(jsonWriter);
-               output.registerWriter(coberturaWriter);
-               output.registerWriter(sonarqubeWriter);
        }
 
        reporter.registerListener(mergeParser);
-       output.registerWriter(mergeParser);
+       if (!conf.keyAsInt("cobertura-only"))
+       {
+               output.registerWriter(mergeParser);
+       }
 
        g_engine = engine;
        g_output = &output;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/output-handler.cc 
new/kcov-41/src/output-handler.cc
--- old/kcov-40/src/output-handler.cc   2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/output-handler.cc   2023-02-23 13:55:55.000000000 +0100
@@ -37,10 +37,13 @@
                        (void)mkdir(m_baseDirectory.c_str(), 0755);
                        (void)mkdir(m_outDirectory.c_str(), 0755);
 
-                       (void)unlink(readableName.c_str());
-                       if (symlink(m_outDirectory.c_str(), 
readableName.c_str()) < 0)
+                       if (!conf.keyAsInt("cobertura-only"))
                        {
-                               kcov_debug(INFO_MSG, "Can't symlink readable 
name\n");
+                               (void)unlink(readableName.c_str());
+                               if (symlink(m_outDirectory.c_str(), 
readableName.c_str()) < 0)
+                               {
+                                       kcov_debug(INFO_MSG, "Can't symlink 
readable name\n");
+                               }
                        }
 
                        if (collector)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/parsers/bfd-disassembler.cc 
new/kcov-41/src/parsers/bfd-disassembler.cc
--- old/kcov-40/src/parsers/bfd-disassembler.cc 2021-12-18 09:25:42.000000000 
+0100
+++ new/kcov-41/src/parsers/bfd-disassembler.cc 2023-02-23 13:55:55.000000000 
+0100
@@ -5,6 +5,7 @@
 #include <set>
 #include <map>
 #include <algorithm>
+#include <stdexcept>
 
 #ifndef ATTRIBUTE_FPTR_PRINTF_2
 # define ATTRIBUTE_FPTR_PRINTF_2
@@ -50,15 +51,11 @@
                "jpo",
                "js",
                "jz",
-               "jczx"
-               "jezx"
-
+               "jczx",
+               "jezx",
                "loop",
-
                "jmp",
-
                "call",
-
                "ret",
 };
 
@@ -75,7 +72,11 @@
        BfdDisassembler()
        {
                memset(&m_info, 0, sizeof(m_info));
+#if KCOV_LIBFD_DISASM_STYLED
+               init_disassemble_info(&m_info, (void *)this, 
BfdDisassembler::opcodesFprintFuncStatic, 
BfdDisassembler::opcodesFprintStyledFuncStatic);
+#else
                init_disassemble_info(&m_info, (void *)this, 
BfdDisassembler::opcodesFprintFuncStatic);
+#endif
                m_disassembler = print_insn_i386;
 
                m_info.arch = bfd_arch_i386;
@@ -86,6 +87,12 @@
 
        virtual void setup(const void *header, size_t headerSize)
        {
+               // New ELF file, clear any state from the previous instance
+               m_cache.clear();
+               m_instructions.clear();
+               m_orderedInstructions.clear();
+               m_bbs.clear();
+
                const uint8_t *data = (const uint8_t *)header;
 
                panic_if(headerSize <= EI_CLASS,
@@ -293,24 +300,35 @@
 
        Section *lookupSection(uint64_t address)
        {
+               // Iterator to the lowest-addressed section that starts at or 
above
+               // `address`
                SectionCache_t::iterator it = m_cache.lower_bound(address);
 
-               if (it == m_cache.end())
-                       return NULL;
+               // Rare case, the searched for address might be exactly the 
base address of
+               // this section
+               if (it != m_cache.end() && it->first == address) {
+                       return it->second;
+               }
+
+               // Go back one section (this might be too far, but we'll check 
later)
                --it;
 
-               // Above the last symbol
+               // If there was no previous section, the address isn't in a 
section (it's
+               // before the lowest section's baseAddress)
                if (it == m_cache.end())
                        return NULL;
 
+               // We've found the highest-starting section that's lower than 
the target
+               // address, check it actually contains the address
                Section *cur = it->second;
                uint64_t end = cur->getBase() + cur->getSize() - 1;
 
-               // Below nearest (possible?)
+               // Address is below the section's baseAddress (impossible from 
the above
+               // logic)
                if (address < cur->getBase())
-                       return NULL;
+                       throw std::logic_error("Section search invariant 
broken");
 
-               // Above section
+               // Address is above section's end
                if (address > end)
                        return NULL;
 
@@ -373,7 +391,6 @@
                }
        }
 
-
        Instruction *getInstruction(uint64_t address)
        {
                if (m_instructions.find(address) == m_instructions.end())
@@ -382,8 +399,6 @@
                return &m_instructions[address];
        }
 
-
-
        void opcodesFprintFunc(const char *str)
        {
                std::string stdStr(str);
@@ -407,6 +422,25 @@
                return out;
        }
 
+#if KCOV_LIBFD_DISASM_STYLED
+       static int opcodesFprintStyledFuncStatic(void *info, enum 
disassembler_style style, const char *fmt, ...)
+       {
+               (void)style;
+               BfdDisassembler *pThis = (BfdDisassembler *)info;
+               char str[64];
+               int out;
+
+               va_list args;
+               va_start (args, fmt);
+               out = vsnprintf( str, sizeof(str) - 1, fmt, args );
+               va_end (args);
+
+               pThis->opcodesFprintFunc(str);
+
+               return out;
+       }
+#endif
+
        typedef std::map<uint64_t, Section *> SectionCache_t;
        typedef std::unordered_map<uint64_t, Instruction> 
InstructionAddressMap_t;
        typedef std::map<uint64_t, Instruction *> InstructionOrderedMap_t;
@@ -414,7 +448,6 @@
        struct disassemble_info m_info;
        disassembler_ftype m_disassembler;
 
-
        std::vector<std::string> m_instructionVector;
 
        SectionCache_t m_cache;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/solib-parser/lib.c 
new/kcov-41/src/solib-parser/lib.c
--- old/kcov-40/src/solib-parser/lib.c  2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/src/solib-parser/lib.c  2023-02-23 13:55:55.000000000 +0100
@@ -95,6 +95,8 @@
                        ".long 0xfedeffe7\n" /* undefined insn */
 #elif defined(__aarch64__)
                        ".long 0xd4200000\n" /* From 
https://github.com/scottt/debugbreak */
+#elif defined(__riscv)
+                       "ebreak\n"
 #else
 # error Unsupported architecture
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/writers/cobertura-writer.cc 
new/kcov-41/src/writers/cobertura-writer.cc
--- old/kcov-40/src/writers/cobertura-writer.cc 2021-12-18 09:25:42.000000000 
+0100
+++ new/kcov-41/src/writers/cobertura-writer.cc 2023-02-23 13:55:55.000000000 
+0100
@@ -27,7 +27,11 @@
        CoberturaWriter(IFileParser &parser, IReporter &reporter, const 
std::string &outDir) :
                        WriterBase(parser, reporter), 
m_maxPossibleHits(parser.maxPossibleHits())
        {
-               m_outFiles.push_back(outDir + "/cobertura.xml");
+               if (!IConfiguration::getInstance().keyAsInt("cobertura-only"))
+               {
+                       // cobertura-only is used for vscode, normally
+                       m_outFiles.push_back(outDir + "/cobertura.xml");
+               }
                m_outFiles.push_back(outDir + "/cov.xml"); // For vscode 
coverage gutters
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/writers/codecov-writer.cc 
new/kcov-41/src/writers/codecov-writer.cc
--- old/kcov-40/src/writers/codecov-writer.cc   1970-01-01 01:00:00.000000000 
+0100
+++ new/kcov-41/src/writers/codecov-writer.cc   2023-02-23 13:55:55.000000000 
+0100
@@ -0,0 +1,200 @@
+namespace std
+{
+class type_info;
+}
+
+#include <reporter.hh>
+#include <file-parser.hh>
+#include <configuration.hh>
+#include <writer.hh>
+#include <utils.hh>
+
+#include <string>
+#include <list>
+#include <vector>
+#include <unordered_map>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include "writer-base.hh"
+
+namespace kcov
+{
+
+namespace
+{
+
+// Outputs a coverage file that conforms to the Codecov Custom Coverage Format
+// as described here: 
https://docs.codecov.com/docs/codecov-custom-coverage-format
+//
+// Noteably, while this file format can be consumed by Codecov, it is most
+// useful for interoperating with other services that expect this format, as
+// Codecov intentionally can consume multiple formats.
+class CodecovWriter : public WriterBase
+{
+public:
+       CodecovWriter(IFileParser &parser, IReporter &reporter, const 
std::string &outFile) :
+                       WriterBase(parser, reporter), m_outFile(outFile), 
m_maxPossibleHits(parser.maxPossibleHits())
+       {
+       }
+
+       void onStartup()
+       {
+       }
+
+       void onStop()
+       {
+       }
+
+       void write()
+       {
+               std::stringstream out;
+
+               setupCommonPaths();
+
+               for (FileMap_t::const_iterator it = m_files.begin(); it != 
m_files.end(); ++it)
+               {
+                       File *file = it->second;
+
+                       // Fixup file->m_codeLines etc
+                       sumOne(file);
+               }
+               out << getHeader();
+
+               bool first_time = true;
+               for (FileMap_t::const_iterator it = m_files.begin(); it != 
m_files.end(); ++it)
+               {
+                       if (!first_time) {
+                               out << ",\n";
+                       }
+                       File *file = it->second;
+                       out << writeOne(file);
+                       first_time = false;
+               }
+               out << "\n";
+
+               out << getFooter();
+
+               std::ofstream cur(m_outFile);
+               cur << out.str();
+       }
+
+private:
+       void sumOne(File *file)
+       {
+               unsigned int nExecutedLines = 0;
+               unsigned int nCodeLines = 0;
+
+               for (unsigned int n = 1; n < file->m_lastLineNr; n++)
+               {
+                       if (!m_reporter.lineIsCode(file->m_name, n))
+                               continue;
+
+                       IReporter::LineExecutionCount cnt = 
m_reporter.getLineExecutionCount(file->m_name, n);
+
+                       nExecutedLines += !!cnt.m_hits;
+                       nCodeLines++;
+
+                       // Update the execution count
+                       file->m_executedLines = nExecutedLines;
+                       file->m_codeLines = nCodeLines;
+               }
+       }
+
+       std::string writeOne(File *file)
+       {
+               unsigned int nExecutedLines = 0;
+               unsigned int nCodeLines = 0;
+               IConfiguration& conf = IConfiguration::getInstance();
+
+               // Compute filename, stripping paths
+               std::string filename = file->m_name;
+
+               if (conf.keyAsInt("codecov-full-paths") == 0)
+               {
+                       std::string stripPath = conf.keyAsString("strip-path");
+                       if (stripPath.size() == 0)
+                       {
+                               stripPath = m_commonPath;
+                       }
+                       size_t pos = filename.find(stripPath);
+                       if (pos != std::string::npos && filename.size() > 
stripPath.size())
+                       {
+                               filename = filename.substr(stripPath.size() + 
1);
+                       }
+               }
+
+               // Produce each line score.
+               std::vector<std::string> lineEntries;
+               for (unsigned int n = 1; n < file->m_lastLineNr; n++)
+               {
+                       if (m_reporter.lineIsCode(file->m_name, n))
+                       {
+                               IReporter::LineExecutionCount cnt = 
m_reporter.getLineExecutionCount(file->m_name, n);
+                               std::string hitScore = "0";
+
+                               if (m_maxPossibleHits == 
IFileParser::HITS_UNLIMITED || m_maxPossibleHits == IFileParser::HITS_SINGLE)
+                               {
+                                       if (cnt.m_hits) {
+                                               hitScore = fmt("%u", 
cnt.m_hits);
+                                       }
+                               }
+                               else
+                               { // One or multiple for a line
+                                       hitScore = fmt("\"%u/%u\"", cnt.m_hits, 
cnt.m_possibleHits);
+                               }
+                               lineEntries.push_back(fmt("      \"%u\": %s", 
n, hitScore.c_str()));
+
+                               nExecutedLines += !!cnt.m_hits;
+                               nCodeLines++;
+                       } else {
+                               // We could emit '"linenum": null,' though that 
seems wasteful in storage.
+                       }
+
+                       // Update the execution count.
+                       file->m_executedLines = nExecutedLines;
+                       file->m_codeLines = nCodeLines;
+               }
+
+               std::string linesBlock;
+               for (std::vector<std::string>::const_iterator lineEntry = 
lineEntries.begin(); lineEntry != lineEntries.end(); ++lineEntry) {
+                       if (!linesBlock.empty()) {
+                               linesBlock += ",\n";
+                       }
+                       linesBlock += *lineEntry;
+               }
+               linesBlock += "\n";
+
+
+               std::string out = 
+                       "    \"" + filename + "\": {\n" +
+                       linesBlock +
+                       "    }";
+
+               return out;
+       }
+
+       std::string getHeader()
+       {
+               return "{\n"
+                      "  \"coverage\": {\n";
+       }
+
+       const std::string getFooter()
+       {
+               return "  }\n"
+                      "}\n";
+       }
+
+       std::string m_outFile;
+       IFileParser::PossibleHits m_maxPossibleHits;
+};
+
+}  // namespace anonymous
+
+IWriter &createCodecovWriter(IFileParser &parser, IReporter &reporter, const 
std::string &outFile)
+{
+       return *new CodecovWriter(parser, reporter, outFile);
+}
+}  // namespace kcov
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/src/writers/codecov-writer.hh 
new/kcov-41/src/writers/codecov-writer.hh
--- old/kcov-40/src/writers/codecov-writer.hh   1970-01-01 01:00:00.000000000 
+0100
+++ new/kcov-41/src/writers/codecov-writer.hh   2023-02-23 13:55:55.000000000 
+0100
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <string>
+
+namespace kcov
+{
+       class IFileParser;
+       class IReporter;
+       class IOutputHandler;
+
+       IWriter &createCodecovWriter(IFileParser &elf, IReporter &reporter,
+                       const std::string &outFile);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/tests/python/link_main 
new/kcov-41/tests/python/link_main
--- old/kcov-40/tests/python/link_main  1970-01-01 01:00:00.000000000 +0100
+++ new/kcov-41/tests/python/link_main  2023-04-30 16:08:16.592335847 +0200
@@ -0,0 +1 @@
+symbolic link to main
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kcov-40/tests/tools/python.py 
new/kcov-41/tests/tools/python.py
--- old/kcov-40/tests/tools/python.py   2021-12-18 09:25:42.000000000 +0100
+++ new/kcov-41/tests/tools/python.py   2023-02-23 13:55:55.000000000 +0100
@@ -24,6 +24,13 @@
 
         assert b"Cannot find Python parser 'python3'" not in o
 
+class python_issue_368_can_handle_symlink_target(testbase.KcovTestCase):
+    def runTest(self):
+        self.setUp()
+        rv,o = self.do(testbase.kcov + " --python-parser=python3 " + 
testbase.outbase + "/kcov " + testbase.sources + "/tests/python/link_main 5 
--foo")
+
+        assert b"unrecognized option '--foo'" not in o
+
 class python_unittest(testbase.KcovTestCase):
     def runTest(self):
         self.setUp()

Reply via email to