| #! /bin/bash |
| # Copyright (C) Sebastian Pipping <sebastian@pipping.org> |
| # 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 |