
# @(#) $Revision: 4.10 $

# APPLY SPECIAL PREPROCESSING TO JUDY COMPILATIONS
#
# Pass the name of this script to the makefile.  In turn it calls this script
# with a compilation command line.  This script modifies the line to preprocess
# the source file before compiling it, to make it easier to detect compile
# errors and/or run a debugger on the result.
#
# There must be exactly one *.c filename on the command line and exactly one
# *.o filename.  The *.c filename is created as a preprocessed file under the
# path to the *.o file, and then the latter is built from it.


# USAGE MESSAGE:

	if [[ ($# = 0) || (x${1--?} = x-?) ]]
	then
	    echo >&2 "Usage: $0 compilation command line\n" \
		     '(must contain exactly one *.c and one *.o)'
	    exit 1
	fi


# PREPARE COMMANDS:

	case "${PLATFORM-}" in

	linux_ia32 | \
	linux_ipf) CB='indent';	SHELL='ksh' ;;	# use indent, but require ksh.
	win_ipf)   CB='cat';	SHELL='sh'  ;;	# do without cb; and no ksh.
	*)	   CB='cb';	SHELL='ksh' ;;

	esac

	if [[ "${PLATFORM-}" = linux_ia32 || "${PLATFORM-}" = linux_ipf ]]
	then BACKS='\\'			# Linux awk complains without this.
	else BACKS='\'
	fi

	echo $@ | awk '{

# Study the command line field-by-field and note the sourcefile and objectfile
# name fields:

	    for (field = 1; field <= NF; ++field)
	    {
		if ($field ~ /\.c$/)	# record source file field number:
		{
		    if (srcfield)	# not first one.
		    {
			print "echo '"$0"': must be only one sourcefile name", \
			      "on command line";
			exit;
		    }
		    srcfield = field;
		    continue;
		}

		if ($field ~ /\.o$/)	# record object file field number:
		{
		    if (objfield)	# not first one.
		    {
			print "echo '"$0"': must be only one objectfile name", \
			      "on command line";
			exit;
		    }
		    objfield = field;
		    continue;
		}
	    } # for.

	    if (! srcfield)		# did not find one.
	    {
		print "echo '"$0"': must be one sourcefile name on command", \
		      "line";
		exit;
	    }

	    if (! objfield)		# did not find one.
	    {
		print "echo '"$0"': must be one objectfile name on command", \
		      "line";
		exit;
	    }

# Build new sourcefile path:

	    srcbase = $srcfield;
	    gsub(".*/",  "",	      srcbase);	# basename part.
	     sub("'"$BACKS"'.c$", "", srcbase);	# less suffix.

# Note:  $objfield might have a "-[F]o" option in front of it due to Win32
# cl.exe requiring single opt/arg; if so, remove that:

	    objbase = $objfield;
	    gsub(".*/",  "",	      objbase);	# basename part.
	     sub("'"$BACKS"'.o$", "", objbase);	# less suffix.
	     sub("^-o",  "",	      objbase);	# less prefix if any.
	     sub("^-Fo", "",	      objbase);	# less prefix if any.

# Build a long, fully qualified srcbase for safety:

	    srcbase = srcbase "_" objbase "_pre.c";

	    objpath = $objfield;
	    sub("^-o",    "", objpath);		# less prefix if any.
	    sub("^-Fo",   "", objpath);		# less prefix if any.
	    sub("[^/]*$", "", objpath);		# directory part.
	    srcnew = objpath srcbase;

# Finally, some compilers get ill if you combine -o and -E, so remove the -o
# option and the object file name for the -E output command, but first prepare
# a modified copy of the command line for the second output line:

	    srcold    = $srcfield;
	    $srcfield = srcnew;
	    cmd2      = $0;
	    $srcfield = srcold;

	    $objfield = "";

	    if ((objfield > 1) \
	     && (($(objfield - 1) == "-o") || (($(objfield - 1) == "-Fo"))))
	    {
		$(objfield - 1) = "";
	    }

# Emit modified command lines:
#
# For the first line, emit the modified command line and then append a -E
# option and some post-processing to srcnew:
#
# Delete original line number directives, then "fold" long lines.
#
# Note:  Cannot fold using fold(1), even with -w or -s, because quoted strings
# in assertions are folded, and that breaks compilation, so instead fold using
# cb(1).  (Wow, an actual use of cb!)

	    printf("%s -E |\n", $0);
	    printf("grep -v -e '\''^#line'\'' -e '\''^# [1-9]'\'' |\n");
	    printf("'$CB' > %s\n", srcnew);
	    print cmd2;
	}' |

	$SHELL				# execute the revised commands.
