[comp.windows.x] Imake with both ANSI and K&R cpp

robert@isgtec.UUCP (Robert Osborne) (03/28/91)

At ISG we are currently using imake (the one that came with R4) for
internal projects as well as for X.  The big snag was supporting many
cpp's, both ANSI & K&R, and having the rules files work across all of
them.  The solution I finally hit upon (after giving up completely on
the cpp that comes with the X11 source :-)  was to use %% as the
tokenizing string rather than /**/.  This works since %% (like @@)
passes through all our cpp's untouched.

I modified the CleanCppInput function to prefix make comments with
%% and change /**/ to %%.  In the CleanCppOutput I strip out %% and
change @@ to newlines as before.  I then changed all the rules files
by passing them through the sed program

	 	sed -e "s#/**/#%%#"

This should work for all possible input 'Imakefile's.  We've been
running this modified Imake for almost a month with no problems so I
assume it's safe for the rest of the world (NO CLAIMS TO FITNESS FOR
blah blah ... :-).

If anybody else is supporting X11 (or home brewed imake) across the different
types of cpp's here is the patch to imake.c:

Rob.
------------------------ cut here ---------------------------------
#!/bin/sh
# This is a shell archive (shar 3.32)
# made 03/27/1991 19:03 UTC by robert@peabody
# Source directory /tmp_mnt/home/joker1/robert/tmp
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   4111 -rw-rw-r-- imake.patch
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= imake.patch ==============
echo "x - extracting imake.patch (Text)"
sed 's/^X//' << 'SHAR_EOF' > imake.patch &&
Xdiff -c -r1.1 imake.c
X*** 1.1	1990/10/05 11:36:31
X--- imake.c	1991/03/27 18:28:31
X***************
X*** 506,511 ****
X--- 506,517 ----
X  	}
X  }
X  
X+ /*
X+ **  change '/'**'/' lines to %%
X+ **		This allows '/'**'/' to be used to catenate under all cpps
X+ **	change \n# to \n%%#
X+ **		This prevents cpp's from choking on # in first column
X+ */
X  char *CleanCppInput(Imakefile)
X  	char	*Imakefile;
X  {
X***************
X*** 534,540 ****
X  
X  	punwritten = pbuf = buf;
X  	while (*pbuf) {
X! 	    /* pad make comments for cpp */
X  	    if (*pbuf == '#' && (pbuf == buf || pbuf[-1] == '\n')) {
X  
X  		ptoken = pbuf+1;
X--- 540,546 ----
X  
X  	punwritten = pbuf = buf;
X  	while (*pbuf) {
X! 	    /* is pbuf the start of a Make comment */
X  	    if (*pbuf == '#' && (pbuf == buf || pbuf[-1] == '\n')) {
X  
X  		ptoken = pbuf+1;
X***************
X*** 562,572 ****
X  				tmpImakefile);
X  		    }
X  		    fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile);
X! 		    fputs("/**/", outFile);
X  		    punwritten = pbuf;
X  		}
X  		*pend = savec;
X  	    }
X  	    pbuf++;
X  	}
X  	if (outFile) {
X--- 568,594 ----
X  				tmpImakefile);
X  		    }
X  		    fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile);
X! 		    fputs("%%", outFile);
X  		    punwritten = pbuf;
X  		}
X  		*pend = savec;
X  	    }
X+ 	    /* pbuf starts a empty comment */
X+ 	    if( *pbuf == '/' && *(pbuf+1) == '*' &&
X+ 		*(pbuf+2) == '*' && *(pbuf+3) == '/' ) {
X+ 		if (outFile == NULL) {
X+ 		    tmpImakefile = mktemp(strdup(tmpImakefile));
X+ 		    cleanedImakefile = tmpImakefile;
X+ 		    outFile = fopen(tmpImakefile, "w");
X+ 		    if (outFile == NULL)
X+ 			LogFatal("Cannot open %s for write.\n",
X+ 			    tmpImakefile);
X+ 		}
X+ 		fwrite(punwritten, sizeof(char), pbuf-punwritten, outFile);
X+ 		fputs("%%", outFile);
X+ 		pbuf += 4;
X+ 		punwritten = pbuf;
X+ 	    }
X  	    pbuf++;
X  	}
X  	if (outFile) {
X***************
X*** 577,582 ****
X--- 599,610 ----
X  	return(cleanedImakefile);
X  }
X  
X+ /*
X+ **  Does the following to the output from cpp:
X+ **	change %% to nothing
X+ **	change @@ to newlines
X+ **	correct the whitespace for Makes tabs
X+ */
X  CleanCppOutput(tmpfd, tmpfname)
X  	FILE	*tmpfd;
X  	char	*tmpfname;
X***************
X*** 654,661 ****
X  	char	*tmpfname;
X  {
X  	static boolean	initialized = FALSE;
X! 	static char	*buf, *pline, *end;
X! 	char	*p1, *p2;
X  
X  	if (! initialized) {
X  		int	total_red;
X--- 682,689 ----
X  	char	*tmpfname;
X  {
X  	static boolean	initialized = FALSE;
X! 	static char	*buf, *p, *end, cleaned[1024];
X! 	char *p2 = cleaned;
X  
X  	if (! initialized) {
X  		int	total_red;
X***************
X*** 666,672 ****
X  		 */
X  		fseek(tmpfd, 0, 0);
X  		fstat(fileno(tmpfd), &st);
X! 		pline = buf = Emalloc(st.st_size+1);
X  		total_red = read(fileno(tmpfd), buf, st.st_size);
X  		if (total_red != st.st_size)
X  			LogFatal("cannot read %s\n", tmpMakefile);
X--- 694,700 ----
X  		 */
X  		fseek(tmpfd, 0, 0);
X  		fstat(fileno(tmpfd), &st);
X! 		p = buf = Emalloc(st.st_size+1);
X  		total_red = read(fileno(tmpfd), buf, st.st_size);
X  		if (total_red != st.st_size)
X  			LogFatal("cannot read %s\n", tmpMakefile);
X***************
X*** 701,724 ****
X  #endif /* FIXUP_CPP_WHITESPACE */
X  	}
X  
X! 	for (p1 = pline; p1 < end; p1++) {
X! 		if (*p1 == '@' && *(p1+1) == '@') { /* soft EOL */
X! 			*p1++ = '\0';
X! 			p1++; /* skip over second @ */
X! 			break;
X  		}
X! 		else if (*p1 == '\n') { /* real EOL */
X! 			*p1++ = '\0';
X! 			break;
X  		}
X  	}
X! 
X! 	/*
X! 	 * return NULL at the end of the file.
X! 	 */
X! 	p2 = (pline == p1 ? NULL : pline);
X! 	pline = p1;
X! 	return(p2);
X  }
X  
X  writetmpfile(fd, buf, cnt)
X--- 729,755 ----
X  #endif /* FIXUP_CPP_WHITESPACE */
X  	}
X  
X! 	p2 = cleaned;
X! 	while( p < end ) {
X! 		if( *p == '%' && *(p+1) == '%') { /* null space! */
X! 			p += 2;
X! 			continue;
X  		}
X! 		else if( *p == '@' && *(p+1) == '@') { /* soft EOL */
X! 			*p2 = '\0';
X! 			/* skip over @@ */
X! 			p += 2;
X! 			return cleaned;
X  		}
X+ 		else if (*p == '\n') { /* real EOL */
X+ 			*p2 = '\0';
X+ 			p++;
X+ 			return cleaned;
X+ 		}
X+ 		*p2++ = *p++;
X  	}
X! 	*p2 = '\0';
X! 	return (p2 == cleaned) ? NULL : cleaned;
X  }
X  
X  writetmpfile(fd, buf, cnt)
SHAR_EOF
$TOUCH -am 0327140291 imake.patch &&
chmod 0664 imake.patch ||
echo "restore of imake.patch failed"
set `wc -c imake.patch`;Wc_c=$1
if test "$Wc_c" != "4111"; then
	echo original size 4111, current size $Wc_c
fi
exit 0
---
Robert A. Osborne   ...uunet!utai!lsuc!isgtec!robert or robert@isgtec.uucp

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (04/02/91)

> At ISG we are currently using imake (the one that came with R4) for
> internal projects as well as for X.  The big snag was supporting many
> cpp's, both ANSI & K&R, and having the rules files work across all of
> them.

I have a cpp I wrote, which I have placed in the public domain, that
comes close enough to Reiser semantics to keep imake happy.

Those of you with FTP access (which from the address I would guess does
not include the original poster) can get it from 132.206.1.1, in
X/XNeXT/ (file names with "cpp" in them); others can send me mail and
I'll be glad to mail you a copy.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu