s_rdinstack.c

来自「这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易」· C语言 代码 · 共 142 行

C
142
字号
#include <u.h>#include <libc.h>#include <bio.h>#include "String.h"struct Sinstack{	int	depth;	Biobuf	*fp[32];	/* hard limit to avoid infinite recursion */};/* initialize */extern Sinstack *s_allocinstack(char *file){	Sinstack *sp;	Biobuf *fp;	fp = Bopen(file, OREAD);	if(fp == nil)		return nil;	sp = malloc(sizeof *sp);	sp->depth = 0;	sp->fp[0] = fp;	return sp;}extern voids_freeinstack(Sinstack *sp){	while(sp->depth >= 0)		Bterm(sp->fp[sp->depth--]);	free(sp);}/*  Append an input line to a String. * *  Empty lines and leading whitespace are removed. */static char *rdline(Biobuf *fp, String *to){	int c;	int len = 0;	c = Bgetc(fp);	/* eat leading white */	while(c==' ' || c=='\t' || c=='\n' || c=='\r')		c = Bgetc(fp);	if(c < 0)		return 0;	for(;;){		switch(c) {		case -1:			goto out;		case '\\':			c = Bgetc(fp);			if (c != '\n') {				s_putc(to, '\\');				s_putc(to, c);				len += 2;			}			break;		case '\r':			break;		case '\n':			if(len != 0)				goto out;			break;		default:			s_putc(to, c);			len++;			break;		}		c = Bgetc(fp);	}out:	s_terminate(to);	return to->ptr - len;}/* Append an input line to a String. * * Returns a pointer to the character string (or 0). * Leading whitespace and newlines are removed. * Lines starting with #include cause us to descend into the new file. * Empty lines and other lines starting with '#' are ignored. */ extern char *s_rdinstack(Sinstack *sp, String *to){	char *p;	Biobuf *fp, *nfp;	s_terminate(to);	fp = sp->fp[sp->depth];	for(;;){		p = rdline(fp, to);		if(p == nil){			if(sp->depth == 0)				break;			Bterm(fp);			sp->depth--;			return s_rdinstack(sp, to);		}		if(strncmp(p, "#include", 8) == 0 && (p[8] == ' ' || p[8] == '\t')){			to->ptr = p;			p += 8;			/* sanity (and looping) */			if(sp->depth >= nelem(sp->fp))				sysfatal("s_recgetline: includes too deep");			/* skip white */			while(*p == ' ' || *p == '\t')				p++;			nfp = Bopen(p, OREAD);			if(nfp == nil)				continue;			sp->depth++;			sp->fp[sp->depth] = nfp;			return s_rdinstack(sp, to);		}		/* got milk? */		if(*p != '#')			break;		/* take care of comments */		to->ptr = p;		s_terminate(to);	}	return p;}

⌨️ 快捷键说明

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