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

📄 uerror.c

📁 举世闻名的joe记事本源程序
💻 C
字号:
/* *	Compiler error handler *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"/* Error database */typedef struct error ERROR;struct error {	LINK(ERROR) link;	/* Linked list of errors */	long line;		/* Target line number */	long org;		/* Original target line number */	unsigned char *file;	/* Target file name */	long src;		/* Error-file line number */	unsigned char *msg;	/* The message */} errors = { { &errors, &errors} };ERROR *errptr = &errors;	/* Current error row */B *errbuf = NULL;		/* Buffer with error messages *//* Function which allows stepping through all error buffers,   for multi-file search and replace.  Give it a buffer.  It finds next   buffer in error list.  Look at 'berror' for error information. *//* This is made to work like bafter: it does not increment refcount of buffer */B *beafter(B *b){	struct error *e;	unsigned char *name = b->name;	if (!name) name = USTR "";	for (e = errors.link.next; e != &errors; e = e->link.next)		if (!zcmp(name, e->file))			break;	if (e == &errors) {		/* Given buffer is not in list?  Return first buffer in list. */		e = errors.link.next;	}	while (e != &errors && !zcmp(name, e->file))		e = e->link.next;	berror = 0;	if (e != &errors) {		B *b = bfind(e->file);		/* bfind bumps refcount, so we have to unbump it */		if (b->count == 1)			b->orphan = 1; /* Oops */		else			--b->count;		return b;	}	return 0;}/* Insert and delete notices */void inserr(unsigned char *name, long int where, long int n, int bol){	ERROR *e;	if (!n)		return;	if (name) {		for (e = errors.link.next; e != &errors; e = e->link.next) {			if (!zcmp(e->file, name)) {				if (e->line > where)					e->line += n;				else if (e->line == where && bol)					e->line += n;			}		}	}}void delerr(unsigned char *name, long int where, long int n){	ERROR *e;	if (!n)		return;	if (name) {		for (e = errors.link.next; e != &errors; e = e->link.next) {			if (!zcmp(e->file, name)) {				if (e->line > where + n)					e->line -= n;				else if (e->line > where)					e->line = where;			}		}	}}/* Abort notice */void abrerr(unsigned char *name){	ERROR *e;	if (name)		for (e = errors.link.next; e != &errors; e = e->link.next)			if (!zcmp(e->file, name))				e->line = e->org;}/* Save notice */void saverr(unsigned char *name){	ERROR *e;	if (name)		for (e = errors.link.next; e != &errors; e = e->link.next)			if (!zcmp(e->file, name))				e->org = e->line;}/* Pool of free error nodes */ERROR errnodes = { {&errnodes, &errnodes} };/* Free an error node */static void freeerr(ERROR *n){	vsrm(n->file);	vsrm(n->msg);	enquef(ERROR, link, &errnodes, n);}/* Free all errors */static void freeall(void){	while (!qempty(ERROR, link, &errors))		freeerr(deque_f(ERROR, link, errors.link.next));	errptr = &errors;}/* Parse error messages into database *//* From joe's joe 2.9 *//* First word (allowing ., /, _ and -) with a . is the file name.  Next number   is line number.  Then there should be a ':' */static void parseone(struct charmap *map,unsigned char *s,unsigned char **rtn_name,long *rtn_line){	int x, y, flg;	unsigned char *name = NULL;	long line = -1;	y=0;	flg=0;	do {		/* Skip to first word */		for (x = y; s[x] && !(joe_isalnum_(map,s[x]) || s[x] == '.' || s[x] == '/'); ++x) ;		/* Skip to end of first word */		for (y = x; joe_isalnum_(map,s[y]) || s[y] == '.' || s[y] == '/' || s[y]=='-'; ++y)			if (s[y] == '.')				flg = 1;	} while (!flg && x!=y);	/* Save file name */	if (x != y)		name = vsncpy(NULL, 0, s + x, y - x);	/* Skip to first number */	for (x = y; s[x] && (s[x] < '0' || s[x] > '9'); ++x) ;	/* Skip to end of first number */	for (y = x; s[y] >= '0' && s[y] <= '9'; ++y) ;	/* Save line number */	if (x != y)		sscanf((char *)(s + x), "%ld", &line);	if (line != -1)		--line;	/* Look for ':' */	flg = 0;	while (s[y]) {	/* Allow : anywhere on line: works for MIPS C compiler *//*	for (y = 0; s[y];)*/		if (s[y]==':') {			flg = 1;			break;		}		++y;	}	if (!flg)		line = -1;	*rtn_name = name;	*rtn_line = line;}/* Parser for file name lists from grep, find and ls. * * filename * filename:* * filename:line-number:* */void parseone_grep(struct charmap *map,unsigned char *s,unsigned char **rtn_name,long *rtn_line){	int y;	unsigned char *name = NULL;	long line = -1;	/* Skip to first : or end of line */	for (y = 0;s[y] && s[y] != ':';++y);	if (y) {		/* This should be the file name */		name = vsncpy(NULL,0,s,y);		line = 0;		if (s[y] == ':') {			/* Maybe there's a line number */			++y;			while (s[y] >= '0' && s[y] <= '9')				line = line * 10 + (s[y++] - '0');			--line;			if (line < 0 || s[y] != ':') {				/* Line number is only valid if there's a second : */				line = 0;			}		}	}	*rtn_name = name;	*rtn_line = line;}static int parseit(struct charmap *map,unsigned char *s, long int row,  void (*parseone)(struct charmap *map, unsigned char *s, unsigned char **rtn_name, long *rtn_line)){	unsigned char *name = NULL;	long line = -1;	ERROR *err;	parseone(map,s,&name,&line);	if (name) {		if (line != -1) {			/* We have an error */			err = (ERROR *) alitem(&errnodes, sizeof(ERROR));			err->file = name;			err->org = err->line = line;			err->src = row;			err->msg = vsncpy(NULL, 0, sc("\\i"));			err->msg = vsncpy(sv(err->msg), sv(s));			enqueb(ERROR, link, &errors, err);			return 1;		} else			vsrm(name);	}	return 0;}/* Parse the error output contained in a buffer */static long parserr(B *b){	P *p = pdup(b->bof, USTR "parserr");	P *q = pdup(p, USTR "parserr");	long nerrs = 0;	freeall();	do {		unsigned char *s;		pset(q, p);		p_goto_eol(p);		s = brvs(q, (int) (p->byte - q->byte));		if (s) {			nerrs += parseit(b->o.charmap, s, q->line, (b->parseone ? b->parseone : parseone));			vsrm(s);		}	} while (pgetc(p) != NO_MORE_DATA);	prm(p);	prm(q);	return nerrs;}BW *find_a_good_bw(B *b){	W *w;	BW *bw = 0;	/* Find lowest window with buffer */	if ((w = maint->topwin) != NULL) {		do {			if ((w->watom->what&TYPETW) && ((BW *)w->object)->b==b && w->y>=0)				bw = (BW *)w->object;			w = w->link.next;		} while (w != maint->topwin);	}	if (bw)		return bw;	/* Otherwise just find lowest window */	if ((w = maint->topwin) != NULL) {		do {			if ((w->watom->what&TYPETW) && w->y>=0)				bw = (BW *)w->object;			w = w->link.next;		} while (w != maint->topwin);	}	return bw;}int parserrb(B *b){	BW *bw;	int n;	errbuf = b;	freeall();	n = parserr(b);	bw = find_a_good_bw(b);	if (n)		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("%d messages found")), n);	else		joe_snprintf_0(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("No messages found")));	msgnw(bw->parent, msgbuf);	return 0;}int uparserr(BW *bw){	int n;	errbuf = bw->b;	freeall();	n = parserr(bw->b);	if (n)		joe_snprintf_1(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("%d messages found")), n);	else		joe_snprintf_0(msgbuf, JOE_MSGBUFSIZE, joe_gettext(_("No messages found")));	msgnw(bw->parent, msgbuf);	return 0;}int jump_to_file_line(BW *bw,unsigned char *file,int line,unsigned char *msg){	int omid;	if (!bw->b->name || zcmp(file, bw->b->name)) {		if (doswitch(bw, vsdup(file), NULL, NULL))			return -1;		bw = (BW *) maint->curwin->object;	}	omid = mid;	mid = 1;	pline(bw->cursor, line);	dofollows();	mid = omid;	bw->cursor->xcol = piscol(bw->cursor);	msgnw(bw->parent, msg);	return 0;}/* Show current message */int ucurrent_msg(BW *bw){	if (errptr != &errors) {		msgnw(bw->parent, errptr->msg);		return 0;	} else {		msgnw(bw->parent, joe_gettext(_("No messages")));		return -1;	}}/* Find line in error database: return pointer to message */ERROR *srcherr(BW *bw,unsigned char *file,long line){	ERROR *p;	for (p = errors.link.next; p != &errors; p=p->link.next)		if (!zcmp(p->file,file) && p->org == line) {			errptr = p;			setline(errbuf, errptr->src);			return errptr;			}	return 0;}int ujump(BW *bw){	int rtn = -1;	P *p = pdup(bw->cursor, USTR "ujump");	P *q = pdup(p, USTR "ujump");	unsigned char *s;	p_goto_bol(p);	p_goto_eol(q);	s = brvs(p, (int) (q->byte - p->byte));	prm(p);	prm(q);	if (s) {		unsigned char *name = NULL;		long line = -1;		if (bw->b->parseone)			bw->b->parseone(bw->b->o.charmap,s,&name,&line);		else			parseone(bw->b->o.charmap,s,&name,&line);		if (name && line != -1) {			ERROR *p = srcherr(bw, name, line);			uprevw((BASE *)bw);			/* Check that we made it to a tw */			if (p)				rtn = jump_to_file_line(maint->curwin->object,name,p->line,NULL /* p->msg */);			else				rtn = jump_to_file_line(maint->curwin->object,name,line,NULL);			vsrm(name);		}		vsrm(s);	}	return rtn;}int unxterr(BW *bw){	if (errptr->link.next == &errors) {		msgnw(bw->parent, joe_gettext(_("No more errors")));		return -1;	}	errptr = errptr->link.next;	setline(errbuf, errptr->src);	return jump_to_file_line(bw,errptr->file,errptr->line,NULL /* errptr->msg */);}int uprverr(BW *bw){	if (errptr->link.prev == &errors) {		msgnw(bw->parent, joe_gettext(_("No more errors")));		return -1;	}	errptr = errptr->link.prev;	setline(errbuf, errptr->src);	return jump_to_file_line(bw,errptr->file,errptr->line,NULL /* errptr->msg */);}

⌨️ 快捷键说明

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