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

📄 getline.c

📁 minix软件源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			 * last time we tried. Undo this increment			 */			poff--;			--lastreadline;		}	}	else {		if (nopipe) pblock->b_foff = lseek(stdf, 0L, 1);		if (saved) {			/*			 * There were leftovers from the previous block			 */			pblock->b_info = saved;			if (nopipe) pblock->b_foff -= savedc1 - saved;			c1 = savedc1;			saved = 0;		}		else {	/* Allocate new block */			pblock->b_info = c1 = alloc(BLOCKSIZE + 1, 1);		}		/*		 * Allocate some space for line-offsets		 */		pblock->b_offs = poff = (int *)			alloc((unsigned) (100 * sizeof(int)), 0);		siz = 99;		*poff++ = 0;	}	c = c1;	for (;;) {		/*		 * Read loop		 */		cnt = read(stdf, c1, BLOCKSIZE - (c1 - pblock->b_info));		if (cnt < 0) {			/*			 * Interrupted read			 */			if (errno == EINTR) continue;			error("Could not read input file");			cnt = 0;		}		c1 += cnt;		if (c1 != pblock->b_info + BLOCKSIZE) {			ENDseen = 1;			pblock->b_flags |= PARTLY;		}		break;	}	assert(c <= c1);	while (c < c1) {		/*		 * Now process the block		 */		*c &= 0177;	/* Most significant bit ignored */		if (*c == '\n') {			/*			 * Newlines are replaced by '\0', so that "getline"			 * can deliver one line at a time			 */			*c = 0;			lastreadline++;			/*			 * Remember the line-offset			 */			if (poff == pblock->b_offs + siz) {				/*				 * No space for it, allocate some more				 */				pblock->b_offs = (int *)					re_alloc((char *) pblock->b_offs,						 (siz+1) * sizeof(int),						 (siz + 51) * sizeof(int));				poff = pblock->b_offs + siz;				siz += 50;			}			*poff++ = c - pblock->b_info + 1;		}		else if (*c == '\0') {			/*			 * 0-bytes are replaced by 0200, because newlines are			 * replaced by 0, and 0200 & 0177 gives again 0 ...			 */			*c = 0200;		}		c++;	}	assert(c==c1);	*c = 0;	if (c != pblock->b_info && *(c-1) != 0) {		/*		 * The last line read does not end with a newline, so add one		 */		lastreadline++;		*poff++ = c - pblock->b_info + 1;		if (!(pblock->b_flags & PARTLY) && *(poff - 2) != 0) {			/*			 * Save the started line; it will be in the next block.			 * Remove the newline we added just now.			 */			saved = c1 = alloc(BLOCKSIZE + 1, 1);			c = pblock->b_info + *(--poff - 1);			while (*c) *c1++ = *c++;			c = pblock->b_info + *(poff - 1);			savedc1 = c1;			--lastreadline;		}	}	pblock->b_end = lastreadline;	if (pblock->b_flags & PARTLY) {		/*		 * Take care, that we can call "nextblock" again, to fill in		 * the rest of this block		 */		savedsiz = siz;		savedpoff = poff;		savedc1 = c;		if (c == pblock->b_info) {			lastreadline++;			pblock->b_end = 0;		}	}	else {		/*		 * Not completely read blocks are not in the linked list,		 * so can never be "swapped out".		 */		addtolist(pblock);		cnt = pblock - blocklist;		filldegree = ((c-pblock->b_info) + (cnt-1) * filldegree) / cnt;	}	assert(pblock->b_end - (pblock-1)->b_end <= poff - pblock->b_offs);}/* * Allocate core for the block, and read it back from * the temporary file. */STATIC VOIDreadblock(pblock) register struct block *pblock; {	register int size;	register long i;	/*	 * Find out where the block is, and read it	 */	pblock->b_info = alloc(BLOCKSIZE + 1, 1);	i = (pblock - 1)->b_end * sizeof(int);	size = (int) (pblock->b_end * sizeof(int) - i);	pblock->b_offs	= (int *) alloc((unsigned) size, 0);	if (nopipe) {		register char *c;		register int line_index;		int cnt;		long l = lseek(stdf, 0L, 1);		(VOID) lseek(stdf, pblock->b_foff, 0);		cnt = read(stdf, pblock->b_info, BLOCKSIZE);		(VOID) lseek(stdf, l, 0);		c = pblock->b_info;		pblock->b_offs[0] = 0;		line_index = 1;		size /= sizeof(int);		while (c < pblock->b_info + cnt) {			*c &= 0177;			if (*c == '\n') {				*c = '\0';				if (line_index < size)					pblock->b_offs[line_index++] =						(c - pblock->b_info) + 1;			}			else if (*c == '\0') *c = 0200;			c++;		}		*c = '\0';	}	else {		(VOID) lseek(tfdes, (long) ((long) BLOCKSIZE * (pblock - blocklist)),0);		if (read(tfdes, pblock->b_info,BLOCKSIZE) != BLOCKSIZE) {			panic("read error");		}		/*		 * Find out where the line-offset list is, and read it		 */		(VOID) lseek(ifdes, i, 0);		if (read(ifdes, (char *) pblock->b_offs, size) != size) {			panic("read error");		}		pblock->b_info[BLOCKSIZE] = '\0';	}	/*	 * Add this block to the list of incore blocks	 */	addtolist(pblock);}/* * Called after processing a file. * Free all core. */VOIDdo_clean() {	register struct block *pblock;	register char *p;	for (pblock = blocklist; pblock < maxblocklist; pblock++) {		if (p = pblock->b_info) {			free(p);			free((char *) pblock->b_offs);		}	}	if (p = (char *) blocklist) {		free(p);	}	blocklist = 0;	maxblocklist = 0;	topblocklist = 0;	lastreadline = 0;	filldegree = 0;	ENDseen = 0;	if (p = saved) free(p);	saved = 0;	b_head = 0;	b_tail = 0;# if MAXNBLOCKS	nblocks = 0;# endif}/* * Close a file with file-descriptor "file", if it indeed is one */STATIC VOIDcls(file) {	if (file) (VOID) close(file);}/* * Close all files */VOIDcls_files() {	cls(tfdes);	cls(ifdes);	cls(stdf);}/* * Get a character. If possible, do some workahead. */intgetch() {# if USG_OPEN# include <fcntl.h># include <sys/stat.h>	register int i,j;	struct stat buf;# else# ifdef FIONREAD# include <sys/stat.h>	struct stat buf;	long i;# endif# endif	char c;	int retval;	flush();	if (startcomm) {		/*		 * Command line option command		 */		if (*startcomm) return *startcomm++;		return '\n';	}# if USG_OPEN	if (stdf >= 0) {		/*		 * Make reads from the terminal non-blocking, so that		 * we can see if the user typed something		 */		i = fcntl(0,F_GETFL,0);		if (i != -1 && fcntl(0, F_SETFL, i|O_NDELAY) != -1) {			j = 0;			while (! ENDseen && 			       ((j = read(0,&c,1)) == 0#ifdef EWOULDBLOCK			        || (j < 0 && errno == EWOULDBLOCK)#endif			       )			       &&			       (nopipe || 				(fstat(stdf,&buf) >= 0 && buf.st_size > 0))) {				/*				 * Do some read ahead, after making sure there				 * is input and the user did not type a command				 */				new_block();			}			(VOID) fcntl(0,F_SETFL,i);			if (j < 0) {				/*				 * Could this have happened?				 * I'm not sure, because the read is				 * nonblocking. Can it be interrupted then?				 */				return -1;			}			if (j > 0) return c;		}	}# else# ifdef FIONREAD	if (stdf >= 0) {		/*		 * See if there are any characters waiting in the terminal input		 * queue. If there are not, read ahead.		 */		while (! ENDseen &&		       ( ioctl(0, FIONREAD, (char *) &i) >= 0 && i == 0) &&		       ( nopipe || fstat(stdf,&buf) >= 0 && buf.st_size > 0)) {			/*			 * While the user does'nt type anything, and there is			 * input to be processed, work ahead			 */			if (interrupt) return -1;			new_block();		}	}# endif# endif	if (read(0,&c,1) <= 0) retval = -1; else retval = c & 0177;	return retval;}/* * Get the position of line "ln" in the file. */longgetpos(ln) long ln; {	register struct block *pblock;	register long i;	pblock = getblock(ln,1);	assert(pblock != 0);	i = filldegree * (pblock - blocklist);	return i - (filldegree - pblock->b_offs[ln - (pblock-1)->b_end]);}

⌨️ 快捷键说明

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