• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /bin/bash
2# Copyright (C) Sebastian Pipping <sebastian@pipping.org>
3# Licensed under the MIT license
4
5export PS4='# '
6
7
8_get_source_dir() {
9    echo "source__${version}"
10}
11
12
13_get_build_dir() {
14    local libbsd_part=
15    if ${with_libbsd}; then
16        libbsd_part=__libbsd
17    fi
18
19    local mingw_part=
20    if ${with_mingw}; then
21        mingw_part=__windows
22    fi
23
24    local char_part=
25    if ${with_unsigned_char}; then
26        char_part=__unsigned_char
27    fi
28
29    echo "build__${version}__unicode_${unicode_enabled}__xml_context_${xml_context}${libbsd_part}${mingw_part}${char_part}"
30}
31
32
33_get_coverage_dir() {
34    echo "coverage__${version}"
35}
36
37
38_configure() {
39    local configure_args=()
40
41    ${unicode_enabled} \
42            && configure_args+=( CPPFLAGS='-DXML_UNICODE -DXML_UNICODE_WCHAR_T' )
43
44    if [[ ${xml_context} -eq 0 ]]; then
45        configure_args+=( --disable-xml-context )
46    else
47        configure_args+=( --enable-xml-context=${xml_context} )
48    fi
49
50    ${with_libbsd} && configure_args+=( --with-libbsd )
51    ${with_mingw} && configure_args+=( --host=i686-w64-mingw32 )
52
53    (
54        set -x
55        ./buildconf.sh &> configure.log
56        ./configure "${configure_args[@]}" "$@" &>> configure.log
57    )
58}
59
60
61_copy_to() {
62    local target_dir="$1"
63    [[ -d "${target_dir}" ]] && return 0
64
65    mkdir "${target_dir}"
66    git archive --format=tar "${version}" | ( cd "${target_dir}" && tar x )
67}
68
69
70_copy_missing_mingw_libaries() {
71    # These extra files are copied because
72    # * coverage GCC flags make them needed
73    # * With WINEDLLPATH Wine looks for .dll.so in these folders, not .dll
74    local target="$1"
75    local mingw_gcc_dll_dir="$(dirname "$(ls -1 /usr/lib*/gcc/i686-w64-mingw32/*/libgcc_s_sjlj-1.dll | head -n1)")"
76    for dll in libgcc_s_sjlj-1.dll libstdc++-6.dll; do
77        (
78            set -x
79            ln -s "${mingw_gcc_dll_dir}"/${dll} "${target}"/${dll}
80        )
81    done
82
83    local mingw_pthread_dll_dir="$(dirname "$(ls -1 /usr/i686-w64-mingw32/lib*/libwinpthread-1.dll | head -n1)")"
84    for dll in libwinpthread-1.dll; do
85        source="${mingw_pthread_dll_dir}"/${dll}
86        [[ -e "${source}" ]] || continue
87        (
88            set -x
89            ln -s "${source}" "${target}"/${dll}
90        )
91    done
92}
93
94
95_run() {
96    local source_dir="$1"
97    local build_dir="$2"
98    local capture_dir=lib
99
100    local BASE_FLAGS='-pipe -Wall -Wextra -pedantic -Wno-overlength-strings'
101    BASE_FLAGS+=' --coverage --no-inline'
102
103    ${with_unsigned_char} && BASE_FLAGS="${BASE_FLAGS} -funsigned-char"
104
105    local CFLAGS="-std=c99 ${BASE_FLAGS}"
106    local CXXFLAGS="-std=c++98 ${BASE_FLAGS}"
107
108    (
109        set -e
110        cd "${build_dir}"
111
112        _configure \
113                CFLAGS="${BASE_FLAGS}" \
114                CXXFLAGS="${BASE_FLAGS}"
115
116        (
117            set -x
118            make -C lib &> build.log
119
120            lcov -c -d "${capture_dir}" -i -o "${coverage_info}-zero" &> run.log
121        )
122
123        if ${with_mingw}; then
124            for d in {tests,xmlwf}/.libs ; do
125                mkdir -p "${d}"
126                _copy_missing_mingw_libaries "${d}"
127            done
128        fi
129
130        set -x
131        make all check run-xmltest
132
133        lcov -c -d "${capture_dir}" -o "${coverage_info}-test" &>> run.log
134        lcov \
135                -a "${coverage_info}-zero" \
136                -a "${coverage_info}-test" \
137                -o "${coverage_info}-all" \
138                &>> run.log
139
140        # Make sure that files overlap in report despite different build folders
141        sed "/SF:/ s,${build_dir}/,${source_dir}/," "${coverage_info}-all" > "${coverage_info}"
142    ) |& sed 's,^,  ,'
143    res=${PIPESTATUS[0]}
144
145    if [[ ${res} -eq 0 ]]; then
146        echo PASSED
147    else
148        echo FAILED >&2
149        return 1
150    fi
151}
152
153
154_merge_coverage_info() {
155    local coverage_dir="$1"
156    shift
157    local build_dirs=( "$@" )
158
159    mkdir -p "${coverage_dir}"
160    (
161        local lcov_merge_args=()
162        for build_dir in "${build_dirs[@]}"; do
163            lcov_merge_args+=( -a "${build_dir}/${coverage_info}" )
164        done
165        lcov_merge_args+=( -o "${coverage_dir}/${coverage_info}" )
166
167        set -x
168        lcov "${lcov_merge_args[@]}"
169    ) &> "${coverage_dir}/merge.log"
170}
171
172
173_render_html_report() {
174    local coverage_dir="$1"
175    genhtml -o "${coverage_dir}" "${coverage_dir}/${coverage_info}" &> "${coverage_dir}/render.log"
176}
177
178
179_show_summary() {
180    local coverage_dir="$1"
181    lcov -q -l "${coverage_dir}/${coverage_info}" | grep -v '^\['
182}
183
184
185_main() {
186    version="$(git describe --tags)"
187    coverage_info=coverage.info
188
189    local build_dirs=()
190    local source_dir="$(_get_source_dir)"
191    local coverage_dir="$(_get_coverage_dir)"
192
193    _copy_to "${source_dir}"
194
195    _build_case() {
196        local build_dir="$(_get_build_dir)"
197
198        echo "[${build_dir}]"
199        _copy_to "${build_dir}"
200        _run "${source_dir}" "${build_dir}"
201
202        build_dirs+=( "${build_dir}" )
203    }
204
205    # All combinations:
206    with_unsigned_char=false
207    with_libbsd=false
208    for with_mingw in true false ; do
209        for unicode_enabled in true false ; do
210            if ${unicode_enabled} && ! ${with_mingw} ; then
211                continue
212            fi
213
214            for xml_context in 0 1024 ; do
215                _build_case
216            done
217        done
218    done
219
220    # Single cases:
221    with_libbsd=true _build_case
222    with_unsigned_char=true _build_case
223
224    echo
225    echo 'Merging coverage files...'
226    _merge_coverage_info "${coverage_dir}" "${build_dirs[@]}"
227
228    echo 'Rendering HTML report...'
229    _render_html_report "${coverage_dir}"
230    echo "--> ${coverage_dir}/index.html"
231
232    echo
233    _show_summary "${coverage_dir}"
234}
235
236
237_main
238