Path: utzoo!censor!isgtec!robert From: robert@isgtec.UUCP (Robert Osborne) Newsgroups: comp.windows.x Subject: Imake with both ANSI and K&R cpp Message-ID: <943@isgtec.UUCP> Date: 27 Mar 91 19:03:06 GMT Sender: news@isgtec.UUCP Reply-To: robert@isgtec.UUCP Organization: IAP Group, ISG Technologies Lines: 236 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