#! /usr/bin/sh
# @(#) A.10.30 HP C LANGUAGE TOOL (LINT) 950421
#
#  SVID3 Print out version string
#
WHAT_STRING=" A.10.30 HP C LANGUAGE TOOL (LINT) 950421"
#
# New lint shell script.  Changed to make lint(1) act as much as is possible
# like a different version of the cc(1) command.  This includes the notion of
# a ``lint .o'' (.ln) and incremental linting. 
#
#################### NLS catalog support int LINT ##########################
#
#     All error messages should be defined at the top.  
#     This helps to localize all the message at one spot which
#     makes it easier for modification by the LOCAL SE. 
#
############################################################################
MSG01="usage: lint -[abhuvxnpscDUI] [-MA] [-A{ac}] [-l<lib>] [-c|-o<lib>] files"
MSG02="lint: bad option ignored"
MSG03="lint: file with unknown suffix ignored."
MSG04=" : lint library not found."
MSG05=
#
###################  END of MESSAGE CATALOG   #############################
#
TMPDIR=${TMPDIR:-/var/tmp}
LINT1=${ST_CCOM:-/opt/ansic/lbin/ccom}

TOUT=$TMPDIR/tlint.$$		# combined input for second pass
HOUT=$TMPDIR/hlint.$$		# header messages file
TMP=$TMPDIR/tmp.$$		# lint pass1 output file.
TOUT_FILES=$TMPDIR/tlint_files.$$ # system lint libraries on command line.
CPPOUT=$TMPDIR/cppout.$$        # C preprocessor output
CCOMOPT=" -w1 -Xrl"         # S800 lint opts. +w1 low level warnings.
ANSIOPT=" -Ac"			# Initialize to default mode.
L1OPTS=
NULLF=/dev/null

#
LDIR=${ST_LINT_DIR:-/opt/ansic/lbin} # second pass lint location.
LLDIR=${ST_LINT_LIB_DIR:-/usr/ccs/lib}      #where lint libraries are found
PATH=/bin:/usr/bin:/usr/ccs/bin
CC_CMD=${ST_CC:-/opt/ansic/bin/cc}
#
CCF="-E -C -D__lint -D__LINT__"	# options for the cc command
LINTF=				# options for the lint passes
LINT2F=				# options for lint2
FILES=				# the *.c and *.ln files in order
NDOTC=				# how many *.c were there
DEFL=$LLDIR/llib-lc.ln		# the default library to use
LLIB=				# lint library file to create
CONLY=				# set for ``compile only''
pre=				# these three variables used for
post=				# handling options with arguments
optarg=				# list variable to add argument to
MODE=				# ANSI vs compatibility
NAMESPACE=			# e.g. -D_POSIX_SOURCE causes llib-lc relinting
LFN_SIZE=0                      # LFN file system support.
LFN_FNAME=                      # temporary.
EXIT_STATUS=0			# exit status for lint.


