Add code coverage support

The coverage report shows what code is covered by tests and what is not
and the ratio could be tracked over time. These reports will allow us
to identify code that is not being tested and improve the test suites.

To enable the reports configure with --enable-code-coverage and execute
"make check-code-coverage". The HTML report will be generated in a
subdirectory with name libosmocore-$(PACKAGE_VERSION)-coverage/index.html

The report is generated using gcov, lcov and lcov_cobertura tools and
the OSMO_AC_CODE_COVERAGE macro. The osmo_ax_code_coverage.m4 is a copy of
ax_code_coverage.m4 taken from autoconf-archive v2018.03.13. It was
copied to avoid the additional external dependency and renamed to avoid
overwriting it in case autoconf-archive is already installed as we are
going to install it in $(datadir)/aclocal in order to be reused in other
osmocom's projects.

Closes: OS#1987
Change-Id: I6f4ffb91bd7f3dd070aa09dd16d5ad1faf130a4c
diff --git a/m4/osmo_ac_code_coverage.m4 b/m4/osmo_ac_code_coverage.m4
new file mode 100644
index 0000000..7921db5
--- /dev/null
+++ b/m4/osmo_ac_code_coverage.m4
@@ -0,0 +1,51 @@
+AC_DEFUN([OSMO_AC_CODE_COVERAGE],[
+	dnl Check for --enable-code-coverage
+	AC_REQUIRE([OSMO_AX_CODE_COVERAGE])
+	AC_REQUIRE([AX_CHECK_COMPILE_FLAG])
+
+	AS_IF([ test "x$enable_code_coverage" = "xyes" ], [
+		# Check whether --coverage flags is supported and add it to CFLAGS
+		# When it is not supported add CODE_COVERAGE_CFLAGS to CFLAGS instead
+		AX_CHECK_COMPILE_FLAG([--coverage],
+			[CFLAGS="$CFLAGS -O0 -g --coverage"],
+			[CFLAGS="$CFLAGS $CODE_COVERAGE_CFLAGS"])
+
+		# Add both the absolute source and build directories to the coverage directories.
+		CODE_COVERAGE_DIRECTORY='$(abspath $(abs_top_srcdir)) $(abspath $(abs_top_builddir))'
+		AC_SUBST(CODE_COVERAGE_DIRECTORY)
+
+		# Enable branch coverage by default
+		CODE_COVERAGE_BRANCH_COVERAGE='1'
+		AC_SUBST(CODE_COVERAGE_BRANCH_COVERAGE)
+
+		# Exclude external files by default
+		CODE_COVERAGE_LCOV_OPTIONS='$(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) --no-external'
+		AC_SUBST(CODE_COVERAGE_LCOV_OPTIONS)
+
+		# Exclude tests sources from the coverage report
+		CODE_COVERAGE_IGNORE_PATTERN='"$(abspath $(abs_top_srcdir))/tests/*"'
+		AC_SUBST(CODE_COVERAGE_IGNORE_PATTERN)
+
+		# lcov_cobertura is needed only when you want to export the coverage report in
+		# the Cobertura's XML format supported by Jenkin's Cobertura plugin
+		AC_CHECK_PROG([LCOV_COBERTURA], [lcov_cobertura], [lcov_cobertura])
+		AS_IF([test "x$LCOV_COBERTURA" != "xno"], [m4_pattern_allow([AM_V_GEN]) CODE_COVERAGE_RULES+='
+coverage-cobertura.xml: $(CODE_COVERAGE_OUTPUT_FILE)
+	$(AM_V_GEN)$(LCOV_COBERTURA) -b $(top_srcdir) -o $$@@ $(CODE_COVERAGE_OUTPUT_FILE)
+
+.PHONY: code-coverage-cobertura
+code-coverage-cobertura: code-coverage-capture coverage-cobertura.xml
+'
+		], [CODE_COVERAGE_RULES+='
+.PHONY: code-coverage-cobertura
+code-coverage-cobertura:
+	@echo "Need to install lcov_cobertura"
+'
+		])
+	], [CODE_COVERAGE_RULES+='
+.PHONY: code-coverage-cobertura
+code-coverage-cobertura:
+	@echo "Need to and reconfigure with --enable-code-coverage"
+'
+	])
+])