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

📄 file.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <draw.h>#include <thread.h>#include <cursor.h>#include <mouse.h>#include <keyboard.h>#include <frame.h>#include <fcall.h>#include <plumb.h>#include "dat.h"#include "fns.h"/* * Structure of Undo list: * 	The Undo structure follows any associated data, so the list *	can be read backwards: read the structure, then read whatever *	data is associated (insert string, file name) and precedes it. *	The structure includes the previous value of the modify bit *	and a sequence number; successive Undo structures with the *	same sequence number represent simultaneous changes. */typedef struct Undo Undo;struct Undo{	short	type;		/* Delete, Insert, Filename */	short	mod;	/* modify bit */	uint		seq;		/* sequence number */	uint		p0;		/* location of change (unused in f) */	uint		n;		/* # runes in string or file name */};enum{	Undosize = sizeof(Undo)/sizeof(Rune),};File*fileaddtext(File *f, Text *t){	if(f == nil){		f = emalloc(sizeof(File));		f->unread = TRUE;	}	f->text = realloc(f->text, (f->ntext+1)*sizeof(Text*));	f->text[f->ntext++] = t;	f->curtext = t;	return f;}voidfiledeltext(File *f, Text *t){	int i;	for(i=0; i<f->ntext; i++)		if(f->text[i] == t)			goto Found;	error("can't find text in filedeltext");    Found:	f->ntext--;	if(f->ntext == 0){		fileclose(f);		return;	}	memmove(f->text+i, f->text+i+1, (f->ntext-i)*sizeof(Text*));	if(f->curtext == t)		f->curtext = f->text[0];}voidfileinsert(File *f, uint p0, Rune *s, uint ns){	if(p0 > f->nc)		error("internal error: fileinsert");	if(f->seq > 0)		fileuninsert(f, &f->delta, p0, ns);	bufinsert(f, p0, s, ns);	if(ns)		f->mod = TRUE;}voidfileuninsert(File *f, Buffer *delta, uint p0, uint ns){	Undo u;	/* undo an insertion by deleting */	u.type = Delete;	u.mod = f->mod;	u.seq = f->seq;	u.p0 = p0;	u.n = ns;	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);}voidfiledelete(File *f, uint p0, uint p1){	if(!(p0<=p1 && p0<=f->nc && p1<=f->nc))		error("internal error: filedelete");	if(f->seq > 0)		fileundelete(f, &f->delta, p0, p1);	bufdelete(f, p0, p1);	if(p1 > p0)		f->mod = TRUE;}voidfileundelete(File *f, Buffer *delta, uint p0, uint p1){	Undo u;	Rune *buf;	uint i, n;	/* undo a deletion by inserting */	u.type = Insert;	u.mod = f->mod;	u.seq = f->seq;	u.p0 = p0;	u.n = p1-p0;	buf = fbufalloc();	for(i=p0; i<p1; i+=n){		n = p1 - i;		if(n > RBUFSIZE)			n = RBUFSIZE;		bufread(f, i, buf, n);		bufinsert(delta, delta->nc, buf, n);	}	fbuffree(buf);	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);}voidfilesetname(File *f, Rune *name, int n){	if(f->seq > 0)		fileunsetname(f, &f->delta);	free(f->name);	f->name = runemalloc(n);	runemove(f->name, name, n);	f->nname = n;	f->unread = TRUE;}voidfileunsetname(File *f, Buffer *delta){	Undo u;	/* undo a file name change by restoring old name */	u.type = Filename;	u.mod = f->mod;	u.seq = f->seq;	u.p0 = 0;	/* unused */	u.n = f->nname;	if(f->nname)		bufinsert(delta, delta->nc, f->name, f->nname);	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);}uintfileload(File *f, uint p0, int fd, int *nulls){	if(f->seq > 0)		error("undo in file.load unimplemented");	return bufload(f, p0, fd, nulls);}/* return sequence number of pending redo */uintfileredoseq(File *f){	Undo u;	Buffer *delta;	delta = &f->epsilon;	if(delta->nc == 0)		return 0;	bufread(delta, delta->nc-Undosize, (Rune*)&u, Undosize);	return u.seq;}voidfileundo(File *f, int isundo, uint *q0p, uint *q1p){	Undo u;	Rune *buf;	uint i, j, n, up;	uint stop;	Buffer *delta, *epsilon;	if(isundo){		/* undo; reverse delta onto epsilon, seq decreases */		delta = &f->delta;		epsilon = &f->epsilon;		stop = f->seq;	}else{		/* redo; reverse epsilon onto delta, seq increases */		delta = &f->epsilon;		epsilon = &f->delta;		stop = 0;	/* don't know yet */	}	buf = fbufalloc();	while(delta->nc > 0){		up = delta->nc-Undosize;		bufread(delta, up, (Rune*)&u, Undosize);		if(isundo){			if(u.seq < stop){				f->seq = u.seq;				goto Return;			}		}else{			if(stop == 0)				stop = u.seq;			if(u.seq > stop)				goto Return;		}		switch(u.type){		default:			fprint(2, "undo: 0x%ux\n", u.type);			abort();			break;		case Delete:			f->seq = u.seq;			fileundelete(f, epsilon, u.p0, u.p0+u.n);			f->mod = u.mod;			bufdelete(f, u.p0, u.p0+u.n);			for(j=0; j<f->ntext; j++)				textdelete(f->text[j], u.p0, u.p0+u.n, FALSE);			*q0p = u.p0;			*q1p = u.p0;			break;		case Insert:			f->seq = u.seq;			fileuninsert(f, epsilon, u.p0, u.n);			f->mod = u.mod;			up -= u.n;			for(i=0; i<u.n; i+=n){				n = u.n - i;				if(n > RBUFSIZE)					n = RBUFSIZE;				bufread(delta, up+i, buf, n);				bufinsert(f, u.p0+i, buf, n);				for(j=0; j<f->ntext; j++)					textinsert(f->text[j], u.p0+i, buf, n, FALSE);			}			*q0p = u.p0;			*q1p = u.p0+u.n;			break;		case Filename:			f->seq = u.seq;			fileunsetname(f, epsilon);			f->mod = u.mod;			up -= u.n;			free(f->name);			if(u.n == 0)				f->name = nil;			else				f->name = runemalloc(u.n);			bufread(delta, up, f->name, u.n);			f->nname = u.n;			break;		}		bufdelete(delta, up, delta->nc);	}	if(isundo)		f->seq = 0;    Return:	fbuffree(buf);}voidfilereset(File *f){	bufreset(&f->delta);	bufreset(&f->epsilon);	f->seq = 0;}voidfileclose(File *f){	free(f->name);	f->nname = 0;	f->name = nil;	free(f->text);	f->ntext = 0;	f->text = nil;	bufclose(f);	bufclose(&f->delta);	bufclose(&f->epsilon);	elogclose(f);	free(f);}voidfilemark(File *f){	if(f->epsilon.nc)		bufdelete(&f->epsilon, 0, f->epsilon.nc);	f->seq = seq;}

⌨️ 快捷键说明

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