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

📄 b.c

📁 举世闻名的joe记事本源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
				}				pprev(p);			} while (p->hdr != q->hdr);		--p->ofst;		--p->byte;		if (GCHAR(p) == '\n')			--p->line;	}	return p;}/* find backward substring s in text pointed by p and set p on the first of found substring */P *prfind(P *p, unsigned char *s, int len){	P *q = pdup(p, USTR "prfind");	if (frfind(q, s, len)) {		rgetto(p, q);		prm(q);		return p;	} else {		prm(q);		return NULL;	}}/* same as prfind() but case insensitive */P *prifind(P *p, unsigned char *s, int len){	P *q = pdup(p, USTR "prifind");	if (frifind(q, s, len)) {		rgetto(p, q);		prm(q);		return p;	} else {		prm(q);		return NULL;	}}/* copy text between 'from' and 'to' into new buffer */B *bcpy(P *from, P *to){	H anchor, *l;	unsigned char *ptr;	P *q;	if (from->byte >= to->byte)		return bmk(from->b);	q = pdup(from, USTR "bcpy");	izque(H, link, &anchor);	if (q->hdr == to->hdr) {		l = halloc();		ptr = vlock(vmem, l->seg);		if (q->ofst != q->hdr->hole)			gstgap(q->hdr, q->ptr, q->ofst);		l->nlines = mcnt(q->ptr + q->hdr->ehole, '\n', l->hole = to->ofst - q->ofst);		mmove(ptr, q->ptr + q->hdr->ehole, l->hole);		vchanged(ptr);		vunlock(ptr);		enqueb(H, link, &anchor, l);	} else {		l = halloc();		ptr = vlock(vmem, l->seg);		if (q->ofst != q->hdr->hole)			gstgap(q->hdr, q->ptr, q->ofst);		l->nlines = mcnt(q->ptr + q->hdr->ehole, '\n', l->hole = SEGSIZ - q->hdr->ehole);		mmove(ptr, q->ptr + q->hdr->ehole, l->hole);		vchanged(ptr);		vunlock(ptr);		enqueb(H, link, &anchor, l);		pnext(q);		while (q->hdr != to->hdr) {			l = halloc();			ptr = vlock(vmem, l->seg);			l->nlines = q->hdr->nlines;			mmove(ptr, q->ptr, q->hdr->hole);			mmove(ptr + q->hdr->hole, q->ptr + q->hdr->ehole, SEGSIZ - q->hdr->ehole);			l->hole = GSIZE(q->hdr);			vchanged(ptr);			vunlock(ptr);			enqueb(H, link, &anchor, l);			pnext(q);		}		if (to->ofst) {			l = halloc();			ptr = vlock(vmem, l->seg);			if (to->ofst != to->hdr->hole)				gstgap(to->hdr, to->ptr, to->ofst);			l->nlines = mcnt(to->ptr, '\n', to->ofst);			mmove(ptr, to->ptr, l->hole = to->ofst);			vchanged(ptr);			vunlock(ptr);			enqueb(H, link, &anchor, l);		}	}	l = anchor.link.next;	deque(H, link, &anchor);	prm(q);	return bmkchn(l, from->b, to->byte - from->byte, to->line - from->line);}/* Coalesce small blocks into a single larger one */void pcoalesce(P *p){	if (p->hdr != p->b->eof->hdr && GSIZE(p->hdr) + GSIZE(p->hdr->link.next) <= SEGSIZ - SEGSIZ / 4) {		H *hdr = p->hdr->link.next;		unsigned char *ptr = vlock(vmem, hdr->seg);		int osize = GSIZE(p->hdr);		int size = GSIZE(hdr);		P *q;		gstgap(hdr, ptr, size);		ginsm(p->hdr, p->ptr, GSIZE(p->hdr), ptr, size);		p->hdr->nlines += hdr->nlines;		vunlock(ptr);		hfree(deque_f(H, link, hdr));		for (q = p->link.next; q != p; q = q->link.next)			if (q->hdr == hdr) {				q->hdr = p->hdr;				if (q->ptr) {					vunlock(q->ptr);					q->ptr = vlock(vmem, q->hdr->seg);				}				q->ofst += osize;			}	}	if (p->hdr != p->b->bof->hdr && GSIZE(p->hdr) + GSIZE(p->hdr->link.prev) <= SEGSIZ - SEGSIZ / 4) {		H *hdr = p->hdr->link.prev;		unsigned char *ptr = vlock(vmem, hdr->seg);		int size = GSIZE(hdr);		P *q;		gstgap(hdr, ptr, size);		ginsm(p->hdr, p->ptr, 0, ptr, size);		p->hdr->nlines += hdr->nlines;		vunlock(ptr);		hfree(deque_f(H, link, hdr));		p->ofst += size;		for (q = p->link.next; q != p; q = q->link.next)			if (q->hdr == hdr) {				q->hdr = p->hdr;				if (q->ptr)					vunlock(q->ptr);				q->ptr = vlock(vmem, q->hdr->seg);			} else if (q->hdr == p->hdr)				q->ofst += size;	}}/* Delete the text between two pointers from a buffer and return it in a new * buffer. * * This routine calls these functions: *  gstgap	- to position gaps *  halloc	- to allocate new header/segment pairs *  vlock	- virtual memory routines *  vunlock *  vchanged *  vupcount *  mcnt	- to count NLs *  snip	- queue routines *  enqueb *  splicef *  scrdel	- to tell screen update to scroll when NLs are deleted *  bmkchn	- to make a buffer out of a chain *//* This is only to be used for bdel() */static B *bcut(P *from, P *to){	H *h,			/* The deleted text */	*i;	unsigned char *ptr;	P *p;	long nlines;		/* No. EOLs to delete */	long amnt;		/* No. bytes to delete */	int toamnt;		/* Amount to delete from segment in 'to' */	int bofmove = 0;	/* Set if bof got deleted */	struct lattr_db *db;	if (!(amnt = to->byte - from->byte))		return NULL;	/* ...nothing to delete */	nlines = to->line - from->line;	if (from->hdr == to->hdr) {	/* Delete is within a single segment */		/* Move gap to deletion point */		if (from->ofst != from->hdr->hole)			gstgap(from->hdr, from->ptr, from->ofst);		/* Store the deleted text */		h = halloc();		ptr = vlock(vmem, h->seg);		mmove(ptr, from->ptr + from->hdr->ehole, (int) amnt);		h->hole = amnt;		h->nlines = nlines;		vchanged(ptr);		vunlock(ptr);		/* Delete */		from->hdr->ehole += amnt;		from->hdr->nlines -= nlines;		toamnt = amnt;	} else {		/* Delete crosses segments */		H *a;		if ((toamnt = to->ofst) != 0) {			/* Delete beginning of to */			/* Move gap to deletion point */			/* To could be deleted if it's at the end of the file */			if (to->ofst != to->hdr->hole)				gstgap(to->hdr, to->ptr, to->ofst);			/* Save deleted text */			i = halloc();			ptr = vlock(vmem, i->seg);			mmove(ptr, to->ptr, to->hdr->hole);			i->hole = to->hdr->hole;			i->nlines = mcnt(to->ptr, '\n', to->hdr->hole);			vchanged(ptr);			vunlock(ptr);			/* Delete */			to->hdr->nlines -= i->nlines;			to->hdr->hole = 0;		} else			i = 0;		/* Delete end of from */		if (!from->ofst) {			/* ... unless from needs to be deleted too */			a = from->hdr->link.prev;			h = NULL;			if (a == from->b->eof->hdr)				bofmove = 1;		} else {			a = from->hdr;			/* Move gap to deletion point */			if (from->ofst != from->hdr->hole)				gstgap(from->hdr, from->ptr, from->ofst);			/* Save deleted text */			h = halloc();			ptr = vlock(vmem, h->seg);			mmove(ptr, from->ptr + from->hdr->ehole, SEGSIZ - from->hdr->ehole);			h->hole = SEGSIZ - from->hdr->ehole;			h->nlines = mcnt(ptr, '\n', h->hole);			vchanged(ptr);			vunlock(ptr);			/* Delete */			from->hdr->nlines -= h->nlines;			from->hdr->ehole = SEGSIZ;		}		/* Make from point to header/segment of to */		from->hdr = to->hdr;		vunlock(from->ptr);		from->ptr = to->ptr;		vupcount(to->ptr);		from->ofst = 0;		/* Delete headers/segments between a and to->hdr (if there are any) */		if (a->link.next != to->hdr)			if (!h) {				h = snip(H, link, a->link.next, to->hdr->link.prev);				if (i)					enqueb(H, link, h, i);			} else {				splicef(H, link, h, snip(H, link, a->link.next, to->hdr->link.prev));				if (i)					enqueb(H, link, h, i);		} else if (!h)			h = i;		else if (i)			enqueb(H, link, h, i);	}	/* If to is empty, then it must have been at the end of the file.  If	   the file did not become empty, delete to */	if (!GSIZE(to->hdr) && from->byte) {		H *ph = from->hdr->link.prev;		hfree(deque_f(H, link, from->hdr));		vunlock(from->ptr);		from->hdr = ph;		from->ptr = vlock(vmem, from->hdr->seg);		from->ofst = GSIZE(ph);		vunlock(from->b->eof->ptr);		from->b->eof->ptr = from->ptr;		vupcount(from->ptr);		from->b->eof->hdr = from->hdr;		from->b->eof->ofst = from->ofst;	}	/* The deletion is now done */	/* Scroll if necessary */	if (bofmove)		pset(from->b->bof, from);	for (db = from->b->db; db; db = db->next)		lattr_del(db, from->line, nlines);	if (!pisbol(from)) {		scrdel(from->b, from->line, nlines, 1);		delerr(from->b->name, from->line, nlines);	} else {		scrdel(from->b, from->line, nlines, 0);		delerr(from->b->name, from->line, nlines);	}	/* Fix pointers */	for (p = from->link.next; p != from; p = p->link.next)		if (p->line == from->line && p->byte > from->byte)			p->valcol = 0;	for (p = from->link.next; p != from; p = p->link.next) {		if (p->byte >= from->byte) {			if (p->byte <= from->byte + amnt) {				if (p->ptr) {					pset(p, from);				} else {					poffline(pset(p, from));				}			} else {				if (p->hdr == to->hdr)					p->ofst -= toamnt;				p->byte -= amnt;				p->line -= nlines;			}		}	}	pcoalesce(from);	/* Make buffer out of deleted text and return it */	return bmkchn(h, from->b, amnt, nlines);}void bdel(P *from, P *to){	if (to->byte - from->byte) {		B *b = bcut(from, to);		if (from->b->undo)			undodel(from->b->undo, from->byte, b);		else			brm(b);		from->b->changed = 1;	}}/* Split a block at p's ofst *//* p is placed in the new block such that it points to the same text but with * p->ofst==0 */static void bsplit(P *p){	if (p->ofst) {		H *hdr;		unsigned char *ptr;		P *pp;		hdr = halloc();		ptr = vlock(vmem, hdr->seg);		if (p->ofst != p->hdr->hole)			gstgap(p->hdr, p->ptr, p->ofst);		mmove(ptr, p->ptr + p->hdr->ehole, SEGSIZ - p->hdr->ehole);		hdr->hole = SEGSIZ - p->hdr->ehole;		hdr->nlines = mcnt(ptr, '\n', hdr->hole);		p->hdr->nlines -= hdr->nlines;		vchanged(ptr);		p->hdr->ehole = SEGSIZ;		enquef(H, link, p->hdr, hdr);		vunlock(p->ptr);		for (pp = p->link.next; pp != p; pp = pp->link.next)			if (pp->hdr == p->hdr && pp->ofst >= p->ofst) {				pp->hdr = hdr;				if (pp->ptr) {					vunlock(pp->ptr);					pp->ptr = ptr;					vupcount(ptr);				}				pp->ofst -= p->ofst;			}		p->ptr = ptr;		p->hdr = hdr;		p->ofst = 0;	}}/* Make a chain out of a block of memory (the block must not be empty) */static H *bldchn(unsigned char *blk, int size, long *nlines){	H anchor, *l;	*nlines = 0;	izque(H, link, &anchor);	do {		unsigned char *ptr;		int amnt;		ptr = vlock(vmem, (l = halloc())->seg);		if (size > SEGSIZ)			amnt = SEGSIZ;		else			amnt = size;		mmove(ptr, blk, amnt);		l->hole = amnt;		l->ehole = SEGSIZ;		(*nlines) += (l->nlines = mcnt(ptr, '\n', amnt));		vchanged(ptr);		vunlock(ptr);		enqueb(H, link, &anchor, l);		blk += amnt;		size -= amnt;	} while (size);	l = anchor.link.next;	deque(H, link, &anchor);	return l;}/* Insert a chain into a buffer (this does not update pointers) */static void inschn(P *p, H *a){	if (!p->b->eof->byte) {	/* P's buffer is empty: replace the empty segment in p with a */		hfree(p->hdr);		p->hdr = a;		vunlock(p->ptr);		p->ptr = vlock(vmem, a->seg);		pset(p->b->bof, p);		p->b->eof->hdr = a->link.prev;		vunlock(p->b->eof->ptr);		p->b->eof->ptr = vlock(vmem, p->b->eof->hdr->seg);		p->b->eof->ofst = GSIZE(p->b->eof->hdr);	} else if (piseof(p)) {	/* We're at the end of the file: append a to the file */		p->b->eof->hdr = a->link.prev;		spliceb(H, link, p->b->bof->hdr, a);		vunlock(p->b->eof->ptr);		p->b->eof->ptr = vlock(vmem, p->b->eof->hdr->seg);		p->b->eof->ofst = GSIZE(p->b->eof->hdr);		p->hdr = a;		vunlock(p->ptr);		p->ptr = vlock(vmem, p->hdr->seg);		p->ofst = 0;	} else if (pisbof(p)) {	/* We're at the beginning of the file: insert chain and set bof pointer */		p->hdr = spliceb_f(H, link, p->hdr, a);		vunlock(p->ptr);		p->ptr = vlock(vmem, a->seg);		pset(p->b->bof, p);	} else {		/* We're in the middle of the file: split and insert */		bsplit(p);		p->hdr = spliceb_f(H, link, p->hdr, a);		vunlock(p->ptr);		p->ptr = vlock(vmem, a->seg);	}}static void fixupins(P *p, long amnt, long nlines, H *hdr, int hdramnt){	P *pp;	struct lattr_db *db;	if (!pisbol(p))		scrins(p->b, p->line, nlines, 1);	else		scrins(p->b, p->line, nlines, 0);	for (db = p->b->db; db; db = db->next)		lattr_ins(db, p->line, nlines);	inserr(p->b->name, p->line, nlines, pisbol(p));	/* FIXME: last arg ??? */	for (pp = p->link.next; pp != p; pp = pp->link.next)		if (pp->line == p->line && (pp->byte > p->byte || (pp->end && pp->byte == p->byte)))			pp->valcol = 0;	for (pp = p->link.next; pp != p; pp = pp->link.next)		if (pp->byte == p->byte && !pp->end)			if (pp->ptr)				pset(pp, p);			else				poffline(pset(pp, p));		else if (pp->byte > p->byte || (pp->end && pp->byte == p->byte)) {			pp->byte += amnt;			pp->line += nlines;			if (pp->hdr == hdr)				pp->ofst += hdramnt;		}	if (p->b->undo)		undoins(p->b->undo, p, amnt);	p->b->changed = 1;}/* Insert a buffer at pointer position (the buffer goes away) */P *binsb(P *p, B *b){	if (b->eof->byte) {		P *q = pdup(p, USTR "binsb");		inschn(q, b->bof->hdr);		b->eof->hdr = halloc();		fixupins(q, b->eof->byte, b->eof->line, NULL, 0);		pcoalesce(q);		prm(q);	}	brm(b);	return p;}/* insert memory block 'blk' at 'p' */P *binsm(P *p, unsigned char *blk, int amnt){	long nlines;	H *h = NULL;	int hdramnt = 0; /* Only used if h is set */	P *q;	if (!amnt)		return p;	q = pdup(p, USTR "binsm");	if (amnt <= GGAPSZ(q->hdr)) {		h = q->hdr;		hdramnt = amnt;		ginsm(q->hdr, q->ptr, q->ofst, blk, amnt);		q->hdr->nlines += (nlines = mcnt(blk, '\n', amnt));	} else if (!q->ofst && q->hdr != q->b->bof->hdr && amnt <= GGAPSZ(q->hdr->link.prev)) {		pprev(q);		ginsm(q->hdr, q->ptr, q->ofst, blk, amnt);		q->hdr->nlines += (nlines = mcnt(blk, '\n', amnt));	} else {		H *a = bldchn(blk, amnt, &nlines);		inschn(q, a);	}	fixupins(q, (long) amnt, nlines, h, hdramnt);	pcoalesce(q);	prm(q);	return p;}/* insert byte 'c' at 'p' */P *binsbyte(P *p, unsigned char c){	if (p->b->o.crlf && c == '\n')		return binsm(p, USTR "\r\n", 2);	else		return binsm(p, &c, 1);}/* UTF-8 encode a character and insert it */P *binsc(P *p, int c){	if (c>127 && p->b->o.charmap->type) {		unsigned char buf[8];		int len = utf8_encode(buf,c);		return binsm(p,buf,len);	} else {		unsigned char ch = c;		if (p->b->o.crlf && c == '\n')			return binsm(p, USTR "\r\n", 2);		else			return binsm(p, &ch, 1);	}}/* insert zero-terminated string 's' at 'p' */P *binss(P *p, unsigned char *s){	return binsm(p, s, zlen(s));}/* Read 'size' bytes from file or stream.  Stops and returns amnt. read * when requested size has been read or when end of file condition occurs. * Returns with -2 in error for read error or 0 in error for success. */static int bkread(int fi, unsigned char *buff, int size){	int a, b;	if (!size) {		berror = 0;		return 0;	}	for (a = b = 0; (a < size) && ((b = joe_read(fi, buff + a, size - a)) > 0); a += b) ;	if (b < 0)		berror = -2;	else		berror = 0;	return a;}/* Read up to 'max' bytes from a file into a buffer *//* Returns with 0 in error or -2 in error for read error */B *bread(int fi, long int max){	H anchor, *l;	long lines = 0, total = 0;	int amnt;	unsigned char *seg;	izque(H, link, &anchor);	berror = 0;	while (seg = vlock(vmem, (l = halloc())->seg), !berror && (amnt = bkread(fi, seg, max >= SEGSIZ ? SEGSIZ : (int) max))) {		total += amnt;		max -= amnt;		l->hole = amnt;		lines += (l->nlines = mcnt(seg, '\n', amnt));		vchanged(seg);		vunlock(seg);		enqueb(H, link, &anchor, l);	}	hfree(l);	vunlock(seg);	if (!total)		return bmk(NULL);	l = anchor.link.next;	deque(H, link, &anchor);	return bmkchn(l, NULL, total, lines);}/* Parse file name. * * Removes ',xxx,yyy' from end of name and puts their value into skip and amnt * Replaces ~user/ with directory of given user * Replaces ~/ with $HOME * * Returns new variable length string. */unsigned char *parsens(unsigned char *s, off_t *skip, off_t *amnt){	unsigned char *n = vsncpy(NULL, 0, sz(s));	int x;	*skip = 0;	*amnt = MAXLONG;	x = sLEN(n) - 1;	if (x > 0 && n[x] >= '0' && n[x] <= '9') {		for (x = sLEN(n) - 1; x > 0 && ((n[x] >= '0' && n[x] <= '9') || n[x] == 'x' || n[x] == 'X'); --x) ;		if (n[x] == ',') {			n[x] = 0;#if SIZEOF_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG			if (n[x + 1] == 'x' || n[x + 1] == 'X')				sscanf((char *)(n + x + 2), "%llx", skip);			else if (n[x + 1] == '0' && (n[x + 2] == 'x' || n[x + 2] == 'X'))				sscanf((char *)(n + x + 3), "%llx", skip);			else if (n[x + 1] == '0')				sscanf((char *)(n + x + 1), "%llo", skip);			else				sscanf((char *)(n + x + 1), "%lld", skip);#else			if (n[x + 1] == 'x' || n[x + 1] == 'X')				sscanf((char *)(n + x + 2), "%lx", skip);			else if (n[x + 1] == '0' && (n[x + 2] == 'x' || n[x + 2] == 'X'))				sscanf((char *)(n + x + 3), "%lx", skip);			else if (n[x + 1] == '0')				sscanf((char *)(n + x + 1), "%lo", skip);			else				sscanf((char *)(n + x + 1), "%ld", skip);#endif			--x;			if (x > 0 && n[x] >= '0' && n[x] <= '9') {				for (; x > 0 && ((n[x] >= '0' && n[x] <= '9') || n[x] == 'x' || n[x] == 'X'); --x) ;				if (n[x] == ',') {					n[x] = 0;					*amnt = *skip;#if SIZEOF_LONG_LONG && SIZEOF_OFF_T == SIZEOF_LONG_LONG					if (n[x + 1] == 'x' || n[x + 1] == 'X')						sscanf((char *)(n + x + 2), "%llx", skip);					else if (n[x + 1] == '0' && (n[x + 2] == 'x' || n[x + 2] == 'X'))						sscanf((char *)(n + x + 3), "%llx", skip);					else if (n[x + 1] == '0')						sscanf((char *)(n + x + 1), "%llo", skip);					else						sscanf((char *)(n + x + 1), "%lld", skip);#else					if (n[x + 1] == 'x' || n[x + 1] == 'X')						sscanf((char *)(n + x + 2), "%lx", skip);					else if (n[x + 1] == '0' && (n[x + 2] == 'x' || n[x + 2] == 'X'))						sscanf((char *)(n + x + 3), "%lx", skip);					else if (n[x + 1] == '0')						sscanf((char *)(n + x + 1), "%lo", skip);					else						sscanf((char *)(n + x + 1), "%ld", skip);#endif				}			}		}	}	/* Don't do this here: do it in prompt buffer instead, so we're just like	   the shell doing it on the command line. */	/* n = canonical(n); */	return n;}/* Canonicalize file name: do ~ expansion */

⌨️ 快捷键说明

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