117 lines
3.8 KiB
Bash
Executable File
117 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Verification for the PIP GDB pretty-printers (tools/gdb/pip_pp.py).
|
|
#
|
|
# Builds demo_pp.cpp with debug info against an already-built PIP library,
|
|
# runs it under GDB in batch mode with the pretty-printers loaded, and
|
|
# checks that the expected pretty output is produced.
|
|
#
|
|
# Usage:
|
|
# tools/gdb/test/test_pp.sh <pip-build-dir>
|
|
#
|
|
# <pip-build-dir> must contain libpip.so and pip_export.h, e.g. build_linux.
|
|
# Requires g++ and gdb.
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PIP_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
|
BUILD_DIR="${1:-}"
|
|
if [[ -z "${BUILD_DIR}" ]]; then
|
|
echo "usage: $0 <pip-build-dir> (e.g. build_linux)" >&2
|
|
exit 2
|
|
fi
|
|
BUILD_DIR="$(cd "${BUILD_DIR}" && pwd)"
|
|
|
|
if [[ ! -f "${BUILD_DIR}/libpip.so" ]]; then
|
|
echo "error: ${BUILD_DIR}/libpip.so not found" >&2
|
|
exit 2
|
|
fi
|
|
if [[ ! -f "${BUILD_DIR}/pip_export.h" ]]; then
|
|
echo "error: ${BUILD_DIR}/pip_export.h not found (is this a PIP build dir?)" >&2
|
|
exit 2
|
|
fi
|
|
|
|
WORK="$(mktemp -d)"
|
|
trap 'rm -rf "${WORK}"' EXIT
|
|
|
|
# Include dirs: libs/main plus each of its subdirectories, plus the build dir.
|
|
INCS="-I${PIP_ROOT}/libs/main -I${BUILD_DIR}"
|
|
for d in "${PIP_ROOT}"/libs/main/*/; do
|
|
INCS+=" -I${d%/}"
|
|
done
|
|
|
|
echo "== building demo =="
|
|
g++ -g -O0 -std=c++11 "${SCRIPT_DIR}/demo_pp.cpp" \
|
|
${INCS} \
|
|
-L"${BUILD_DIR}" -lpip -Wl,-rpath,"${BUILD_DIR}" \
|
|
-o "${WORK}/demo_pp"
|
|
|
|
echo "== running gdb =="
|
|
OUT="$(gdb -batch -nx \
|
|
-ex "source ${PIP_ROOT}/tools/gdb/pip_pp.py" \
|
|
-ex "break main" -ex run \
|
|
-ex "print str_hello" \
|
|
-ex "print str_cyr" \
|
|
-ex "print str_empty" \
|
|
-ex "print str_esc" \
|
|
-ex "print chr_a" \
|
|
-ex "print chr_cyr" \
|
|
-ex "print ba_hello" \
|
|
-ex "print vec_int" \
|
|
-ex "print vec_str" \
|
|
-ex "print vec_vec" \
|
|
-ex "print vec_big" \
|
|
-ex "print map_str_int" \
|
|
-ex "print set_int" \
|
|
-ex "print list_str" \
|
|
-ex "print pair_str_int" \
|
|
-ex "print var_int" \
|
|
-ex "print var_invalid" \
|
|
-ex "print addr" \
|
|
-ex "print addr_null" \
|
|
-ex "print ptr_str" \
|
|
-ex "print *ptr_str" \
|
|
"${WORK}/demo_pp" 2>&1)"
|
|
|
|
echo "${OUT}" | grep -E '^\$[0-9]+ = ' || true
|
|
|
|
fail=0
|
|
check() {
|
|
local pattern="$1" desc="$2"
|
|
if grep -qE -- "${pattern}" <<<"${OUT}"; then
|
|
echo "ok ${desc}"
|
|
else
|
|
echo "FAIL ${desc} (expected to match: ${pattern})"
|
|
fail=1
|
|
fi
|
|
}
|
|
|
|
check '^\$[0-9]+ = "hello"$' "PIString ascii"
|
|
check '^\$[0-9]+ = "мир"$' "PIString utf-8"
|
|
check '^\$[0-9]+ = ""$' "PIString empty"
|
|
check '^\$[0-9]+ = "a\\"b\\\\c\\nd\\te"$' "PIString escapes"
|
|
check '^\$[0-9]+ = '"'"'a'"'"'$' "PIChar printable"
|
|
check '^\$[0-9]+ = U\+043c$' "PIChar non-ascii"
|
|
check '^\$[0-9]+ = \{0x48, 0x65, 0x6c, 0x6c, 0x6f\}$' "PIByteArray hex"
|
|
check '^\$[0-9]+ = \{1, 2, 3\}$' "PIVector<int>"
|
|
check '^\$[0-9]+ = \{"a", "bb"\}$' "PIVector<PIString>"
|
|
check '^\$[0-9]+ = \{\{10\}, \{1, 2, 3\}\}$' "PIVector<PIVector<int>>"
|
|
check '\.\.\. \(40 total\)\}$' "element count limit"
|
|
check '^\$[0-9]+ = \{"x": 1, "y": 2\}$' "PIMap"
|
|
check '^\$[0-9]+ = \{3, 5\}$' "PISet"
|
|
check '^\$[0-9]+ = \{"one", "two"\}$' "PIStringList"
|
|
check '^\$[0-9]+ = \{"k", 7\}$' "PIPair"
|
|
check '^\$[0-9]+ = PIVariant\(pivInt, 4 bytes\)$' "PIVariant typed"
|
|
check '^\$[0-9]+ = PIVariant\(pivInvalid, 0 bytes\)$' "PIVariant invalid"
|
|
check '^\$[0-9]+ = 192\.168\.1\.10:8080$' "PINetworkAddress"
|
|
check '^\$[0-9]+ = 0\.0\.0\.0:0$' "PINetworkAddress null"
|
|
check '^\$[0-9]+ = \(PIString \*\) 0x[0-9a-f]+ "hello"$' "pointer to PIString"
|
|
check '^\$[0-9]+ = "hello"$' "dereferenced pointer"
|
|
|
|
if [[ "${fail}" -ne 0 ]]; then
|
|
echo "== FAILED =="
|
|
exit 1
|
|
fi
|
|
echo "== all checks passed =="
|