libexpat/expat/qa.sh

311 lines
7.9 KiB
Bash
Raw Normal View History

#! /usr/bin/env bash
# __ __ _
# ___\ \/ /_ __ __ _| |_
# / _ \\ /| '_ \ / _` | __|
# | __// \| |_) | (_| | |_
# \___/_/\_\ .__/ \__,_|\__|
# |_| XML parser
#
# Copyright (c) 2016-2021 Sebastian Pipping <sebastian@pipping.org>
# Copyright (c) 2019 Philippe Antoine <contact@catenacyber.fr>
# Copyright (c) 2019 Hanno Böck <hanno@gentoo.org>
# 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.
2016-05-15 08:11:11 -04:00
set -e
2016-05-15 08:11:11 -04:00
set -o nounset
2016-05-30 14:56:00 -04:00
ANNOUNCE() {
2016-05-24 14:33:13 -04:00
local open='\e[1m'
local close='\e[0m'
echo -e -n "${open}" >&2
echo -n "# $*" >&2
echo -e "${close}" >&2
}
WARNING() {
local open='\e[1;33m'
local close='\e[0m'
echo -e -n "${open}" >&2
echo -n "WARNING: $*" >&2
echo -e "${close}" >&2
2016-05-30 14:56:00 -04:00
}
2016-05-24 14:33:13 -04:00
2016-05-30 14:56:00 -04:00
RUN() {
ANNOUNCE "$@"
2016-05-24 14:33:13 -04:00
env "$@"
}
2016-05-15 08:11:11 -04:00
populate_environment() {
: ${MAKE:=make}
2016-05-15 08:11:11 -04:00
case "${QA_COMPILER}" in
clang)
: ${CC:=clang}
: ${CXX:=clang++}
2019-07-09 17:55:05 -04:00
: ${LD:=clang++}
;;
gcc)
: ${CC:=gcc}
: ${CXX:=g++}
2019-07-09 17:55:05 -04:00
: ${LD:=ld}
;;
esac
2016-05-15 08:11:11 -04:00
: ${BASE_COMPILE_FLAGS:="-pipe -Wall -Wextra -pedantic -Wno-overlength-strings -Wno-long-long"}
: ${BASE_LINK_FLAGS:=}
if [[ ${QA_COMPILER} = clang ]]; then
case "${QA_SANITIZER}" in
address)
# http://clang.llvm.org/docs/AddressSanitizer.html
BASE_COMPILE_FLAGS+=" -g -fsanitize=address -fno-omit-frame-pointer -fno-common"
BASE_LINK_FLAGS+=" -g -fsanitize=address"
2019-08-03 15:21:25 -04:00
# macOS's XCode does not support LeakSanitizer and reports error:
# AddressSanitizer: detect_leaks is not supported on this platform.
if [[ "$(uname -s)" != Darwin* ]]; then
export ASAN_OPTIONS=detect_leaks=1
fi
;;
memory)
# http://clang.llvm.org/docs/MemorySanitizer.html
BASE_COMPILE_FLAGS+=" -fsanitize=memory -fno-omit-frame-pointer -g -O2 -fsanitize-memory-track-origins -fsanitize-blacklist=$PWD/memory-sanitizer-blacklist.txt"
;;
undefined)
# http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
BASE_COMPILE_FLAGS+=" -fsanitize=undefined"
BASE_LINK_FLAGS+=" -fsanitize=undefined"
export UBSAN_OPTIONS="print_stacktrace=1:halt_on_error=1:abort_on_error=1"
;;
esac
fi
2016-05-15 08:11:11 -04:00
2016-05-24 14:34:07 -04:00
if [[ ${QA_COMPILER} = gcc ]]; then
case "${QA_PROCESSOR}" in
egypt) BASE_COMPILE_FLAGS+=" -fdump-rtl-expand" ;;
gcov) BASE_COMPILE_FLAGS+=" --coverage -O0" ;;
2016-05-24 14:34:07 -04:00
esac
fi
2016-05-15 08:11:11 -04:00
CFLAGS="-std=c99 ${BASE_COMPILE_FLAGS} ${CFLAGS:-}"
CXXFLAGS="-std=c++98 ${BASE_COMPILE_FLAGS} ${CXXFLAGS:-}"
LDFLAGS="${BASE_LINK_FLAGS} ${LDFLAGS:-}"
}
run_cmake() {
local cmake_args=(
-DCMAKE_C_COMPILER="${CC}"
-DCMAKE_C_FLAGS="${CFLAGS}"
-DCMAKE_CXX_COMPILER="${CXX}"
-DCMAKE_CXX_FLAGS="${CXXFLAGS}"
-DCMAKE_LINKER="${LD}"
-DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}"
-DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}"
-DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}"
-DEXPAT_WARNINGS_AS_ERRORS=ON
)
RUN cmake "${cmake_args[@]}" "$@" .
}
run_compile() {
local make_args=(
VERBOSE=1
-j2
)
RUN "${MAKE}" "${make_args[@]}" clean all
}
run_tests() {
case "${QA_PROCESSOR}" in
egypt) return 0 ;;
esac
if [[ ${CC} =~ mingw ]]; then
# NOTE: Filenames are hardcoded for Travis' Ubuntu Bionic, as of now
for i in tests xmlwf ; do
mingw32_dir="$(ls -1d /usr/lib/gcc/i686-w64-mingw32/* | head -n1)"
RUN ln -s \
/usr/i686-w64-mingw32/lib/libwinpthread-1.dll \
"${mingw32_dir}"/libgcc_s_sjlj-1.dll \
"${mingw32_dir}"/libstdc++-6.dll \
"$PWD"/libexpat{,w}.dll \
${i}/
done
fi
local make_args=(
CTEST_OUTPUT_ON_FAILURE=1
CTEST_PARALLEL_LEVEL=2
VERBOSE=1
test
)
[[ $* =~ -DEXPAT_DTD=OFF ]] || make_args+=( run-xmltest )
RUN "${MAKE}" "${make_args[@]}"
}
run_processor() {
if [[ ${QA_COMPILER} != gcc ]]; then
return 0
fi
case "${QA_PROCESSOR}" in
2016-05-30 14:29:33 -04:00
egypt)
local DOT_FORMAT="${DOT_FORMAT:-svg}"
2016-05-30 14:56:00 -04:00
local o="callgraph.${DOT_FORMAT}"
ANNOUNCE "egypt ...... | dot ...... > ${o}"
find -name '*.expand' \
| sort \
| xargs -r egypt \
| unflatten -c 20 \
| dot -T${DOT_FORMAT} -Grankdir=LR \
> "${o}"
2016-05-30 14:29:33 -04:00
;;
gcov)
for gcov_dir in lib xmlwf ; do
(
cd "${gcov_dir}" || exit 1
for gcda_file in $(find . -name '*.gcda' | sort) ; do
RUN gcov -s .libs/ ${gcda_file}
done
)
done
RUN find -name '*.gcov' | sort
2016-05-24 14:34:07 -04:00
;;
2016-05-24 14:33:13 -04:00
esac
2016-05-15 08:11:11 -04:00
}
run() {
populate_environment
dump_config
run_cmake "$@"
run_compile
run_tests "$@"
run_processor
}
dump_config() {
cat <<EOF
Configuration:
2019-09-04 15:53:47 -04:00
QA_COMPILER=${QA_COMPILER} # auto-detected from \$CC and \$CXX
QA_PROCESSOR=${QA_PROCESSOR} # GCC only
QA_SANITIZER=${QA_SANITIZER} # Clang only
CFLAGS=${CFLAGS}
CXXFLAGS=${CXXFLAGS}
LDFLAGS=${LDFLAGS}
CC=${CC}
CXX=${CXX}
LD=${LD}
MAKE=${MAKE}
2019-07-22 17:34:08 -04:00
Compiler (\$CC):
EOF
2019-07-22 17:34:08 -04:00
"${CC}" --version | sed 's,^, ,'
echo
}
2019-09-04 15:53:47 -04:00
classify_compiler() {
local i
for i in "${CC:-}" "${CXX:-}"; do
[[ "$i" =~ clang ]] && { echo clang ; return ; }
done
echo gcc
}
process_config() {
2019-09-04 15:53:47 -04:00
case "${QA_COMPILER:=$(classify_compiler)}" in
clang|gcc) ;;
*) usage; exit 1 ;;
esac
if [[ ${QA_COMPILER} != gcc && -n ${QA_PROCESSOR:-} ]]; then
WARNING "QA_COMPILER=${QA_COMPILER} is not 'gcc' -- ignoring QA_PROCESSOR=${QA_PROCESSOR}"
fi
case "${QA_PROCESSOR:=gcov}" in
egypt|gcov) ;;
*) usage; exit 1 ;;
esac
if [[ ${QA_COMPILER} != clang && -n ${QA_SANITIZER:-} ]]; then
WARNING "QA_COMPILER=${QA_COMPILER} is not 'clang' -- ignoring QA_SANITIZER=${QA_SANITIZER}" >&2
fi
case "${QA_SANITIZER:=address}" in
address|memory|undefined) ;;
*) usage; exit 1 ;;
esac
}
usage() {
cat <<"EOF"
Usage:
$ ./qa.sh [ARG ..]
Environment variables
2019-09-04 15:53:47 -04:00
QA_COMPILER=(clang|gcc) # default: auto-detected
QA_PROCESSOR=(egypt|gcov) # default: gcov
QA_SANITIZER=(address|memory|undefined) # default: address
EOF
}
main() {
if [[ ${1:-} = --help ]]; then
usage; exit 0
fi
process_config
run "$@"
}
2016-05-15 08:11:11 -04:00
main "$@"