#! /usr/bin/env bash # Copyright (C) Sebastian Pipping # Licensed under the MIT license export PS4='# ' _get_source_dir() { echo "source__${version}" } _get_build_dir() { local libbsd_part= if ${with_libbsd}; then libbsd_part=__libbsd fi local mingw_part= if ${with_mingw}; then mingw_part=__windows fi local char_part= if ${with_unsigned_char}; then char_part=__unsigned_char fi echo "build__${version}__unicode_${unicode_enabled}__xml_context_${xml_context}${libbsd_part}${mingw_part}${char_part}" } _get_coverage_dir() { echo "coverage__${version}" } _configure() { local configure_args=() ${unicode_enabled} \ && configure_args+=( CPPFLAGS='-DXML_UNICODE -DXML_UNICODE_WCHAR_T' ) if [[ ${xml_context} -eq 0 ]]; then configure_args+=( --disable-xml-context ) else configure_args+=( --enable-xml-context=${xml_context} ) fi ${with_libbsd} && configure_args+=( --with-libbsd ) ${with_mingw} && configure_args+=( --host=i686-w64-mingw32 ) ( set -x ./buildconf.sh &> configure.log ./configure "${configure_args[@]}" "$@" &>> configure.log ) } _copy_to() { local target_dir="$1" [[ -d "${target_dir}" ]] && return 0 mkdir "${target_dir}" git archive --format=tar "${version}" | ( cd "${target_dir}" && tar x ) } _copy_missing_mingw_libaries() { # These extra files are copied because # * coverage GCC flags make them needed # * With WINEDLLPATH Wine looks for .dll.so in these folders, not .dll local target="$1" local mingw_gcc_dll_dir="$(dirname "$(ls -1 /usr/lib*/gcc/i686-w64-mingw32/*/libgcc_s_sjlj-1.dll | head -n1)")" for dll in libgcc_s_sjlj-1.dll libstdc++-6.dll; do ( set -x ln -s "${mingw_gcc_dll_dir}"/${dll} "${target}"/${dll} ) done local mingw_pthread_dll_dir="$(dirname "$(ls -1 /usr/i686-w64-mingw32/lib*/libwinpthread-1.dll | head -n1)")" for dll in libwinpthread-1.dll; do source="${mingw_pthread_dll_dir}"/${dll} [[ -e "${source}" ]] || continue ( set -x ln -s "${source}" "${target}"/${dll} ) done } _run() { local source_dir="$1" local build_dir="$2" local capture_dir=lib local BASE_FLAGS='-pipe -Wall -Wextra -pedantic -Wno-overlength-strings' BASE_FLAGS+=' --coverage --no-inline' ${with_unsigned_char} && BASE_FLAGS="${BASE_FLAGS} -funsigned-char" local CFLAGS="-std=c99 ${BASE_FLAGS}" local CXXFLAGS="-std=c++98 ${BASE_FLAGS}" ( set -e cd "${build_dir}" _configure \ CFLAGS="${BASE_FLAGS}" \ CXXFLAGS="${BASE_FLAGS}" ( set -x make -C lib &> build.log lcov -c -d "${capture_dir}" -i -o "${coverage_info}-zero" &> run.log ) if ${with_mingw}; then for d in {tests,xmlwf}/.libs ; do mkdir -p "${d}" _copy_missing_mingw_libaries "${d}" done fi set -x make all check run-xmltest lcov -c -d "${capture_dir}" -o "${coverage_info}-test" &>> run.log lcov \ -a "${coverage_info}-zero" \ -a "${coverage_info}-test" \ -o "${coverage_info}-all" \ &>> run.log # Make sure that files overlap in report despite different build folders sed "/SF:/ s,${build_dir}/,${source_dir}/," "${coverage_info}-all" > "${coverage_info}" ) |& sed 's,^, ,' res=${PIPESTATUS[0]} if [[ ${res} -eq 0 ]]; then echo PASSED else echo FAILED >&2 return 1 fi } _merge_coverage_info() { local coverage_dir="$1" shift local build_dirs=( "$@" ) mkdir -p "${coverage_dir}" ( local lcov_merge_args=() for build_dir in "${build_dirs[@]}"; do lcov_merge_args+=( -a "${build_dir}/${coverage_info}" ) done lcov_merge_args+=( -o "${coverage_dir}/${coverage_info}" ) set -x lcov "${lcov_merge_args[@]}" ) &> "${coverage_dir}/merge.log" } _render_html_report() { local coverage_dir="$1" genhtml -o "${coverage_dir}" "${coverage_dir}/${coverage_info}" &> "${coverage_dir}/render.log" } _show_summary() { local coverage_dir="$1" lcov -q -l "${coverage_dir}/${coverage_info}" | grep -v '^\[' } _main() { version="$(git describe --tags)" coverage_info=coverage.info local build_dirs=() local source_dir="$(_get_source_dir)" local coverage_dir="$(_get_coverage_dir)" _copy_to "${source_dir}" _build_case() { local build_dir="$(_get_build_dir)" echo "[${build_dir}]" _copy_to "${build_dir}" _run "${source_dir}" "${build_dir}" build_dirs+=( "${build_dir}" ) } # All combinations: with_unsigned_char=false with_libbsd=false for with_mingw in true false ; do for unicode_enabled in true false ; do if ${unicode_enabled} && ! ${with_mingw} ; then continue fi for xml_context in 0 1024 ; do _build_case done done done # Single cases: with_libbsd=true _build_case with_unsigned_char=true _build_case echo echo 'Merging coverage files...' _merge_coverage_info "${coverage_dir}" "${build_dirs[@]}" echo 'Rendering HTML report...' _render_html_report "${coverage_dir}" echo "--> ${coverage_dir}/index.html" echo _show_summary "${coverage_dir}" } _main