#
trap "rm -f $TOUT $TOUT_FILES $HOUT; exit 2" 1 2 3 15
#
# First, run through all of the arguments, building lists
#
#	lint's options are "A:abchl:no:psuvxw:M:" 
#	cc/cpp options are "W:I:D:U:gO"
#
if [ $# -eq 0 ]
then
        echo $MSG01
	exit 0
fi
for OPT in "$@"
do
	if [ "$optarg" ]
	then
		if [ "$optarg" = "LLIB" ]	# special case...
		then
			OPT=`basename $OPT`
		fi
		eval "$optarg=\"\$$optarg \$pre\$OPT\$post\""
		pre=
		post=
		optarg=
		continue
	fi
	case "$OPT" in
	*.c)	FILES="$FILES $OPT"	NDOTC="x$NDOTC";;
	*.ln)	FILES="$FILES $OPT";;
	+*)	OPT=`echo $OPT | sed s/+//p`
		while [ "$OPT" ]
		do
			O=`echo $OPT | sed 's/\\(.\\).*/\\1/p'`		
			OPT=`echo $OPT | sed s/.//p`
			case $O in
			R)	CCOMOPT=" -R$OPT $CCOMOPT";;
			[rf])   CCOMOPT=" -$O $CCOMOPT";;
			e)	ANSIOPT="$ANSIOPT -e";;
			esac
		done ;;
	-*)	OPT=`echo $OPT | sed s/-//p`
		while [ "$OPT" ]
		do
			O=`echo $OPT | sed 's/\\(.\\).*/\\1/p'`
			OPT=`echo $OPT | sed s/.//p`
			case $O in
			p)	LINTF="$LINTF -p"
				L1OPTS="$L1OPTS,p"
				CCF="$CCF -Wp,-T"
				DEFL=$LLDIR/llib-port.ln;;
			n)	DEFL=;;
			c)	CONLY=1;;
			[abhsuvxy]) LINTF="$LINTF -$O"
				L1OPTS="$L1OPTS,$O";;
			[gO])	CCF="$CCF -$O";;
			L)      if [ "$O$OPT" = "LINTLIBRARY" ]
				then
				L1OPTS="$L1OPTS,$O"
				fi
				break;;
			V)	echo $WHAT_STRING
				echo;;
			Y)	LINTF="$LINTF -n"
				CCOMOPT=" -Y $CCOMOPT";;
			Z)	LINT2F="$LINT2F -$O$OPT"
				L1OPTS="$L1OPTS,$O$OPT"
				break;;
			N)	LINTF="$LINTF -$O$OPT"
				L1OPTS="$L1OPTS,$O$OPT"
				break;;
			M)	if [ "$O$OPT" = "MA" ]
				then
	       				LINTF="$LINTF -A"
					MODE=ANSI
					DEFL=$LLDIR/llib-lansi.ln
				fi
				break;;
			w)	if [ "$OPT" ]
				then
					LINTF="$LINTF -w$OPT"
				fi
				break ;;
			[AWIDU]) if [ "$OPT" ]
				then
					CCF="$CCF -$O$OPT"
				else
					optarg=CCF
					pre=-$O
				fi
				if [ "$O$OPT" = "Aa" ]
				then
					LINTF="$LINTF -A"
					ANSIOPT="-Aa"
					MODE=ANSI
				fi
				if [ "$O$OPT" = "Ae" ]
				then
					LINTF="$LINTF -A"
					ANSIOPT="-Ae"
					MODE=ANSI
				fi

				# Need to re-lint llib-lc if a namespace 
				# variable is set; e.g. -D_POSIX_SOURCE
				DEF="$O$OPT"
				if [ \( "$DEF" = "D__STDC__" \) -o \
				     \( "$DEF" = "D_POSIX_SOURCE" \) -o \
				     \( "$DEF" = "D_POSIX2_SOURCE" \) -o \
				     \( "$DEF" = "D_XOPEN_SOURCE" \) -o \
				     \( "$DEF" = "D_CLASSIC_TYPES" \) -o \
				     \( "$DEF" = "D_CLASSIC_ANSI_TYPES" \) -o \
				     \( "$DEF" = "D_CLASSIC_POSIX_TYPES" \) -o \
				     \( "$DEF" = "D_CLASSIC_XOPEN_TYPES" \) -o \
				     \( "$DEF" = "D_CLASSIC_ID_TYPES" \) ]
				then
					NAMESPACE=NONHPUX
				fi
				break;;
			l)	if [ "$OPT" ]
                                then
                                    LFN_SIZE=`echo "$OPT\c" | wc -c`
                                    if [ $LFN_SIZE -gt 5 ]
                                    then
                                      LFN_FNAME=llib-l$OPT.ln
                                      if [ -r $LLDIR/$LFN_FNAME ]
                                      then
                                        cat < $LLDIR/$LFN_FNAME >> $TOUT_FILES
                                      else
                                        LFN_FNAME=`expr substr $LFN_FNAME 0 14`
                                        if [ -r $LLDIR/$LFN_FNAME ]
                                        then
                                          cat < $LLDIR/$LFN_FNAME >> $TOUT_FILES
                                        else
                                          echo  "l$OPT  $MSG04"
                                        fi
                                      fi
                                    else
                                      cat < $LLDIR/llib-l$OPT.ln >> $TOUT_FILES
                                    fi
                                else
                                        optarg=FILES
                                        pre=$LLDIR/llib-l
                                        post=.ln
				fi
				break;;
			o)	if [ "$OPT" ]
				then
					OPT=`basename $OPT`
					LLIB="llib-l$OPT.ln"
				else
					LLIB=
					optarg=LLIB
					pre=llib-l
					post=.ln
				fi
				break;;
			*)	echo $MSG02 
                                echo "			$O";;
			esac
		done;;
	*)	echo $MSG03 
		echo "			$OPT" ;;
	esac
