#!/bin/sh
#
# man page lint checking, mainly for use in PCP CI builds.
# Usage: scripts/man-lint [-f] <file>...
#
# Note: silently exits if 'mandoc' utility is unavailable.
# Will also (optionally) use 'lexgrog' if it is installed,
# as a secondary static check.
#

which mandoc >/dev/null 2>&1
[ $? -eq 0 ] || exit 0	# not installed

sts=0
exit_sts=true
if [ $# -gt 0 -a "X$1" = X-f ]
then
    # -f => exit status is 0, so don't break the build!
    #
    exit_sts=false
    shift
fi

tmp=`mktemp -d /tmp/pcp.XXXXXXXXX` || exit 1
trap "rm -rf $tmp; exit \$sts" 0 1 2 3 15

# some things reported by mandoc -T lint are just plain bogus,
# or things we are not going to change
#
# the WARNING -> Warning substitution is so that the warnings
# will get picked up by the daily builds (scripts/pcp-daily)
#
mandoc -T lint "$@" \
    | sed \
	-e '/ UNSUPP: /d' \
	-e '/ WARNING: missing date/d' \
	-e '/ WARNING: cannot parse date/d' \
	-e '/ STYLE: input text line longer than 80 bytes/d' \
	-e 's/ WARNING:/ Warning:/' \
> $tmp/mandoc 2>&1
if test -s $tmp/mandoc
then
    $exit_sts && sts=1
    cat $tmp/mandoc	# failure, report issues
fi

if which lexgrog >/dev/null 2>&1
then
    if lexgrog "$@" > $tmp/lexgrog
    then
	:
    else
	$exit_sts && sts=1
	cat $tmp/lexgrog	# failure, report issues
    fi
fi

# the $(INSTALL_MAN) gmake macro has some quirks ...
# "man" page basename comes from
# - .ds xM name (no other check needed)
# - text after .SH NAME that is assumed to be \f3name\f1 ... or
#   \f3\*(foo\f1 ... (if a .ds foo name was seen previously) or
#   one or more of these constructs before the first \\- or -,
#   e.g.
#	\f3pmRegisterDerived\f1,
#	\f3pmRegisterDerivedMetric\f1  \- register a global ...
#
# Check for these.
#
for file
do
    awk <$file >$tmp/out '
BEGIN				{ state = 0 }
$1 == ".ds" && $3 = "xM"	{ print $3; exit }
$1 == ".ds"			{ ds["\\\\*("$2] = $3 }
$1 == ".SH" && $2 == "NAME"	{ state = 1; next }
state == 1			{ print >"'$tmp/tmp'" }
$1 == ".SH" && state = 1		{ exit }
/^\./				{ next }
state == 1	{ for (i = 1; i <= NF; i++) {
		    if ($i == "\\-" || $i == "-") exit
		    gsub("\\f3", "", $i);
		    gsub("\\f1.*", "", $i);
		    for (d in ds)
			sub(d, ds[d], $i)
		    print $i
		  }
		}'

    if [ ! -s $tmp/out ]
    then
	echo "$file: Error: .SH NAME not in format required by \$(INSTALL_MAN)"
	echo "Scanned .SH NAME text ..."
	cat $tmp/tmp
	$exit_sts && sts=1
    fi
done

# sanity check that man(1) can read each file without producing errors
for manpage in "$@"
do
    man ./$manpage 2>$tmp/err | cat >/dev/null
    if [ -s $tmp/err ]
    then
	echo "Error: man ./$manpage produces the following stderr diagnostics:"
	cat $tmp/err
	sts=1
    fi
done

exit
