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

📄 mc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * mc - columnate * * mc[-][-LINEWIDTH][-t][file...] *	- causes break on colon *	-LINEWIDTH sets width of line in which to columnate(default 80) *	-t suppresses expanding multiple blanks into tabs * */#include	<u.h>#include	<libc.h>#include	<draw.h>#include	<bio.h>#define	WIDTH			80#define	TAB	4#define	WORD_ALLOC_QUANTA	1024#define	ALLOC_QUANTA		4096int linewidth=WIDTH;int mintab=1;int colonflag=0;int tabflag=0;	/* -t flag turned off forever */Rune *cbuf, *cbufp;Rune **word;int maxwidth=0;int nalloc=ALLOC_QUANTA;int nwalloc=WORD_ALLOC_QUANTA;int nchars=0;int nwords=0;int tabwidth=0;Font *font;Biobuf	bin;Biobuf	bout;void getwidth(void), readbuf(int), error(char *);void scanwords(void), columnate(void), morechars(void);int wordwidth(Rune*, int);int nexttab(int);voidmain(int argc, char *argv[]){	int i;	int lineset;	int ifd;	lineset = 0;	Binit(&bout, 1, OWRITE);	while(argc > 1 && argv[1][0] == '-'){		--argc; argv++;		switch(argv[0][1]){		case '\0':			colonflag = 1;			break;		case 't':			tabflag = 0;			break;		default:			linewidth = atoi(&argv[0][1]);			if(linewidth <= 1)				linewidth = WIDTH;			lineset = 1;			break;		}	}	if(lineset == 0){		getwidth();		if(linewidth <= 1){			linewidth = WIDTH;			font = nil;		}	}	cbuf = cbufp = malloc(ALLOC_QUANTA*(sizeof *cbuf));	word = malloc(WORD_ALLOC_QUANTA*(sizeof *word));	if(word == 0 || cbuf == 0)		error("out of memory");	if(argc == 1)		readbuf(0);	else{		for(i = 1; i < argc; i++){			if((ifd = open(*++argv, OREAD)) == -1)				fprint(2, "mc: can't open %s (%r)\n", *argv);			else{				readbuf(ifd);				Bflush(&bin);				close(ifd);			}		}	}	columnate();	exits(0);}voiderror(char *s){	fprint(2, "mc: %s\n", s);	exits(s);}voidreadbuf(int fd){	int lastwascolon = 0;	long c;	int linesiz = 0;	Binit(&bin, fd, OREAD);	do{		if(nchars++ >= nalloc)			morechars();		*cbufp++ = c = Bgetrune(&bin);		linesiz++;		if(c == '\t') {			cbufp[-1] = L' ';			while(linesiz%TAB != 0) {				if(nchars++ >= nalloc)					morechars();				*cbufp++ = L' ';				linesiz++;			}		}		if(colonflag && c == ':')			lastwascolon++;		else if(lastwascolon){			if(c == '\n'){				--nchars; 	/* skip newline */				*cbufp = L'\0';				while(nchars > 0 && cbuf[--nchars] != '\n')					;				if(nchars)					nchars++;				columnate();				if (nchars)					Bputc(&bout, '\n');				Bprint(&bout, "%S", cbuf+nchars);				nchars = 0;				cbufp = cbuf;			}			lastwascolon = 0;		}		if(c == '\n')			linesiz = 0;	}while(c >= 0);}voidscanwords(void){	Rune *p, *q;	int i, w;	nwords=0;	maxwidth=0;	for(p = q = cbuf, i = 0; i < nchars; i++){		if(*p++ == L'\n'){			if(nwords >= nwalloc){				nwalloc += WORD_ALLOC_QUANTA;				if((word = realloc(word, nwalloc*sizeof(*word)))==0)					error("out of memory");			}			word[nwords++] = q;			p[-1] = L'\0';			w = wordwidth(q, p-q-1);			if(w > maxwidth)				maxwidth = w;			q = p;		}	}}voidcolumnate(void){	int i, j;	int words_per_line;	int nlines;	int col;	int endcol;	scanwords();	if(nwords==0)		return;	maxwidth = nexttab(maxwidth+mintab-1);	words_per_line = linewidth/maxwidth;	if(words_per_line <= 0)		words_per_line = 1;	nlines=(nwords+words_per_line-1)/words_per_line;	for(i = 0; i < nlines; i++){		col = endcol = 0;		for(j = i; j < nwords; j += nlines){			endcol += maxwidth;			Bprint(&bout, "%S", word[j]);			col += wordwidth(word[j], runestrlen(word[j]));			if(j+nlines < nwords){				if(tabflag) {					while(col < endcol){						Bputc(&bout, '\t');						col = nexttab(col);					}				}else{					while(col < endcol){						Bputc(&bout, ' ');						col++;					}				}			}		}		Bputc(&bout, '\n');	}}intwordwidth(Rune *w, int nw){	if(font)		return runestringnwidth(font, w, nw);	return nw;}intnexttab(int col){	if(tabwidth){		col += tabwidth;		col -= col%tabwidth;		return col;	}	return col+1;}voidmorechars(void){	nalloc += ALLOC_QUANTA;	if((cbuf = realloc(cbuf, nalloc*sizeof(*cbuf))) == 0)		error("out of memory");	cbufp = cbuf+nchars-1;}/* * These routines discover the width of the display. * It takes some work.  If we do the easy calls to the * draw library, the screen flashes due to repainting * when mc exits. */jmp_buf	drawjmp;voidterror(Display*, char*){	longjmp(drawjmp, 1);}voidgetwidth(void){	int n, fd;	char buf[128], *f[10], *p;	if(access("/dev/acme", OREAD) >= 0){		if((fd = open("/dev/acme/ctl", OREAD)) < 0)			return;		n = read(fd, buf, sizeof buf-1);		close(fd);		if(n <= 0)			return;		buf[n] = 0;		n = tokenize(buf, f, nelem(f));		if(n < 7)			return;		if((font = openfont(nil, f[6])) == nil)			return;		if(n >= 8)			tabwidth = atoi(f[7]);		else			tabwidth = 4*stringwidth(font, "0");		mintab = stringwidth(font, "0");		linewidth = atoi(f[5]);		tabflag = 1;		return;	}	if((p = getenv("font")) == nil)		return;	if((font = openfont(nil, p)) == nil)		return;	if((fd = open("/dev/window", OREAD)) < 0){		font = nil;		return;	}	n = read(fd, buf, 5*12);	close(fd);	if(n < 5*12){		font = nil;		return;	}	buf[n] = 0;		/* window stucture:		4 bit left edge		1 bit gap		12 bit scrollbar		4 bit gap		text		4 bit right edge	*/	linewidth = atoi(buf+3*12) - atoi(buf+1*12) - (4+1+12+4+4);	mintab = stringwidth(font, "0");	if((p = getenv("tabstop")) != nil)		tabwidth = atoi(p)*stringwidth(font, "0");	if(tabwidth == 0)		tabwidth = 4*stringwidth(font, "0");	tabflag = 1;}

⌨️ 快捷键说明

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