#! /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

# Source directory.  Automake sets this for us on out-of-tree builds.
srcdir=${srcdir:-.}


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

# This version must be at the top of the NEWS file.
check_news_version() {
	if ! head -n1 $srcdir/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 $srcdir/include/pqxx/* -type f)
	count_includes $srcdir/pqxx/compiler-internal-pre.hxx $HEADERS >"$PRE"
	count_includes $srcdir/pqxx/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() {
	if which cppcheck >/dev/null
	then
		cppcheck -q -j$(nproc) -I include src/*.cxx test/*.cxx test/unit/*.cxx
	fi
}


pylint() {
	local PYFILES="$srcdir/tools/*.py $srcdir/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