done
#
# Second, walk through the FILES list, running all .c's through
# lint's first pass, and just adding all .ln's to the running result
#
if [ "$MODE" != "ANSI" ]  # avoid polluting ANSI namespace
then
	CCF="$CCF -Dlint"
else
         CCF=`echo $CCF |  sed s/-Wp,-T//p`
fi
if [ "$NDOTC" != "x" ]	# note how many *.c's there were
then
	NDOTC=1
else
	NDOTC=
fi
if [ "$CONLY" ]		# run lint1 on *.c's only producing *.ln's
then
	for i in $FILES
	do
		case $i in
		*.c)	T=`basename $i .c`.ln
			if [ "$NDOTC" ]
			then
				echo $i:
			fi
			($CC_CMD $CCF $i > $CPPOUT &&     \
			 $LINT1 $CPPOUT $NULLF $TMP $ANSIOPT $CCOMOPT$L1OPTS ) 2>&1
			if [ $? -eq  0 ]
			then
			   cat $TMP > $T
			else
			   EXIT_STATUS=1	
			fi	
			rm -f $TMP
		esac
	done
else			# send all *.c's through lint1 run all through lint2
	rm -f $TOUT $HOUT
# Append lint system libraries to TOUT file. This will take care file name
# truncation problems in LFN & 14 char file name systems. 

        if [ -r $TOUT_FILES ]
        then
            cat < $TOUT_FILES >>$TOUT
            rm -f $TOUT_FILES
        fi

	for i in $FILES
	do
		case $i in
		*.ln)	cat <$i >>$TOUT;;
		*.c)	if [ "$NDOTC" ]
			then
				echo $i:
			fi
			($CC_CMD $CCF $i > $CPPOUT &&     \
			 $LINT1 $CPPOUT $NULLF $TMP $ANSIOPT $CCOMOPT$L1OPTS )2>&1
			if [ $? -eq  0 ]
			then
			   cat $TMP >> $TOUT
			else
			   EXIT_STATUS=1
			fi
			rm -f $TMP;;
		esac
	done
	if [ "$LLIB" ] && [ $EXIT_STATUS -eq 0 ]
	then
		cp $TOUT $LLIB
	fi
	if [ "$DEFL" ]
	then
		if [ "$NAMESPACE" -a "$DEFL"="$LLDIR/llib-lc.ln" ]
		then
			if [ -f /usr/include/nfs/nfs.h ]
			then
				CCF="$CCF -DNFS"
			fi
			if [ -f /usr/include/netdb.h ]
			then
				CCF="$CCF -D_LANLINK"
			fi
			if [ -f /usr/include/netinet/in.h ]
			then
				CCF="$CCF -D_LANBLD"
			fi
			($CC_CMD $CCF $LLDIR/lint/llib-lc > $CPPOUT && \
			$LINT1 $CPPOUT $NULLF $TMP $ANSIOPT $CCOMOPT$L1OPTS) 2>&1
			if [ $? -eq  0 ]
			then
			   cat $TMP >> $TOUT
			else
			   EXIT_STATUS=1	
			fi
			rm $TMP
		else
			cat <$DEFL >>$TOUT
		fi
	fi
	if [ -s "$TOUT" ]
	then
		if [ -s "$HOUT" ]
		then
			$LDIR/lint2 $LINT2F -T$TOUT -H$HOUT $LINTF
		else
			$LDIR/lint2 $LINT2F -T$TOUT $LINTF
		fi
		if [ $? -ne 0 ]
		then
		  EXIT_STATUS=1
		fi
	fi
fi
rm -f $TOUT $HOUT $CPPOUT
exit $EXIT_STATUS
