📄 uerror.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 + -