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

📄 parse.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"mk.h"char *infile;int mkinline;static int rhead(char *, Word **, Word **, int *, char **);static char *rbody(Biobuf*);extern Word *target1;voidparse(char *f, int fd, int varoverride){	int hline;	char *body;	Word *head, *tail;	int attr, set, pid;	char *prog, *p;	int newfd;	Biobuf in;	Bufblock *buf;	if(fd < 0){		perror(f);		Exit();	}	ipush();	infile = strdup(f);	mkinline = 1;	Binit(&in, fd, OREAD);	buf = newbuf();	while(assline(&in, buf)){		hline = mkinline;		switch(rhead(buf->start, &head, &tail, &attr, &prog))		{		case '<':			p = wtos(tail, ' ');			if(*p == 0){				SYNERR(-1);				fprint(2, "missing include file name\n");				Exit();			}			newfd = open(p, OREAD);			if(newfd < 0){				fprint(2, "warning: skipping missing include file: ");				perror(p);			} else				parse(p, newfd, 0);			break;		case '|':			p = wtos(tail, ' ');			if(*p == 0){				SYNERR(-1);				fprint(2, "missing include program name\n");				Exit();			}			execinit();			pid=pipecmd(p, envy, &newfd);			if(newfd < 0){				fprint(2, "warning: skipping missing program file: ");				perror(p);			} else				parse(p, newfd, 0);			while(waitup(-3, &pid) >= 0)				;			if(pid != 0){				fprint(2, "bad include program status\n");				Exit();			}			break;		case ':':			body = rbody(&in);			addrules(head, tail, body, attr, hline, prog);			break;		case '=':			if(head->next){				SYNERR(-1);				fprint(2, "multiple vars on left side of assignment\n");				Exit();			}			if(symlook(head->s, S_OVERRIDE, 0)){				set = varoverride;			} else {				set = 1;				if(varoverride)					symlook(head->s, S_OVERRIDE, (void *)"");			}			if(set){/*char *cp;dumpw("tail", tail);cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);*/				setvar(head->s, (void *) tail);				symlook(head->s, S_WESET, (void *)"");			}			if(attr)				symlook(head->s, S_NOEXPORT, (void *)"");			break;		default:			SYNERR(hline);			fprint(2, "expected one of :<=\n");			Exit();			break;		}	}	close(fd);	freebuf(buf);	ipop();}voidaddrules(Word *head, Word *tail, char *body, int attr, int hline, char *prog){	Word *w;	assert(/*addrules args*/ head && body);		/* tuck away first non-meta rule as default target*/	if(target1 == 0 && !(attr&REGEXP)){		for(w = head; w; w = w->next)			if(charin(w->s, "%&"))				break;		if(w == 0)			target1 = wdup(head);	}	for(w = head; w; w = w->next)		addrule(w->s, tail, body, head, attr, hline, prog);}static intrhead(char *line, Word **h, Word **t, int *attr, char **prog){	char *p;	char *pp;	int sep;	Rune r;	int n;	Word *w;	p = charin(line,":=<");	if(p == 0)		return('?');	sep = *p;	*p++ = 0;	if(sep == '<' && *p == '|'){		sep = '|';		p++;	}	*attr = 0;	*prog = 0;	if(sep == '='){		pp = charin(p, termchars);	/* termchars is shell-dependent */		if (pp && *pp == '=') {			while (p != pp) {				n = chartorune(&r, p);				switch(r)				{				default:					SYNERR(-1);					fprint(2, "unknown attribute '%c'\n",*p);					Exit();				case 'U':					*attr = 1;					break;				}				p += n;			}			p++;		/* skip trailing '=' */		}	}	if((sep == ':') && *p && (*p != ' ') && (*p != '\t')){		while (*p) {			n = chartorune(&r, p);			if (r == ':')				break;			p += n;			switch(r)			{			default:				SYNERR(-1);				fprint(2, "unknown attribute '%c'\n", p[-1]);				Exit();			case 'D':				*attr |= DEL;				break;			case 'E':				*attr |= NOMINUSE;				break;			case 'n':				*attr |= NOVIRT;				break;			case 'N':				*attr |= NOREC;				break;			case 'P':				pp = utfrune(p, ':');				if (pp == 0 || *pp == 0)					goto eos;				*pp = 0;				*prog = strdup(p);				*pp = ':';				p = pp;				break;			case 'Q':				*attr |= QUIET;				break;			case 'R':				*attr |= REGEXP;				break;			case 'U':				*attr |= UPD;				break;			case 'V':				*attr |= VIR;				break;			}		}		if (*p++ != ':') {	eos:			SYNERR(-1);			fprint(2, "missing trailing :\n");			Exit();		}	}	*h = w = stow(line);	if(*w->s == 0 && sep != '<' && sep != '|') {		SYNERR(mkinline-1);		fprint(2, "no var on left side of assignment/rule\n");		Exit();	}	*t = stow(p);	return(sep);}static char *rbody(Biobuf *in){	Bufblock *buf;	int r, lastr;	char *p;	lastr = '\n';	buf = newbuf();	for(;;){		r = Bgetrune(in);		if (r < 0)			break;		if (lastr == '\n') {			if (r == '#')				rinsert(buf, r);			else if (r != ' ' && r != '\t') {				Bungetrune(in);				break;			}		} else			rinsert(buf, r);		lastr = r;		if (r == '\n')			mkinline++;	}	insert(buf, 0);	p = strdup(buf->start);	freebuf(buf);	return p;}struct input{	char *file;	int line;	struct input *next;};static struct input *inputs = 0;voidipush(void){	struct input *in, *me;	me = (struct input *)Malloc(sizeof(*me));	me->file = infile;	me->line = mkinline;	me->next = 0;	if(inputs == 0)		inputs = me;	else {		for(in = inputs; in->next; )			in = in->next;		in->next = me;	}}voidipop(void){	struct input *in, *me;	assert(/*pop input list*/ inputs != 0);	if(inputs->next == 0){		me = inputs;		inputs = 0;	} else {		for(in = inputs; in->next->next; )			in = in->next;		me = in->next;		in->next = 0;	}	infile = me->file;	mkinline = me->line;	free((char *)me);}

⌨️ 快捷键说明

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