| #! /usr/bin/env bash |
| # __ __ _ |
| # ___\ \/ /_ __ __ _| |_ |
| # / _ \\ /| '_ \ / _` | __| |
| # | __// \| |_) | (_| | |_ |
| # \___/_/\_\ .__/ \__,_|\__| |
| # |_| XML parser |
| # |
| # Copyright (c) 2017-2019 Sebastian Pipping <sebastian@pipping.org> |
| # Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it> |
| # Copyright (c) 2019 Mohammed Khajapasha <mohammed.khajapasha@intel.com> |
| # Licensed under the MIT license: |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining |
| # a copy of this software and associated documentation files (the |
| # "Software"), to deal in the Software without restriction, including |
| # without limitation the rights to use, copy, modify, merge, publish, |
| # distribute, sublicense, and/or sell copies of the Software, and to permit |
| # persons to whom the Software is furnished to do so, subject to the |
| # following conditions: |
| # |
| # The above copyright notice and this permission notice shall be included |
| # in all copies or substantial portions of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
| # NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
| # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
| # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
| # USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| 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 |
| |
| local xml_attr_part= |
| if ${xml_attr_info_enabled}; then |
| xml_attr_part=__attr_info |
| fi |
| |
| echo "build__${version}__unicode_${unicode_enabled}__xml_context_${xml_context}${libbsd_part}${mingw_part}${char_part}${xml_attr_part}" |
| } |
| |
| |
| _get_coverage_dir() { |
| echo "coverage__${version}" |
| } |
| |
| |
| _call_cmake() { |
| local cmake_args=() |
| |
| ${unicode_enabled} \ |
| && cmake_args+=( -DEXPAT_CHAR_TYPE=wchar_t ) |
| |
| ${xml_attr_info_enabled} \ |
| && cmake_args+=( -DEXPAT_ATTR_INFO=ON ) |
| |
| if [[ ${xml_context} -eq 0 ]]; then |
| cmake_args+=( -DEXPAT_CONTEXT_BYTES=OFF ) |
| else |
| cmake_args+=( -DEXPAT_CONTEXT_BYTES=${xml_context} ) |
| fi |
| |
| ${with_libbsd} && cmake_args+=( -DEXPAT_WITH_LIBBSD=ON ) |
| ${with_mingw} && cmake_args+=( -DCMAKE_TOOLCHAIN_FILE="${abs_source_dir}"/cmake/mingw-toolchain.cmake ) |
| |
| ( |
| set -x |
| cmake "${cmake_args[@]}" "$@" . &>> cmake.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="$(ls -1 /usr/i686-w64-mingw32/lib*/libwinpthread-1.dll 2>/dev/null | head -n1)" |
| if [[ -n ${mingw_pthread_dll} ]]; then |
| local mingw_pthread_dll_dir="$(dirname "${mingw_pthread_dll}")" |
| for dll in libwinpthread-1.dll; do |
| source="${mingw_pthread_dll_dir}"/${dll} |
| ( |
| set -x |
| ln -s "${source}" "${target}"/${dll} |
| ) |
| done |
| fi |
| |
| for dll in libexpat{,w}.dll; do |
| ( |
| set -x |
| ln -s "${abs_build_dir}"/${dll} "${target}"/${dll} |
| ) |
| done |
| } |
| |
| |
| _run() { |
| local source_dir="$1" |
| local build_dir="$2" |
| local abs_source_dir="${PWD}/${source_dir}" |
| local abs_build_dir="${PWD}/${build_dir}" |
| local capture_dir=. |
| |
| 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}" |
| |
| _call_cmake \ |
| -DCMAKE_C_FLAGS="${CFLAGS}" \ |
| -DCMAKE_CXX_FLAGS="${CXXFLAGS}" |
| |
| ( |
| set -x |
| make &> build.log |
| |
| lcov -c -d "${capture_dir}" -i -o "${coverage_info}-zero" &> run.log |
| ) |
| |
| if ${with_mingw}; then |
| for d in tests xmlwf ; do |
| mkdir -p "${d}" |
| _copy_missing_mingw_libaries "${d}" |
| done |
| fi |
| |
| set -x |
| make CTEST_OUTPUT_ON_FAILURE=1 test 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=( -q ) |
| 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[@]}" |
| ) |& tee "${coverage_dir}/merge.log" |
| } |
| |
| |
| _clean_coverage_info() { |
| local coverage_dir="$1" |
| local dir |
| for dir in CMakeFiles examples tests ; do |
| local pattern="*/${dir}/*" |
| ( |
| set -x |
| lcov -q -o "${coverage_dir}/${coverage_info}" -r "${coverage_dir}/${coverage_info}" "${pattern}" |
| ) |& tee "${coverage_dir}/clean.log" |
| done |
| } |
| |
| |
| _render_html_report() { |
| local coverage_dir="$1" |
| ( |
| set -x |
| genhtml -o "${coverage_dir}" "${coverage_dir}/${coverage_info}" &> "${coverage_dir}/render.log" |
| ) |
| } |
| |
| |
| _show_summary() { |
| local coverage_dir="$1" |
| ( |
| set -x |
| 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}" |
| |
| # Make sure we don't need to download xmlts.zip over and over again |
| if [[ ${#build_dirs[*]} -gt 0 ]]; then |
| ln -s "$PWD/${build_dirs[0]}/tests/xmlts.zip" "${build_dir}"/tests/ |
| fi |
| |
| _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_attr_info_enabled in true false ; do |
| for xml_context in 0 1024 ; do |
| _build_case |
| done |
| 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 |
| echo 'Cleaning coverage files...' |
| _clean_coverage_info "${coverage_dir}" |
| |
| echo |
| echo 'Rendering HTML report...' |
| _render_html_report "${coverage_dir}" |
| echo "--> ${coverage_dir}/index.html" |
| |
| echo |
| echo 'Rendering ASCII report...' |
| _show_summary "${coverage_dir}" |
| } |
| |
| |
| _main |