#! /bin/sh
#
# Routine sanity checks for libpqxx source tree.
#
# Usage: lint [srcdir]
#
# srcdir is the source directory; it defaults to the current directory but
# may be set for out-of-tree builds.

set -e
set -u

# Run from source directory.  We don't write any artefacts.  Without this,
# out-of-tree builds will fail to find the files this script needs to read.
cd $(dirname "$0")/..

PQXXVERSION="$(./tools/extract_version)"

# This version must be at the top of the NEWS file.
check_news_version() {
	if ! head -n1 NEWS | grep -q "^$PQXXVERSION\$"
	then
		cat <<EOF >&2
Version $PQXXVERSION is not at the top of NEWS.
EOF
		exit 1
	fi
}


# Count number of times header $1 is included from each of given input files.
# Output is lines of <filename>:<count>, one line per file, sorted.
count_includes() {
	local HEADER_NAME WS PAT
	HEADER_NAME="$1"
	shift
	WS="[[:space:]]*"
	PAT="^${WS}#${WS}include${WS}[<\"]$HEADER_NAME[>\"]"
	grep -c "$PAT" $* | sort
}


# Any file that includes compiler-internal-pre.hxx must also include
# compiler-internal-post.hxx, and vice versa.
check_compiler_internal_headers() {
	local TEMPDIR PRE POST HEADERS
	TEMPDIR="$(mktemp --tmpdir -d pqxx-lint.XXXX)"
	if test -z "$TEMPDIR"
	then
		echo >&2 "Could not create temporary directory."
                exit 1
	fi
	PRE="$TEMPDIR/pre"
	POST="$TEMPDIR/post"
	HEADERS=$(find include/pqxx/* -type f)
	count_includes pqxx/internal/compiler-internal-pre.hxx $HEADERS >"$PRE"
	count_includes pqxx/internal/compiler-internal-post.hxx $HEADERS >"$POST"
	DIFF="$(diff "$PRE" "$POST")" || /bin/true
	rm -r -- "$TEMPDIR"
	if test -n "$DIFF"
	then
		cat <<EOF >&2
The number of inclusions of compiler-internal.post.hxx does not match the number
of inclusions of compiler-internal.post.hxx:

$DIFF
EOF
		exit 1
	fi
}


cpplint() {
        echo "Skipping cppcheck; it's not up to date with C++17."
	# if which cppcheck >/dev/null
	# then
	# 	cppcheck -q -j$(nproc) -I include src/*.cxx test/*.cxx test/unit/*.cxx
	# fi
}


pylint() {
	local PYFILES="tools/*.py tools/splitconfig"
	if which pocketlint >/dev/null
	then
		pocketlint $PYFILES
	fi

	if which flake8 >/dev/null
	then
		flake8 $PYFILES
	fi
}

cpplint
pylint
check_news_version
check_compiler_internal_headers
