⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 3 页
字号:
## include "stdio.h"/* C command/* written by John F. Reiser/* July/August 1978*/#define STATIC#define STDIN 0#define STDOUT 1#define STDERR 2#define READ 0#define WRITE 1#define SALT '#'#ifndef BUFSIZ#define BUFSIZ 512#endifchar *pbeg,*pbuf,*pend;char *outp,*inp;char *newp;char cinit;/* some code depends on whether characters are sign or zero extended *//*	#if '\377' < 0		not used here, old cpp doesn't understand */#if pdp11 | vax#define COFF 128#else#define COFF 0#endif# if gcos#define ALFSIZ 512	/* alphabet size */# else#define ALFSIZ 256	/* alphabet size */# endifchar macbit[ALFSIZ+11];char toktyp[ALFSIZ];#define BLANK 1#define IDENT 2#define NUMBR 3/* a superimposed code is used to reduce the number of calls to the/* symbol table lookup routine.  (if the kth character of an identifier/* is 'a' and there are no macro names whose kth character is 'a'/* then the identifier cannot be a macro name, hence there is no need/* to look in the symbol table.)  'scw1' enables the test based on/* single characters and their position in the identifier.  'scw2'/* enables the test based on adjacent pairs of characters and their/* position in the identifier.  scw1 typically costs 1 indexed fetch,/* an AND, and a jump per character of identifier, until the identifier/* is known as a non-macro name or until the end of the identifier./* scw1 is inexpensive.  scw2 typically costs 4 indexed fetches,/* an add, an AND, and a jump per character of identifier, but it is also/* slightly more effective at reducing symbol table searches./* scw2 usually costs too much because the symbol table search is/* usually short; but if symbol table search should become expensive,/* the code is here./* using both scw1 and scw2 is of dubious value.*/#define scw1 1#define scw2 0#if scw2char t21[ALFSIZ],t22[ALFSIZ],t23[ALFSIZ+8];#endif#if scw1#define b0 1#define b1 2#define b2 4#define b3 8#define b4 16#define b5 32#define b6 64#define b7 128#endif#define IB 1#define SB 2#define NB 4#define CB 8#define QB 16#define WB 32char fastab[ALFSIZ];char slotab[ALFSIZ];char *ptrtab;#define isslo (ptrtab==(slotab+COFF))#define isid(a)  ((fastab+COFF)[a]&IB)#define isspc(a) (ptrtab[a]&SB)#define isnum(a) ((fastab+COFF)[a]&NB)#define iscom(a) ((fastab+COFF)[a]&CB)#define isquo(a) ((fastab+COFF)[a]&QB)#define iswarn(a) ((fastab+COFF)[a]&WB)#define eob(a) ((a)>=pend)#define bob(a) (pbeg>=(a))char buffer[8+BUFSIZ+BUFSIZ+8];# define SBSIZE 12000char	sbf[SBSIZE];char	*savch	= sbf;# define DROP 0xFE	/* special character not legal ASCII or EBCDIC */# define WARN DROP# define SAME 0# define MAXINC 10# define MAXFRE 14	/* max buffers of macro pushback */# define MAXFRM 31	/* max number of formals/actuals to a macro */static char warnc = WARN;int mactop,fretop;char *instack[MAXFRE],*bufstack[MAXFRE],*endbuf[MAXFRE];int plvl;	/* parenthesis level during scan for macro actuals */int maclin;	/* line number of macro call requiring actuals */char *macfil;	/* file name of macro call requiring actuals */char *macnam;	/* name of macro requiring actuals */int maclvl;	/* # calls since last decrease in nesting level */char *macforw;	/* pointer which must be exceeded to decrease nesting level */int macdam;	/* offset to macforw due to buffer shifting */#if tgpint tgpscan;	/* flag for dump(); */#endifSTATIC	int	inctop[MAXINC];STATIC	char	*fnames[MAXINC];STATIC	char	*dirnams[MAXINC];	/* actual directory of #include files */STATIC	int	fins[MAXINC];STATIC	int	lineno[MAXINC];STATIC	char	*dirs[10];	/* -I and <> directories */char *strdex(), *copy(), *subst(), *trmdir();struct symtab *stsym();STATIC	int	fin	= STDIN;STATIC	FILE	*fout	= stdout;STATIC	int	nd	= 1;STATIC	int	pflag;	/* don't put out lines "# 12 foo.c" */STATIC	int	passcom;	/* don't delete comments */STATIC	int rflag;	/* allow macro recursion */STATIC	int	ifno;# define NPREDEF 20STATIC	char *prespc[NPREDEF];STATIC	char **predef = prespc;STATIC	char *punspc[NPREDEF];STATIC	char **prund = punspc;STATIC	int	exfail;struct symtab {	char	*name;	char	*value;} *lastsym, *lookup(), *slookup();# if gcos#include <setjmp.h>static jmp_buf env;# define main	mainpp# undef exit# define exit(S)	longjmp(env, 1)# define open(S,D)	fileno(fopen(S, "r"))# define close(F)	fclose(_f[F])extern FILE *_f[];# define symsiz 500# else# define symsiz 400# endifSTATIC	struct symtab stab[symsiz];STATIC	struct symtab *defloc;STATIC	struct symtab *udfloc;STATIC	struct symtab *incloc;STATIC	struct symtab *ifloc;STATIC	struct symtab *elsloc;STATIC	struct symtab *eifloc;STATIC	struct symtab *ifdloc;STATIC	struct symtab *ifnloc;STATIC	struct symtab *ysysloc;STATIC	struct symtab *varloc;STATIC	struct symtab *lneloc;STATIC	struct symtab *ulnloc;STATIC	struct symtab *uflloc;STATIC	int	trulvl;STATIC	int	flslvl;sayline() {	if (pflag==0) fprintf(fout,"# %d \"%s\"\n", lineno[ifno], fnames[ifno]);}/* data structure guide/*/* most of the scanning takes place in the buffer:/*/*  (low address)                                             (high address)/*  pbeg                           pbuf                                 pend/*  |      <-- BUFSIZ chars -->      |         <-- BUFSIZ chars -->        |/*  _______________________________________________________________________/* |_______________________________________________________________________|/*          |               |               |/*          |<-- waiting -->|               |<-- waiting -->/*          |    to be      |<-- current -->|    to be/*          |    written    |    token      |    scanned/*          |               |               |/*          outp            inp             p/*/*  *outp   first char not yet written to output file/*  *inp    first char of current token/*  *p      first char not yet scanned/*/* macro expansion: write from *outp to *inp (chars waiting to be written),/* ignore from *inp to *p (chars of the macro call), place generated/* characters in front of *p (in reverse order), update pointers,/* resume scanning./*/* symbol table pointers point to just beyond the end of macro definitions;/* the first preceding character is the number of formal parameters./* the appearance of a formal in the body of a definition is marked by/* 2 chars: the char WARN, and a char containing the parameter number./* the first char of a definition is preceded by a zero character./*/* when macro expansion attempts to back up over the beginning of the/* buffer, some characters preceding *pend are saved in a side buffer,/* the address of the side buffer is put on 'instack', and the rest/* of the main buffer is moved to the right.  the end of the saved buffer/* is kept in 'endbuf' since there may be nulls in the saved buffer./*/* similar action is taken when an 'include' statement is processed,/* except that the main buffer must be completely emptied.  the array/* element 'inctop[ifno]' records the last side buffer saved when/* file 'ifno' was included.  these buffers remain dormant while/* the file is being read, and are reactivated at end-of-file./*/* instack[0 : mactop] holds the addresses of all pending side buffers./* instack[inctop[ifno]+1 : mactop-1] holds the addresses of the side/* buffers which are "live"; the side buffers instack[0 : inctop[ifno]]/* are dormant, waiting for end-of-file on the current file./*/* space for side buffers is obtained from 'savch' and is never returned./* bufstack[0:fretop-1] holds addresses of side buffers which/* are available for use.*/dump() {/* write part of buffer which lies between  outp  and  inp ./* this should be a direct call to 'write', but the system slows to a crawl/* if it has to do an unaligned copy.  thus we buffer.  this silly loop/* is 15% of the total time, thus even the 'putc' macro is too slow.*/	register char *p1,*p2; register FILE *f;	if ((p1=outp)==inp || flslvl!=0) return;#if tgp#define MAXOUT 80	if (!tgpscan) {/* scan again to insure <= MAXOUT chars between linefeeds */		register char c,*pblank; char savc,stopc,brk;		tgpscan=1; brk=stopc=pblank=0; p2=inp; savc= *p2; *p2='\0';		while (c= *p1++) {			if (c=='\\') c= *p1++;			if (stopc==c) stopc=0;			else if (c=='"' || c=='\'') stopc=c;			if (p1-outp>MAXOUT && pblank!=0) {				*pblank++='\n'; inp=pblank; dump(); brk=1; pblank=0;			}			if (c==' ' && stopc==0) pblank=p1-1;		}		if (brk) sayline();		*p2=savc; inp=p2; p1=outp; tgpscan=0;	}#endif	f=fout;# if gcos/* filter out "$ program c" card if first line of input *//* gmatch is a simple pattern matcher in the GCOS Standard Library */{	static int gmfirst = 0;	if (!gmfirst) {		++gmfirst;		if (gmatch(p1, "^$*program[ \t]*c*"))			p1 = strdex(p1, '\n');	}}# endif	while (p1<inp) putc(*p1++,f);	outp=p1;}char *refill(p) register char *p; {/* dump buffer.  save chars from inp to p.  read into buffer at pbuf,/* contiguous with p.  update pointers, return new p.*/	register char *np,*op; register int ninbuf;	dump(); np=pbuf-(p-inp); op=inp;	if (bob(np+1)) {pperror("token too long"); np=pbeg; p=inp+BUFSIZ;}	macdam += np-inp; outp=inp=np;	while (op<p) *np++= *op++;	p=np;	for (;;) {		if (mactop>inctop[ifno]) {/* retrieve hunk of pushed-back macro text */			op=instack[--mactop]; np=pbuf;			do {while (*np++= *op++);} while (op<endbuf[mactop]); pend=np-1;			/* make buffer space avail for 'include' processing */			if (fretop<MAXFRE) bufstack[fretop++]=instack[mactop];			return(p);		} else {/* get more text from file(s) */			maclvl=0;			if (0<(ninbuf=read(fin,pbuf,BUFSIZ))) {				pend=pbuf+ninbuf; *pend='\0';				return(p);			}			/* end of #include file */			if (ifno==0) {/* end of input */				if (plvl!=0) {					int n=plvl,tlin=lineno[ifno]; char *tfil=fnames[ifno];					lineno[ifno]=maclin; fnames[ifno]=macfil;					pperror("%s: unterminated macro call",macnam);					lineno[ifno]=tlin; fnames[ifno]=tfil;					np=p; *np++='\n';	/* shut off unterminated quoted string */					while (--n>=0) *np++=')';	/* supply missing parens */					pend=np; *np='\0'; if (plvl<0) plvl=0;					return(p);				}				inp=p; dump(); exit(exfail);			}			close(fin); fin=fins[--ifno]; dirs[0]=dirnams[ifno]; sayline();		}	}}#define BEG 0#define LF 1char *cotoken(p) register char *p; {	register int c,i; char quoc;	static int state = BEG;	if (state!=BEG) goto prevlf;for (;;) {again:	while (!isspc(*p++));	switch (*(inp=p-1)) {	case 0: {		if (eob(--p)) {p=refill(p); goto again;}		else ++p; /* ignore null byte */	} break;	case '|': case '&': for (;;) {/* sloscan only */		if (*p++== *inp) break;		if (eob(--p)) p=refill(p);		else break;	} break;	case '=': case '!': for (;;) {/* sloscan only */		if (*p++=='=') break;		if (eob(--p)) p=refill(p);		else break;	} break;	case '<': case '>': for (;;) {/* sloscan only */		if (*p++=='=' || p[-2]==p[-1]) break;		if (eob(--p)) p=refill(p);		else break;	} break;	case '\\': for (;;) {		if (*p++=='\n') {++lineno[ifno]; break;}		if (eob(--p)) p=refill(p);		else {++p; break;}	} break;	case '/': for (;;) {		if (*p++=='*') {/* comment */			if (!passcom) {inp=p-2; dump(); ++flslvl;}			for (;;) {				while (!iscom(*p++));				if (p[-1]=='*') for (;;) {					if (*p++=='/') goto endcom;					if (eob(--p)) {						if (!passcom) {inp=p; p=refill(p);}						else if ((p-inp)>=BUFSIZ) {/* split long comment */							inp=p; p=refill(p);	/* last char written is '*' */							putc('/',fout);	/* terminate first part */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -