[mod.sources] v07i023: #elif patch to 4.3BSD cpp

sources-request@mirror.UUCP (09/11/86)

Submitted by: linus!gatech!emoryu1!emoryu2!arnold (Arnold D. Robbins)
Mod.sources: Volume 7, Issue 23
Archive-name: 4.3cpp.patch

[  This is a modification of the V6#44 cpp.patch for 4.3BSD.  --r$  ]

Basically, with these patches are installed, /lib/cpp gains two new
capabilities: The #elif found in recent versions of System V and in the
draft ANSI standard, and the ability to recognize C++ // comments,
which start with the // delimiter, and go to the end of the line.

#elif is automatic: it is fast becoming a standard C feature, and I
feel that everyone would want it. // comments require that the new -B
option be given, for their recognition to be turned on. Sites with C++
should modify their CC shell script to call /lib/cpp with this option.
(I chose -B as sort of mnemonic for the BCPL programming language, from
which // was re-instituted.)

Credits: Doug Gwyn of BRL implemented #elif for his System V emulation;
however I typed it in to make the "style" consistent; all typos are
mine. I wrote the // processing code. Enjoy.

Unpack this file and feed it to patch while in a cpp source directory,
then run make / "make install".

--------------------CUT HERE--------------------
*** cpp.c.orig	Mon Aug 11 17:58:06 1986
--- cpp.c	Mon Aug 11 17:50:28 1986
***************
*** 1,4 ****
--- 1,24 ----
  #ifndef lint
+ static char *RCSid = "$Header: cpp.c,v 1.3 86/08/11 17:49:38 root Locked $";
+ #endif
+ 
+ /*
+  * $Log:	cpp.c,v $
+  * Revision 1.3  86/08/11  17:49:38  root
+  * Bug fix to #elif stuff due to a typo. Fixed new code to call sayline()
+  * with an argument. ADR.
+  * 
+  * Revision 1.2  86/08/07  17:55:56  root
+  * Added Doug Gwyn's code to handle #elif. This is always on. Also
+  * added my code that takes a -B option, to recognize C++ // ... \n
+  * style of comments. ADR.
+  * 
+  * Revision 1.1  86/08/07  16:15:52  root
+  * Initial revision
+  * 
+  */
+ 
+ #ifndef lint
  static char sccsid[] = "@(#)cpp.c	1.14 4/27/86";
  #endif lint
  
***************
*** 153,158 ****
--- 173,179 ----
  STATIC	int	nd	= 1;
  STATIC	int	pflag;	/* don't put out lines "# 12 foo.c" */
  int	passcom;	/* don't delete comments */
+ int	eolcom;		/* allow // ... \n comments */
  int	incomment;	/* True if parsing a comment */
  STATIC	int rflag;	/* allow macro recursion */
  STATIC	int mflag;	/* generate makefile dependencies */
***************
*** 192,197 ****
--- 213,219 ----
  STATIC	struct symtab *udfloc;
  STATIC	struct symtab *incloc;
  STATIC	struct symtab *ifloc;
+ STATIC	struct symtab *eliloc;		/* DAG -- added */
  STATIC	struct symtab *elsloc;
  STATIC	struct symtab *eifloc;
  STATIC	struct symtab *ifdloc;
***************
*** 204,209 ****
--- 226,233 ----
  STATIC	struct symtab *identloc;	/* Sys 5r3 compatibility */
  STATIC	int	trulvl;
  STATIC	int	flslvl;
+ #define MAX_IF_NESTING	64		/* DAG -- added (must be at least6) */
+ STATIC	int	ifdone[MAX_IF_NESTING];	/* DAG -- added */
  
  sayline(where)
  	int where;
***************
*** 393,402 ****
  		else {++p; break;}
  	} break;
  	case '/': for (;;) {
! 		if (*p++=='*') {/* comment */
  			incomment++;
  			if (!passcom) {inp=p-2; dump(); ++flslvl;}
  			for (;;) {
  				while (!iscom(*p++));
  				if (p[-1]=='*') for (;;) {
  					if (*p++=='/') goto endcom;
--- 417,448 ----
  		else {++p; break;}
  	} break;
  	case '/': for (;;) {
! 		if (*p=='/' && eolcom) {
! 			p++;
  			incomment++;
  			if (!passcom) {inp=p-2; dump(); ++flslvl;}
  			for (;;) {
+ 				while (*p && *p++ != '\n');
+ 				if (p[-1]=='\n') {
+ 					p--;
+ 					goto endcpluscom;
+ 				} else if (eob(--p)) {
+ 					if(!passcom) {inp=p; p=refill(p);}
+ 					else if ((p-inp) >= BUFSIZ) {/* split long comment */
+ 						inp=p; refill(p);
+ 					} else p=refill(p);
+ 				} else ++p; /* ignore null byte */
+ 			}
+ 		endcpluscom:
+ 			if (!passcom) {outp=inp=p; --flslvl;}
+ 			incomment--;
+ 			goto newline;
+ 			break;
+ 		}
+ 		else if (*p++=='*') {/* comment */
+ 			incomment++;
+ 			if (!passcom) {inp=p-2; dump(); ++flslvl;}
+ 			for (;;) {
  				while (!iscom(*p++));
  				if (p[-1]=='*') for (;;) {
  					if (*p++=='/') goto endcom;
***************
*** 446,451 ****
--- 492,498 ----
  		}
  	} break;
  	case '\n': {
+ newline:
  		++lineno[ifno]; if (isslo) {state=LF; return(p);}
  prevlf:
  		state=BEG;
***************
*** 746,752 ****
  #define fasscan() ptrtab=fastab+COFF
  #define sloscan() ptrtab=slotab+COFF
  
! char *
  control(p) register char *p; {/* find and handle preprocessor control lines */
  	register struct symtab *np;
  for (;;) {
--- 793,799 ----
  #define fasscan() ptrtab=fastab+COFF
  #define sloscan() ptrtab=slotab+COFF
  
! void	/* DAG -- bug fix (was (char *)) */
  control(p) register char *p; {/* find and handle preprocessor control lines */
  	register struct symtab *np;
  for (;;) {
***************
*** 759,777 ****
  		if (flslvl==0) {p=doincl(p); continue;}
  	} else if (np==ifnloc) {/* ifndef */
  		++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
! 		if (flslvl==0 && np->value==0) ++trulvl;
  		else ++flslvl;
  	} else if (np==ifdloc) {/* ifdef */
  		++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
! 		if (flslvl==0 && np->value!=0) ++trulvl;
  		else ++flslvl;
  	} else if (np==eifloc) {/* endif */
  		if (flslvl) {if (--flslvl==0) sayline(CONT);}
! 		else if (trulvl) --trulvl;
  		else pperror("If-less endif",0);
  	} else if (np==elsloc) {/* else */
  		if (flslvl) {
! 			if (--flslvl!=0) ++flslvl;
  			else {++trulvl; sayline(CONT);}
  		}
  		else if (trulvl) {++flslvl; --trulvl;}
--- 806,832 ----
  		if (flslvl==0) {p=doincl(p); continue;}
  	} else if (np==ifnloc) {/* ifndef */
  		++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
! 		if (flslvl==0)
! 			if(ifdone[trulvl] = np->value==0)
! 				++trulvl;
! 			else
! 				++flslvl;
  		else ++flslvl;
  	} else if (np==ifdloc) {/* ifdef */
  		++flslvl; p=skipbl(p); np=slookup(inp,p,0); --flslvl;
! 		if (flslvl==0)
! 			if (ifdone[trulvl] = np->value!=0)
! 				++trulvl;
! 			else
! 				++flslvl;
  		else ++flslvl;
  	} else if (np==eifloc) {/* endif */
  		if (flslvl) {if (--flslvl==0) sayline(CONT);}
! 		else if (trulvl) ifdone[--trulvl] = 0;	/* DAG */
  		else pperror("If-less endif",0);
  	} else if (np==elsloc) {/* else */
  		if (flslvl) {
! 			if (--flslvl!=0 || ifdone[trulvl]) ++flslvl;
  			else {++trulvl; sayline(CONT);}
  		}
  		else if (trulvl) {++flslvl; --trulvl;}
***************
*** 783,794 ****
  	} else if (np==ifloc) {/* if */
  #if tgp
  		pperror(" IF not implemented, true assumed", 0);
! 		if (flslvl==0) ++trulvl; else ++flslvl;
  #else
  		newp=p;
! 		if (flslvl==0 && yyparse()) ++trulvl; else ++flslvl;
  		p=newp;
  #endif
  	} else if (np==lneloc) {/* line */
  		if (flslvl==0 && pflag==0) {
  			char *savestring();
--- 838,897 ----
  	} else if (np==ifloc) {/* if */
  #if tgp
  		pperror(" IF not implemented, true assumed", 0);
! 		if (flslvl==0) ifdone[trulvl++] = 1; else ++flslvl;
  #else
  		newp=p;
! 		if (flslvl==0)
! 		{
! 			if (ifdone[trulvl] = yyparse())	/* DAG */
! 				++trulvl;
! 			else
! 				++flslvl;
! 		}
! 		else ++flslvl;
  		p=newp;
  #endif
+ 	} else if (np==eliloc) {/* elif */	/* DAG -- added */
+ #if tgp
+ 		pperror (" ELIF not implemented, true assumed", (char *) 0, (char *) 0);
+ 		if (flslvl)
+ 		{
+ 			if (--flslvl == 0 && !ifdone[trulvl])
+ 			{
+ 				ifdone[trulvl++] = 1;
+ 				sayline (CONT);
+ 			}
+ 			else
+ 				++flslvl;
+ 		}
+ 		else if (trulvl)
+ 		{
+ 			++flslvl;
+ 			--trulvl;
+ 		}
+ 		else
+ 			pperror ( "If-less elif", (char *) 0, (char *) 0);
+ #else
+ 		newp = p;
+ 		if (flslvl)
+ 		{
+ 			if (--flslvl == 0 && !ifdone[trulvl] && yyparse ())
+ 			{
+ 				ifdone[trulvl++] = 1;
+ 				sayline (CONT);
+ 			}
+ 			else
+ 				++flslvl;
+ 		}
+ 		else if (trulvl)
+ 		{
+ 			++flslvl;
+ 			--trulvl;
+ 		}
+ 		else
+ 			pperror ( "If-less elif", (char *) 0, (char *) 0);
+ 		p = newp;
+ #endif
  	} else if (np==lneloc) {/* line */
  		if (flslvl==0 && pflag==0) {
  			char *savestring();
***************
*** 1137,1142 ****
--- 1240,1246 ----
  				case 'E': continue;
  				case 'R': ++rflag; continue;
  				case 'C': passcom++; continue;
+ 				case 'B': eolcom++; continue;
  				case 'D':
  					if (predef>prespc+NPREDEF) {
  						pperror("too many -D options, ignoring %s",argv[i]);
***************
*** 1235,1240 ****
--- 1339,1345 ----
  	ifdloc=ppsym("ifdef");
  	ifnloc=ppsym("ifndef");
  	ifloc=ppsym("if");
+ 	eliloc=ppsym("elif");
  	lneloc=ppsym("line");
  	identloc=ppsym("ident");	/* Sys 5r3 compatibility */
  	for (i=sizeof(macbit)/sizeof(macbit[0]); --i>=0; ) macbit[i]=0;