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

📄 b.c

📁 举世闻名的joe记事本源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *	Editor engine *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"#ifdef HAVE_PWD_H#include <pwd.h>#endifextern int errno;#ifdef WITH_SELINUX#include <selinux/selinux.h>static int selinux_enabled = -1;#endifunsigned char stdbuf[stdsiz];int guesscrlf = 0;int guessindent = 0;int berror;int force = 0;VFILE *vmem;unsigned char *msgs[] = {	USTR _("No error"),	USTR _("New File"),	USTR _("Error reading file"),	USTR _("Error seeking file"),	USTR _("Error opening file"),	USTR _("Error writing file"),	USTR _("File on disk is newer")};/* Get size of gap (amount of free space) */#define GGAPSZ(hdr) ((hdr)->ehole - (hdr)->hole)/* Get number of characters in gap buffer */#define GSIZE(hdr) (SEGSIZ - GGAPSZ(hdr))/* Get char from buffer (with jumping around the gap) */#define GCHAR(p) ((p)->ofst >= (p)->hdr->hole ? (p)->ptr[(p)->ofst + GGAPSZ((p)->hdr)] \					      : (p)->ptr[(p)->ofst])/* Set position of gap */static void gstgap(H *hdr, unsigned char *ptr, int ofst){	if (ofst > hdr->hole) {		mmove(ptr + hdr->hole, ptr + hdr->ehole, ofst - hdr->hole);		vchanged(ptr);	} else if (ofst < hdr->hole) {		mmove(ptr + hdr->ehole - (hdr->hole - ofst), ptr + ofst, hdr->hole - ofst);		vchanged(ptr);	}	hdr->ehole = ofst + hdr->ehole - hdr->hole;	hdr->hole = ofst;}/* Insert a block */static void ginsm(H *hdr, unsigned char *ptr, int ofst, unsigned char *blk, int size){	if (ofst != hdr->hole)		gstgap(hdr, ptr, ofst);	mmove(ptr + hdr->hole, blk, size);	hdr->hole += size;	vchanged(ptr);}/* Read block */static void grmem(H *hdr, unsigned char *ptr, int ofst, unsigned char *blk, int size){	if (ofst < hdr->hole)		if (size > hdr->hole - ofst) {			mmove(blk, ptr + ofst, hdr->hole - ofst);			mmove(blk + hdr->hole - ofst, ptr + hdr->ehole, size - (hdr->hole - ofst));		} else			mmove(blk, ptr + ofst, size);	else		mmove(blk, ptr + ofst + hdr->ehole - hdr->hole, size);}static H nhdrs = { {&nhdrs, &nhdrs} };static H ohdrs = { {&ohdrs, &ohdrs} };/* Header allocation */static H *halloc(void){	H *h;	if (qempty(H, link, &ohdrs)) {		h = (H *) alitem(&nhdrs, sizeof(H));		h->seg = my_valloc(vmem, (long) SEGSIZ);	} else		h = deque_f(H, link, ohdrs.link.next);	h->hole = 0;	h->ehole = SEGSIZ;	h->nlines = 0;	izque(H, link, h);	return h;}static void hfree(H *h){	enquef(H, link, &ohdrs, h);}static void hfreechn(H *h){	splicef(H, link, &ohdrs, h);}static P frptrs = { {&frptrs, &frptrs} };/* Pointer allocation */static P *palloc(void){	return alitem(&frptrs, sizeof(P));}static void pfree(P *p){	enquef(P, link, &frptrs, p);}/* Doubly linked list of buffers and free buffer structures */static B bufs = { {&bufs, &bufs} };static B frebufs = { {&frebufs, &frebufs} };void set_file_pos_orphaned(){	B *b;	for (b = bufs.link.next; b != &bufs; b = b->link.next)		if (b->orphan && b->oldcur)			set_file_pos(b->name,b->oldcur->line);}/* Find next buffer in list: for multi-file search and replace *//* This does not bump reference count on found buffer */B *bafter(B *b){	for (b = b->link.next; b->internal || b->scratch || b == &bufs; b = b->link.next);	return b;}int udebug_joe(BW *bw){	unsigned char buf[1024];	B *b;	P *p;	binss(bw->cursor, USTR "Buffers and pointers (the number of pointers per buffer should not grow, except for 20 from markpos):\n\n");	pnextl(bw->cursor);	for (b = bufs.link.next; b != &bufs; b = b->link.next) {		if (b->name)			joe_snprintf_1(buf, sizeof(buf), "Buffer %s\n", b->name);		else			joe_snprintf_1(buf, sizeof(buf), "Buffer 0x%p\n", (void *)b);		binss(bw->cursor, buf);		pnextl(bw->cursor);		for (p = b->bof->link.next; p != b->bof; p = p->link.next) {			joe_snprintf_1(buf, sizeof(buf), "  Pointer created by %s\n", p->tracker);			binss(bw->cursor, buf);			pnextl(bw->cursor);		}	}	dump_syntax(bw);	return 0;}B *bnext(void){	B *b;	do {		b = bufs.link.prev;		deque(B, link, &bufs);		enqueb(B, link, b, &bufs);	} while (b->internal);	return b;}B *bprev(void){	B *b;	do {		b = bufs.link.next;		deque(B, link, &bufs);		enquef(B, link, b, &bufs);	} while (b->internal);	return b;}/* Make a buffer out of a chain */static B *bmkchn(H *chn, B *prop, long amnt, long nlines){	B *b = alitem(&frebufs, sizeof(B));	b->undo = undomk(b);	if (prop)		b->o = prop->o;	else		b->o = pdefault;	mset(b->marks, 0, sizeof(b->marks));	b->rdonly = 0;	b->orphan = 0;	b->oldcur = NULL;	b->oldtop = NULL;	b->backup = 1;	b->internal = 1;	b->scratch = 0;	b->changed = 0;	b->gave_notice = 0;	b->locked = 0;	b->ignored_lock = 0;	b->didfirst = 0;	b->count = 1;	b->name = NULL;	b->er = -3;	b->bof = palloc();	b->mod_time = 0;	b->check_time = time(NULL);	izque(P, link, b->bof);	b->bof->end = 0;	b->bof->b = b;	b->bof->owner = NULL;	b->bof->hdr = chn;	b->bof->ptr = vlock(vmem, b->bof->hdr->seg);	b->bof->ofst = 0;	b->bof->byte = 0;	b->bof->line = 0;	b->bof->col = 0;	b->bof->xcol = 0;	b->bof->valcol = 1;	b->bof->tracker = USTR "bmkchn";	b->eof = pdup(b->bof, USTR "bmkchn");	b->eof->end = 1;	vunlock(b->eof->ptr);	b->eof->hdr = chn->link.prev;	b->eof->ptr = vlock(vmem, b->eof->hdr->seg);	b->eof->ofst = GSIZE(b->eof->hdr);	b->eof->byte = amnt;	b->eof->line = nlines;	b->eof->valcol = 0;	b->pid = 0;	b->out = -1;	b->db = 0;	b->parseone = 0;	enquef(B, link, &bufs, b);	pcoalesce(b->bof);	pcoalesce(b->eof);	return b;}/* Create an empty buffer */B *bmk(B *prop){	return bmkchn(halloc(), prop, 0L, 0L);}/* Eliminate a buffer */void brm(B *b){	if (b && !--b->count) {		if (b->changed)			abrerr(b->name);		if (b->locked && !b->ignored_lock && plain_file(b))			unlock_it(b->name);		if (b == errbuf)			errbuf = NULL;		if (b->undo)			undorm(b->undo);		hfreechn(b->eof->hdr);		while (!qempty(P, link, b->bof))			prm(b->bof->link.next);		prm(b->bof);		if (b->name)			joe_free(b->name);		if (b->db)			rm_all_lattr_db(b->db);		demote(B, link, &frebufs, b);	}}void brmall(){	while (!qempty(B, link, &bufs))		brm(bufs.link.next);}P *poffline(P *p){	if (p->ptr) {		vunlock(p->ptr);		p->ptr = NULL;	}	return p;}P *ponline(P *p){	if (!p->ptr)		p->ptr = vlock(vmem, p->hdr->seg);	return p;}B *boffline(B *b){	P *p = b->bof;	do {		poffline(p);	} while ((p = p->link.next) != b->bof);	return b;}B *bonline(B *b){	P *p = b->bof;	do {		ponline(p);	} while ((p = p->link.next) != b->bof);	return b;}P *pdup(P *p, unsigned char *tr){	P *n = palloc();	n->end = 0;	n->ptr = NULL;	n->owner = NULL;	n->tracker = tr;	enquef(P, link, p, n);	return pset(n, p);}P *pdupown(P *p, P **o, unsigned char *tr){	P *n = palloc();	n->end = 0;	n->ptr = NULL;	n->owner = o;	n->tracker = tr;	enquef(P, link, p, n);	pset(n, p);	if (*o)		prm(*o);	*o = n;	return n;}void prm(P *p){	if (!p)		return;	if (p->owner)		*p->owner = NULL;	if (p->ptr)		vunlock(p->ptr);	pfree(deque_f(P, link, p));}P *pset(P *n, P *p){	if (n != p) {		n->b = p->b;		n->ofst = p->ofst;		n->hdr = p->hdr;		if (n->ptr)			vunlock(n->ptr);		if (p->ptr) {			n->ptr = p->ptr;			vupcount(n->ptr);		} else			n->ptr = vlock(vmem, n->hdr->seg);		n->byte = p->byte;		n->line = p->line;		n->col = p->col;		n->valcol = p->valcol;	}	return n;}P *p_goto_bof(P *p){	return pset(p, p->b->bof);}P *p_goto_eof(P *p){	return pset(p, p->b->eof);}/* is p at the beginning of file? */int pisbof(P *p){	return p->hdr == p->b->bof->hdr && !p->ofst;}/* is p at the end of file? */int piseof(P *p){	return p->ofst == GSIZE(p->hdr);}/* is p at the end of line? */int piseol(P *p){	int c;	if (piseof(p))		return 1;	c = brc(p);	if (c == '\n')		return 1;	if (p->b->o.crlf)		if (c == '\r') {			P *q = pdup(p, USTR "piseol");			pfwrd(q, 1L);			if (pgetb(q) == '\n') {				prm(q);				return 1;			} else				prm(q);		}	return 0;}/* is p at the beginning of line? */int pisbol(P *p){	int c;	if (pisbof(p))		return 1;	c = prgetb(p);	pgetb(p);	return c == '\n';}/* is p at the beginning of word? */int pisbow(P *p){	P *q = pdup(p, USTR "pisbow");	int c = brc(p);	int d = prgetc(q);	prm(q);	if (joe_isalnum_(p->b->o.charmap,c) && (!joe_isalnum_(p->b->o.charmap,d) || pisbof(p)))		return 1;	else		return 0;}/* is p at the end of word? */int piseow(P *p){	P *q = pdup(p, USTR "piseow");	int d = brc(q);	int c = prgetc(q);	prm(q);	if (joe_isalnum_(p->b->o.charmap,c) && (!joe_isalnum_(p->b->o.charmap,d) || piseof(p)))		return 1;	else		return 0;}/* is p on the blank line (ie. full of spaces/tabs)? */int pisblank(P *p){	P *q = pdup(p, USTR "pisblank");	p_goto_bol(q);	while (joe_isblank(p->b->o.charmap,brc(q)))		pgetb(q);	if (piseol(q)) {		prm(q);		return 1;	} else {		prm(q);		return 0;	}}/* is p at end of line or spaces followed by end of line? */int piseolblank(P *p){	P *q = pdup(p, USTR "piseolblank");	while (joe_isblank(p->b->o.charmap,brc(q)))		pgetb(q);	if (piseol(q)) {		prm(q);		return 1;	} else {		prm(q);		return 0;	}}/* return column of first nonblank character */long pisindent(P *p){	P *q = pdup(p, USTR "pisindent");	long col;	p_goto_bol(q);	while (joe_isblank(p->b->o.charmap,brc(q)))		pgetc(q);	col = q->col;	prm(q);	return col;}/* return true if all characters to left of cursor match c */int pispure(P *p,int c){	P *q = pdup(p, USTR "pispure");	p_goto_bol(q);	while (q->byte!=p->byte)		if (pgetc(q)!=c) {			prm(q);			return 0;                }	prm(q);	return 1;}int pnext(P *p){	if (p->hdr == p->b->eof->hdr) {		p->ofst = GSIZE(p->hdr);		return 0;	}	p->hdr = p->hdr->link.next;	p->ofst = 0;	vunlock(p->ptr);	p->ptr = vlock(vmem, p->hdr->seg);	return 1;}int pprev(P *p){	if (p->hdr == p->b->bof->hdr) {		p->ofst = 0;		return 0;	}	p->hdr = p->hdr->link.prev;	p->ofst = GSIZE(p->hdr);	vunlock(p->ptr);	p->ptr = vlock(vmem, p->hdr->seg);	return 1;}/* return current byte and move p to the next byte.  column will be unchanged. */int pgetb(P *p){	unsigned char c;	if (p->ofst == GSIZE(p->hdr))		return NO_MORE_DATA;	c = GCHAR(p);	if (++p->ofst == GSIZE(p->hdr))		pnext(p);	++p->byte;	if (c == '\n') {		++(p->line);		p->col = 0;		p->valcol = 1;	} else if (p->b->o.crlf && c == '\r') {		if (brc(p) == '\n')			return pgetb(p);		else			p->valcol = 0;	} else {		p->valcol = 0;	}	return c;}/* return current character and move p to the next character.  column will be updated if it was valid. */int pgetc(P *p){	if (p->b->o.charmap->type) {		int val;		int c; /* , oc; */		int d;		int n; /* , m; */		int wid = 0;		val = p->valcol;	/* Remember if column number was valid */		c = pgetb(p);		/* Get first byte */		/* oc = c; */		if (c==NO_MORE_DATA)			return c;		if ((c&0xE0)==0xC0) { /* Two bytes */			n = 1;			c &= 0x1F;		} else if ((c&0xF0)==0xE0) { /* Three bytes */			n = 2;			c &= 0x0F;		} else if ((c&0xF8)==0xF0) { /* Four bytes */			n = 3;			c &= 0x07;		} else if ((c&0xFC)==0xF8) { /* Five bytes */			n = 4;			c &= 0x03;		} else if ((c&0xFE)==0xFC) { /* Six bytes */			n = 5;			c &= 0x01;		} else if ((c&0x80)==0x00) { /* One byte */			n = 0;		} else { /* 128-191, 254, 255: Not a valid UTF-8 start character */			n = 0;			c = 'X';			/* c -= 384; */		}		/* m = n; */		if (n) {			while (n) {				d = brc(p);				if ((d&0xC0)!=0x80)					break;				pgetb(p);				c = ((c<<6)|(d&0x3F));				--n;			}			if (n) { /* FIXME: there was a bad UTF-8 sequence */				/* How to represent this? */				/* pbkwd(p,m-n);				c = oc - 384; */				c = 'X';				wid = 1;			} else if (val)				wid = joe_wcwidth(1,c);		} else {			wid = 1;		}		if (val) { /* Update column no. if it was valid to start with */			p->valcol = 1;			if (c=='\t')				p->col += (p->b->o.tab) - (p->col) % (p->b->o.tab);			else if (c=='\n')				p->col = 0;			else				p->col += wid;		}		return c;	} else {		unsigned char c;		if (p->ofst == GSIZE(p->hdr))			return NO_MORE_DATA;		c = GCHAR(p);		if (++p->ofst == GSIZE(p->hdr))			pnext(p);		++p->byte;		if (c == '\n') {			++(p->line);			p->col = 0;			p->valcol = 1;		} else if (p->b->o.crlf && c == '\r') {			if (brc(p) == '\n')				return pgetc(p);			else				++p->col;		} else {			if (c == '\t')				p->col += (p->b->o.tab) - (p->col) % (p->b->o.tab);			else				++(p->col);		}		return c;	}}/* move p n characters forward */P *pfwrd(P *p, long n){	if (!n)		return p;	p->valcol = 0;	do {		if (p->ofst == GSIZE(p->hdr))			do {				if (!p->ofst) {					p->byte += GSIZE(p->hdr);

⌨️ 快捷键说明

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