[comp.unix.xenix] Program cci, fixes problems with cc

erskine@force10.UUCP (Neil Erskine) (01/28/88)

][b
	Have you ever cursed the fact that once in a while you have
    a large program with one file that generates the infamous 
    'out of heap space' message from the preprocessor? Tired of putting
    up with slow compiles because you always use the LARGE passes even
    when unnecessary? Or do you have to contort you makefiles to compensate
    for cc's brain damage? If so, here is a program that should take care of
    -LARGE for you. Too bad SCO didn't hack cc to do this in the first place.

    To compile:
	Save the following progam into the file cci.c
	Compile it with cc -O -lx cci.c -o cci

    To install:
	Place the file 'cci' resulting from the compile in a directory
    that gets searched when using 'make'.

    To use:
	Place the line
		CC = cci
	at the top of your make file. If you have hard coded the name of
	the compiler into a rule somewhere, replace cc with $(CC) wherever
	it occurs in your makefile.

    Type make. If an out of heap space message is printed, cci will rerun
    the compile with the -LARGE parameter.

    If you don't use 'make', just use cci instead of cc.

    Limitations:
	I only put in checking for the out of memory message from the pre-
    processor because that's the only pass I have problems with. The message
    about the optimizer not coping is not trapped by cci (essentially leaving
    the code non-optimized). Feel free to modify the code, or pass it on.
    I've never got the code generator or parser to barf through lack of memory
    so I'm not worrying at all about that.
	If the optimizer is your only concern, set the environment variable
    CCI_TRIGGER to the error message produced by the optimizer that you want
    to trigger use of the large passes.

    Relax. Enjoy. Bug reports (or extensions) to

	dalcs!force10!erskine

||!][b

--------------
Neil S. Erskine		MT&T - (902) 453-4915
AP Computers 		USENET { garfield, watmath, ihnp4!utzoo!utai,
3845 Dutch Village Rd.		 uunet } !dalcs!force10!erskine
Halifax, N.S. B3L-4H9

------------------ Cut here. Save to cci.c -----------------
#include <stdio.h>

#define CCI_TRIGGER "CCI_TRIGGER"
#define DEFAULT_TRIGGER "out of heap space"

main(argc, argv)
int argc;
char *argv[];
{
    FILE *cc_error;
    extern int errno;
    FILE *fdopen();
    int heap_error;
    char *getenv();
    int p[2];
    int pid;
    char *regcmp(), *regex();
    int status;
    char *trigger;
    char workbuf[256];

    if (pipe (p)) {
	fprintf (stderr, "cci: Gaak! Couldn't make pipes, errno = %d\n", errno);
	exit(1);
    }

    pid = fork();
    if (pid < 0) {
	fprintf (stderr, "cci: Gaak! Couldn't fork, ernro = %d\n", errno);
	exit(2);
    }

    if (pid == 0) {	/* Child process */
	dup2 (p[1], 2);		/* Redirect standard error through pipe */
	close (p[0]);		/* Don't need to read this */
	close (p[1]);		/* This is now attached to stderr */
	argv[0] = "cc";		/* Alter cc calling sequence */
	execv ("/bin/cc", argv);	/* Do it */
	sprintf (workbuf,
		 "cci: Gaak! Couldn't exec /bin/cc, ernro = %d\n", errno);
	write (2, workbuf, strlen (workbuf));
	exit(3);
    }

    close (p[1]);	/* Used by child process */
    cc_error = fdopen (p[0], "r");	/* Attach pipe to a stream */
    if (cc_error == 0) {
	fprintf (stderr, "cci: Gaak! Couldn't fdopen, errno = %d\n", errno);
	fprintf (stderr, "     Any error messages will be lost\n");
	close (p[0]);	/* Make child get a pipe error if it writes */
	wait (&status);
	fprintf (stderr, "     cc exit value was %d. Goodbye\n", status);
	exit(status);
    }

    trigger = getenv(CCI_TRIGGER);
    if (trigger == 0 || strlen(trigger) == 0)
	trigger = DEFAULT_TRIGGER;
    trigger = regcmp (trigger, (char *) 0);
    heap_error = 0;
    while (fgets(workbuf, sizeof(workbuf) - 1, cc_error) != NULL) {
	fputs (workbuf, stderr);
	if (regex (trigger, workbuf))
	    heap_error = 1;
    }
    wait (&status);

    if (status && heap_error) {	 /* cc failed because heap was exhausted */
	char *nargv[256];
	char **c = nargv;
	char **c2 = argv;

	/* First, create a diddled argv adding the -LARGE parameter */
	*c++ = "cc";
	*c = "-LARGE";
	do {
	    *++c = *++c2;
	} while (*c2 != 0);	/* Copy ending with the null */

	/* Now try the exec */
	fprintf (stderr, "cci: Trying cc again with the -LARGE parameter\n");
	fflush (stderr);
	execv ("/bin/cc", nargv);	/* Do it with LARGE passes */
	fprintf (stderr,
		 "cci: Gaak! Couldn't re-exec /bin/cc, ernro = %d\n", errno);
	exit(4);
    }

    exit (status);	/* Normal error or success */
}
-- 
Neil S. Erskine		MT&T - (902) 453-4915 x340
AP Computers 		USENET { garfield, watmath, ihnp4!utzoo!utai,
3845 Dutch Village Rd.		 uunet } !dalcs!force10!erskine
Halifax, N.S. B3L-4H9