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

📄 m4.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
/*	@(#)m4.c	4.2	ULTRIX	8/13/90	*//* Based on AT&T version:	*//*	@(#)m4.c	1.3	*/#include	<stdio.h>#include	<signal.h>#include	"m4.h"#define match(c,s)	(c==*s && (!s[1] || inpmatch(s+1)))main(argc,argv)char 	**argv;{	register t;#ifdef gcos	tempfile = "m4*tempa";#endif#ifdef unix	{	static	sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0};	for (t=0; sigs[t]; ++t)		if (signal(sigs[t], SIG_IGN) != SIG_IGN)			signal(sigs[t],catchsig);	}	tempfile = mktemp("/tmp/m4aXXXXX");	close(creat(tempfile,0));#endif/* WARNING: the following depends on the implementation of the ctype macros! */	(_pctype+1)['_'] |= _L;	/* makes '_' a real live letter *//* end of warning */	procnam = argv[0];	getflags(&argc,&argv);	initalloc();	setfname("-");	if (argc>1) {		--argc;		++argv;		if (strcmp(argv[0],"-")) {			ifile[ifx] = xfopen(argv[0],"r");			setfname(argv[0]);		}	}	for (;;) {		token[0] = t = getchr();		token[1] = EOS;		if (t==EOF) {			if (ifx > 0) {				fclose(ifile[ifx]);				ipflr = ipstk[--ifx];				continue;			}			getflags(&argc,&argv);			if (argc<=1)				if (Wrapstr) {					pbstr(Wrapstr);					Wrapstr = NULL;					continue;				} else					break;			--argc;			++argv;			if (ifile[ifx]!=stdin)				fclose(ifile[ifx]);			if (*argv[0]=='-')				ifile[ifx] = stdin;			else				ifile[ifx] = xfopen(argv[0],"r");			setfname(argv[0]);			continue;		}		if (isalpha(t)) {			register char	*tp = token+1;			register	tlim = toksize;			struct nlist	*macadd;  /* temp variable */			while (isalnum(*tp++ = getchr()))				if (--tlim<=0)					error2("more than %d chars in word",							toksize);			putbak(*--tp);			*tp = EOS;			macadd = lookup(token);			*Ap = (char *) macadd;			if (macadd->def) {				if ((char *) (++Ap) >= astklm) {					--Ap;					error2(astkof,stksize);				}				if (Cp++==NULL)					Cp = callst;				Cp->argp = Ap;				*Ap++ = op;				puttok(token);				stkchr(EOS);				t = getchr();				putbak(t);				if (t!='(')					pbstr("()");				else	/* try to fix arg count */					*Ap++ = op;				Cp->plev = 0;			} else {				puttok(token);			}		} else if (match(t,lquote)) {			register	qlev = 1;			for (;;) {				token[0] = t = getchr();				token[1] = EOS;				if (match(t,rquote)) {					if (--qlev > 0)						puttok(token);					else						break;				} else if (match(t,lquote)) {					++qlev;					puttok(token);				} else {					if (t==EOF)						error("EOF in quote");					putchr(t);				}			}		} else if (match(t,lcom)) {			puttok(token);			for (;;) {				token[0] = t = getchr();				token[1] = EOS;				if (match(t,rcom)) {					puttok(token);					break;				} else {					if (t==EOF)						error("EOF in comment");					putchr(t);				}			}		} else if (Cp==NULL) {			putchr(t);		} else if (t=='(') {			if (Cp->plev)				stkchr(t);			else {				/* skip white before arg */				while (isspace(t=getchr()))					;				putbak(t);			}			++Cp->plev;		} else if (t==')') {			--Cp->plev;			if (Cp->plev==0) {				stkchr(EOS);				expand(Cp->argp,Ap-Cp->argp-1);				op = *Cp->argp;				Ap = Cp->argp-1;				if (--Cp < callst)					Cp = NULL;			} else				stkchr(t);		} else if (t==',' && Cp->plev<=1) {			stkchr(EOS);			*Ap = op;			if ((char *) (++Ap) >= astklm) {				--Ap;				error2(astkof,stksize);			}			while (isspace(t=getchr()))				;			putbak(t);		} else			stkchr(t);	}	if (Cp!=NULL)		error("EOF in argument list");	delexit(OK);}char	*inpmatch(s)register char	*s;{	register char	*tp = token+1;	while (*s) {		*tp = getchr();		if (*tp++ != *s++) {			*tp = EOS;			pbstr(token+1);			return 0;		}	}	*tp = EOS;	return token;}getflags(xargc,xargv)register int	*xargc;register char 	***xargv;{	while (*xargc > 1) {		register char	*arg = (*xargv)[1];		if (arg[0]!='-' || arg[1]==EOS)			break;		switch (arg[1]) {		case 'B':			bufsize = atoi(&arg[2]);			break;		case 'D':			{			register char *t;			char *s[2];			initalloc();			for (t = s[0] = &arg[2]; *t; t++)				if (*t=='=') {					*t++ = EOS;					break;				}			s[1] = t;			dodef(&s[-1],2);			break;			}		case 'H':			hshsize = atoi(&arg[2]);			break;		case 'S':			stksize = atoi(&arg[2]);			break;		case 'T':			toksize = atoi(&arg[2]);			break;		case 'U':			{			char *s[1];			initalloc();			s[0] = &arg[2];			doundef(&s[-1],1);			break;			}		case 'e':#ifdef unix			setbuf(stdout,(char *) NULL);			signal(SIGINT,SIG_IGN);#endif			break;		case 's':			/* turn on line sync */			sflag = 1;			break;		default:			fprintf(stderr,"%s: bad option: %s\n",				procnam,arg);			delexit(NOT_OK);		}		(*xargv)++;		--(*xargc);	}	return;}initalloc(){	static	done = 0;	register	t;	if (done++)		return;	hshtab = (struct nlist **) xcalloc(hshsize,sizeof(struct nlist *));	callst = (struct call *) xcalloc(stksize/3+1,sizeof(struct call));	Ap = argstk = (char **) xcalloc(stksize+3,sizeof(char *));	ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1,sizeof(char));	op = obuf = xcalloc(bufsize+1,sizeof(char));	token = xcalloc(toksize+1,sizeof(char));	astklm = (char *) (&argstk[stksize]);	ibuflm = &ibuf[bufsize];	obuflm = &obuf[bufsize];	toklm = &token[toksize];	for (t=0; barray[t].bname; ++t) {		static char	p[2] = {0, EOS};		p[0] = t|~LOW7;		install(barray[t].bname,p,NOPUSH);	}#ifdef unix	install("unix",nullstr,NOPUSH);#endif#ifdef gcos	install("gcos",nullstr,NOPUSH);#endif}struct nlist	*install(nam,val,mode)char	*nam;register char	*val;{	register struct nlist *np;	register char	*cp;	int		l;	if (mode==PUSH)		lookup(nam);	/* lookup sets hshval */	else		while (undef(nam))	/* undef calls lookup */			;	np = (struct nlist *) xcalloc(1,sizeof(*np));	np->name = copy(nam);	np->next = hshtab[hshval];	hshtab[hshval] = np;	cp = xcalloc((l=strlen(val))+1,sizeof(*val));	np->def = cp;	cp = &cp[l];	while (*val)		*--cp = *val++;}struct nlist	*lookup(str)char 	*str;{	register char		*s1;	register struct nlist	*np;	static struct nlist	nodef;	s1 = str;	for (hshval = 0; *s1; )		hshval += *s1++;	hshval %= hshsize;	for (np = hshtab[hshval]; np!=NULL; np = np->next) {		if (!strcmp(str, np->name))			return(np);	}	return(&nodef);}expand(a1,c)char	**a1;{	register char	*dp;	register struct nlist	*sp;	sp = (struct nlist *) a1[-1];	if (sp->tflag || trace) {		int	i;		fprintf(stderr,"Trace(%d): %s",Cp-callst,a1[0]);		if (c > 0) {			fprintf(stderr,"(%s",chkbltin(a1[1]));			for (i=2; i<=c; ++i)				fprintf(stderr,",%s",chkbltin(a1[i]));			fprintf(stderr,")");		}		fprintf(stderr,"\n");	}	dp = sp->def;	for (; *dp; ++dp) {		if (*dp&~LOW7) {			(*barray[*dp&LOW7].bfunc)(a1,c);		} else if (dp[1]=='$') {			if (isdigit(*dp)) {				register	n;				if ((n = *dp-'0') <= c)					pbstr(a1[n]);				++dp;			} else if (*dp=='#') {				pbnum((long) c);				++dp;			} else if (*dp=='*' || *dp=='@') {				register i = c;				char **a = a1;				if (i > 0)					for (;;) {						if (*dp=='@')							pbstr(rquote);						pbstr(a[i--]);						if (*dp=='@')							pbstr(lquote);						if (i <= 0)							break;						pbstr(",");					}				++dp;			} else				putbak(*dp);		} else			putbak(*dp);	}}setfname(s)register char 	*s;{	strcpy(fname[ifx],s);	fname[ifx+1] = fname[ifx]+strlen(s)+1;	fline[ifx] = 1;	nflag = 1;	lnsync(stdout);}lnsync(iop)register FILE	*iop;{	static int cline = 0;	static int cfile = 0;	if (!sflag || iop!=stdout)		return;	if (nflag || ifx!=cfile) {		nflag = 0;		cfile = ifx;		fprintf(iop,"#line %d \"",cline = fline[ifx]);		fpath(iop);		fprintf(iop,"\"\n");	} else if (++cline != fline[ifx])		fprintf(iop,"#line %d\n",cline = fline[ifx]);}fpath(iop)register FILE	*iop;{	register	i;	fprintf(iop,"%s",fname[0]);	for (i=1; i<=ifx; ++i)		fprintf(iop,":%s",fname[i]);}catchsig(){#ifdef unix	signal(SIGHUP,SIG_IGN);	signal(SIGINT,SIG_IGN);#endif	delexit(NOT_OK);}delexit(code){	register i;	cf = stdout;/*	if (ofx != 0) {	/* quitting in middle of diversion *//*		ofx = 0;/*		code = NOT_OK;/*	}*/	ofx = 0;	/* ensure that everything comes out */	for (i=1; i<10; i++)		undiv(i,code);	tempfile[7] = 'a';	unlink(tempfile);	if (code==OK)		exit(code);	_exit(code);}puttok(tp)register char *tp;{	if (Cp) {		while (*tp)			stkchr(*tp++);	} else if (cf)		while (*tp)			sputchr(*tp++,cf);}pbstr(str)register char *str;{	register char *p;	for (p = str + strlen(str); --p >= str; )		putbak(*p);}undiv(i,code)register	i;{	register FILE *fp;	register	c;	if (i<1 || i>9 || i==ofx || !ofile[i])		return;	fclose(ofile[i]);	tempfile[7] = 'a'+i;	if (code==OK && cf) {		fp = xfopen(tempfile,"r");		while ((c=getc(fp)) != EOF)			sputchr(c,cf);		fclose(fp);	}	unlink(tempfile);	ofile[i] = NULL;}char 	*copy(s)register char *s;{	register char *p;	p = xcalloc(strlen(s)+1,sizeof(char));	strcpy(p, s);	return(p);}pbnum(num)long num;{	pbnbr(num,10,1);}pbnbr(nbr,base,len)long	nbr;register	base, len;{	register	neg = 0;	if (base<=0)		return;	if (nbr<0)		neg = 1;	else		nbr = -nbr;	while (nbr<0) {		register int	i;		if (base>1) {			i = nbr%base;			nbr /= base;#		if (-3 % 2) != -1			while (i > 0) {				i -= base;				++nbr;			}#		endif			i = -i;		} else {			i = 1;			++nbr;		}		putbak(itochr(i));		--len;	}	while (--len >= 0)		putbak('0');	if (neg)		putbak('-');}itochr(i)register	i;{	if (i>9)		return i-10+'A';	else		return i+'0';}long ctol(str)register char *str;{	register sign;	long num;	while (isspace(*str))		++str;	num = 0;	if (*str=='-') {		sign = -1;		++str;	}	else		sign = 1;	while (isdigit(*str))		num = num*10 + *str++ - '0';	return(sign * num);}min(a,b){	if (a>b)		return(b);	return(a);}FILE	*xfopen(name,mode)char	*name,	*mode;{	FILE	*fp;	if ((fp=fopen(name,mode))==NULL)		error(badfile);	return fp;}char	*xcalloc(nbr,size){	register char	*ptr;	if ((ptr=calloc((unsigned) nbr,(unsigned) size)) == NULL)		error(nocore);	return ptr;}error2(str,num)	char *str;	int num;{	char buf[500];	sprintf(buf,str,num);	error(buf);}error(str)	char *str;{	fprintf(stderr,"\n%s:",procnam);	fpath(stderr);	fprintf(stderr,":%d %s\n",fline[ifx],str);	if (Cp) {		register struct call	*mptr;		/* fix limit */		*op = EOS;		(Cp+1)->argp = Ap+1;		for (mptr=callst; mptr<=Cp; ++mptr) {			register char	**aptr, **lim;			aptr = mptr->argp;			lim = (mptr+1)->argp-1;			if (mptr==callst)				fputs(*aptr,stderr);			++aptr;			fputs("(",stderr);			if (aptr < lim)				for (;;) {					fputs(*aptr++,stderr);					if (aptr >= lim)						break;					fputs(",",stderr);				}		}		while (--mptr >= callst)			fputs(")",stderr);		fputs("\n",stderr);	}	delexit(NOT_OK);}char	*chkbltin(s)char	*s;{	static char	buf[24];	if (*s&~LOW7){		sprintf(buf,"<%s>",barray[*s&LOW7].bname);		return buf;	}	return s;}int	getchr(){	if (ip > ipflr)		return (*--ip);	C = feof(ifile[ifx]) ? EOF : getc(ifile[ifx]);	if (C =='\n')		fline[ifx]++;	return (C);}

⌨️ 快捷键说明

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