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

📄 xfid.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
				if(w->nomark == FALSE){					seq++;					filemark(t->file);				}				q0 = textbsinsert(t, q0, r, nr, TRUE, &nr);				textsetselect(t, t->q0, t->q1);	/* insert could leave it somewhere else */				if(qid!=QWwrsel && !t->w->noscroll)					textshow(t, q0+nr, q0+nr, 1);				textscrdraw(t);			}			winsettag(w);			if(qid == QWwrsel)				w->wrselrange.q1 += nr;			free(r);		}		fc.count = x->count;		respond(x, &fc, nil);		break;	default:		sprint(buf, "unknown qid %d in write", qid);		respond(x, &fc, buf);		break;	}	if(w)		winunlock(w);}voidxfidctlwrite(Xfid *x, Window *w){	Fcall fc;	int i, m, n, nb, nr, nulls;	Rune *r;	char *err, *p, *pp, *q, *e;	int isfbuf, scrdraw, settag;	Text *t;	err = nil;	e = x->data+x->count;	scrdraw = FALSE;	settag = FALSE;	isfbuf = TRUE;	if(x->count < RBUFSIZE)		r = fbufalloc();	else{		isfbuf = FALSE;		r = emalloc(x->count*UTFmax+1);	}	x->data[x->count] = 0;	textcommit(&w->tag, TRUE);	for(n=0; n<x->count; n+=m){		p = x->data+n;		if(strncmp(p, "lock", 4) == 0){	/* make window exclusive use */			qlock(&w->ctllock);			w->ctlfid = x->f->fid;			m = 4;		}else		if(strncmp(p, "unlock", 6) == 0){	/* release exclusive use */			w->ctlfid = ~0;			qunlock(&w->ctllock);			m = 6;		}else		if(strncmp(p, "clean", 5) == 0){	/* mark window 'clean', seq=0 */			t = &w->body;			t->eq0 = ~0;			filereset(t->file);			t->file->mod = FALSE;			w->dirty = FALSE;			settag = TRUE;			m = 5;		}else		if(strncmp(p, "dirty", 5) == 0){	/* mark window 'dirty' */			t = &w->body;			/* doesn't change sequence number, so "Put" won't appear.  it shouldn't. */			t->file->mod = TRUE;			w->dirty = TRUE;			settag = TRUE;			m = 5;		}else		if(strncmp(p, "show", 4) == 0){	/* show dot */			t = &w->body;			textshow(t, t->q0, t->q1, 1);			m = 4;		}else		if(strncmp(p, "name ", 5) == 0){	/* set file name */			pp = p+5;			m = 5;			q = memchr(pp, '\n', e-pp);			if(q==nil || q==pp){				err = Ebadctl;				break;			}			*q = 0;			nulls = FALSE;			cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);			if(nulls){				err = "nulls in file name";				break;			}			for(i=0; i<nr; i++)				if(r[i] <= ' '){					err = "bad character in file name";					goto out;				}out:			seq++;			filemark(w->body.file);			winsetname(w, r, nr);			m += (q+1) - pp;		}else		if(strncmp(p, "dump ", 5) == 0){	/* set dump string */			pp = p+5;			m = 5;			q = memchr(pp, '\n', e-pp);			if(q==nil || q==pp){				err = Ebadctl;				break;			}			*q = 0;			nulls = FALSE;			cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);			if(nulls){				err = "nulls in dump string";				break;			}			w->dumpstr = runetobyte(r, nr);			m += (q+1) - pp;		}else		if(strncmp(p, "dumpdir ", 8) == 0){	/* set dump directory */			pp = p+8;			m = 8;			q = memchr(pp, '\n', e-pp);			if(q==nil || q==pp){				err = Ebadctl;				break;			}			*q = 0;			nulls = FALSE;			cvttorunes(pp, q-pp, r, &nb, &nr, &nulls);			if(nulls){				err = "nulls in dump directory string";				break;			}			w->dumpdir = runetobyte(r, nr);			m += (q+1) - pp;		}else		if(strncmp(p, "delete", 6) == 0){	/* delete for sure */			colclose(w->col, w, TRUE);			m = 6;		}else		if(strncmp(p, "del", 3) == 0){	/* delete, but check dirty */			if(!winclean(w, TRUE)){				err = "file dirty";				break;			}			colclose(w->col, w, TRUE);			m = 3;		}else		if(strncmp(p, "get", 3) == 0){	/* get file */			get(&w->body, nil, nil, FALSE, XXX, nil, 0);			m = 3;		}else		if(strncmp(p, "put", 3) == 0){	/* put file */			put(&w->body, nil, nil, XXX, XXX, nil, 0);			m = 3;		}else		if(strncmp(p, "dot=addr", 8) == 0){	/* set dot */			textcommit(&w->body, TRUE);			clampaddr(w);			w->body.q0 = w->addr.q0;			w->body.q1 = w->addr.q1;			textsetselect(&w->body, w->body.q0, w->body.q1);			settag = TRUE;			m = 8;		}else		if(strncmp(p, "addr=dot", 8) == 0){	/* set addr */			w->addr.q0 = w->body.q0;			w->addr.q1 = w->body.q1;			m = 8;		}else		if(strncmp(p, "limit=addr", 10) == 0){	/* set limit */			textcommit(&w->body, TRUE);			clampaddr(w);			w->limit.q0 = w->addr.q0;			w->limit.q1 = w->addr.q1;			m = 10;		}else		if(strncmp(p, "nomark", 6) == 0){	/* turn off automatic marking */			w->nomark = TRUE;			m = 6;		}else		if(strncmp(p, "mark", 4) == 0){	/* mark file */			seq++;			filemark(w->body.file);			settag = TRUE;			m = 4;		}else		if(strncmp(p, "nomenu", 6) == 0){	/* turn off automatic menu */			w->filemenu = FALSE;			m = 6;		}else		if(strncmp(p, "menu", 4) == 0){	/* enable automatic menu */			w->filemenu = TRUE;			m = 4;		}else		if(strncmp(p, "noscroll", 8) == 0){	/* turn off automatic scrolling */			w->noscroll = TRUE;			m = 8;		}else		if(strncmp(p, "cleartag", 8) == 0){	/* wipe tag right of bar */			wincleartag(w);			settag = TRUE;			m = 8;		}else		if(strncmp(p, "scroll", 6) == 0){	/* turn on automatic scrolling (writes to body only) */			w->noscroll = FALSE;			m = 6;		}else{			err = Ebadctl;			break;		}		while(p[m] == '\n')			m++;	}	if(isfbuf)		fbuffree(r);	else		free(r);	if(err)		n = 0;	fc.count = n;	respond(x, &fc, err);	if(settag)		winsettag(w);	if(scrdraw)		textscrdraw(&w->body);}voidxfideventwrite(Xfid *x, Window *w){	Fcall fc;	int m, n;	Rune *r;	char *err, *p, *q;	int isfbuf;	Text *t;	int c;	uint q0, q1;	err = nil;	isfbuf = TRUE;	if(x->count < RBUFSIZE)		r = fbufalloc();	else{		isfbuf = FALSE;		r = emalloc(x->count*UTFmax+1);	}	for(n=0; n<x->count; n+=m){		p = x->data+n;		w->owner = *p++;	/* disgusting */		c = *p++;		while(*p == ' ')			p++;		q0 = strtoul(p, &q, 10);		if(q == p)			goto Rescue;		p = q;		while(*p == ' ')			p++;		q1 = strtoul(p, &q, 10);		if(q == p)			goto Rescue;		p = q;		while(*p == ' ')			p++;		if(*p++ != '\n')			goto Rescue;		m = p-(x->data+n);		if('a'<=c && c<='z')			t = &w->tag;		else if('A'<=c && c<='Z')			t = &w->body;		else			goto Rescue;		if(q0>t->file->nc || q1>t->file->nc || q0>q1)			goto Rescue;		qlock(&row);	/* just like mousethread */		switch(c){		case 'x':		case 'X':			execute(t, q0, q1, TRUE, nil);			break;		case 'l':		case 'L':			look3(t, q0, q1, TRUE);			break;		default:			qunlock(&row);			goto Rescue;		}		qunlock(&row);	}    Out:	if(isfbuf)		fbuffree(r);	else		free(r);	if(err)		n = 0;	fc.count = n;	respond(x, &fc, err);	return;    Rescue:	err = Ebadevent;	goto Out;}voidxfidutfread(Xfid *x, Text *t, uint q1, int qid){	Fcall fc;	Window *w;	Rune *r;	char *b, *b1;	uint q, off, boff;	int m, n, nr, nb;	w = t->w;	wincommit(w, t);	off = x->offset;	r = fbufalloc();	b = fbufalloc();	b1 = fbufalloc();	n = 0;	if(qid==w->utflastqid && off>=w->utflastboff && w->utflastq<=q1){		boff = w->utflastboff;		q = w->utflastq;	}else{		/* BUG: stupid code: scan from beginning */		boff = 0;		q = 0;	}	w->utflastqid = qid;	while(q<q1 && n<x->count){		/*		 * Updating here avoids partial rune problem: we're always on a		 * char boundary. The cost is we will usually do one more read		 * than we really need, but that's better than being n^2.		 */		w->utflastboff = boff;		w->utflastq = q;		nr = q1-q;		if(nr > BUFSIZE/UTFmax)			nr = BUFSIZE/UTFmax;		bufread(t->file, q, r, nr);		nb = snprint(b, BUFSIZE+1, "%.*S", nr, r);		if(boff >= off){			m = nb;			if(boff+m > off+x->count)				m = off+x->count - boff;			memmove(b1+n, b, m);			n += m;		}else if(boff+nb > off){			if(n != 0)				error("bad count in utfrune");			m = nb - (off-boff);			if(m > x->count)				m = x->count;			memmove(b1, b+(off-boff), m);			n += m;		}		boff += nb;		q += nr;	}	fbuffree(r);	fbuffree(b);	fc.count = n;	fc.data = b1;	respond(x, &fc, nil);	fbuffree(b1);}intxfidruneread(Xfid *x, Text *t, uint q0, uint q1){	Fcall fc;	Window *w;	Rune *r, junk;	char *b, *b1;	uint q, boff;	int i, rw, m, n, nr, nb;	w = t->w;	wincommit(w, t);	r = fbufalloc();	b = fbufalloc();	b1 = fbufalloc();	n = 0;	q = q0;	boff = 0;	while(q<q1 && n<x->count){		nr = q1-q;		if(nr > BUFSIZE/UTFmax)			nr = BUFSIZE/UTFmax;		bufread(t->file, q, r, nr);		nb = snprint(b, BUFSIZE+1, "%.*S", nr, r);		m = nb;		if(boff+m > x->count){			i = x->count - boff;			/* copy whole runes only */			m = 0;			nr = 0;			while(m < i){				rw = chartorune(&junk, b+m);				if(m+rw > i)					break;				m += rw;				nr++;			}			if(m == 0)				break;		}		memmove(b1+n, b, m);		n += m;		boff += nb;		q += nr;	}	fbuffree(r);	fbuffree(b);	fc.count = n;	fc.data = b1;	respond(x, &fc, nil);	fbuffree(b1);	return q-q0;}voidxfideventread(Xfid *x, Window *w){	Fcall fc;	char *b;	int i, n;	i = 0;	x->flushed = FALSE;	while(w->nevents == 0){		if(i){			if(!x->flushed)				respond(x, &fc, "window shut down");			return;		}		w->eventx = x;		winunlock(w);		recvp(x->c);		winlock(w, 'F');		i++;	}	n = w->nevents;	if(n > x->count)		n = x->count;	fc.count = n;	fc.data = w->events;	respond(x, &fc, nil);	b = w->events;	w->events = estrdup(w->events+n);	free(b);	w->nevents -= n;}voidxfidindexread(Xfid *x){	Fcall fc;	int i, j, m, n, nmax, isbuf, cnt, off;	Window *w;	char *b;	Rune *r;	Column *c;	qlock(&row);	nmax = 0;	for(j=0; j<row.ncol; j++){		c = row.col[j];		for(i=0; i<c->nw; i++){			w = c->w[i];			nmax += Ctlsize + w->tag.file->nc*UTFmax + 1;		}	}	nmax++;	isbuf = (nmax<=RBUFSIZE);	if(isbuf)		b = (char*)x->buf;	else		b = emalloc(nmax);	r = fbufalloc();	n = 0;	for(j=0; j<row.ncol; j++){		c = row.col[j];		for(i=0; i<c->nw; i++){			w = c->w[i];			/* only show the currently active window of a set */			if(w->body.file->curtext != &w->body)				continue;			winctlprint(w, b+n, 0);			n += Ctlsize;			m = min(RBUFSIZE, w->tag.file->nc);			bufread(w->tag.file, 0, r, m);			m = n + snprint(b+n, nmax-n-1, "%.*S", m, r);			while(n<m && b[n]!='\n')				n++;			b[n++] = '\n';		}	}	qunlock(&row);	off = x->offset;	cnt = x->count;	if(off > n)		off = n;	if(off+cnt > n)		cnt = n-off;	fc.count = cnt;	memmove(r, b+off, cnt);	fc.data = (char*)r;	if(!isbuf)		free(b);	respond(x, &fc, nil);	fbuffree(r);}

⌨️ 快捷键说明

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