📄 cmd1.c
字号:
* * For non-error lines, or unparsable error lines, this function returns NULL. * Normally, though, it alters errfile and errline, and returns a pointer to * the description. */static char *parse_errmsg(text) REG char *text;{ REG char *cpy; long atol();# if COHERENT || TOS /* any Mark Williams compiler */ /* Get the line number. If no line number, then ignore this line. */ errline = atol(text); if (errline == 0L) return (char *)0; /* Skip to the start of the filename */ while (*text && *text++ != ':') { } if (!*text++) return (char *)0; /* copy the filename to errfile */ for (cpy = errfile; *text && (*cpy++ = *text++) != ':'; ) { } if (!*text++) return (char *)0; cpy[-1] = '\0'; return text;# else /* not a Mark Williams compiler */ char *errmsg; /* the error message is the whole line, by default */ errmsg = text; /* skip leading garbage */ while (*text && !isalnum(*text)) { text++; } /* copy over the filename */ cpy = errfile; while(isalnum(*text) || *text == '.') { *cpy++ = *text++; } *cpy = '\0'; /* ignore the name "Error" and filenames that contain a '/' */ if (*text == '/' || !*errfile || !strcmp(errfile + 1, "rror") || access(errfile, 0) < 0) { return (char *)0; } /* skip garbage between filename and line number */ while (*text && !isdigit(*text)) { text++; } /* if the number is part of a larger word, then ignore this line */ if (*text && isalpha(text[-1])) { return (char *)0; } /* get the error line */ errline = 0L; while (isdigit(*text)) { errline *= 10; errline += (*text - '0'); text++; } /* any line which lacks a filename or line number should be ignored */ if (!errfile[0] || !errline) { return (char *)0; } /* locate the beginning of the error description */ while (*text && !isspace(*text)) { text++; } while (*text) {# ifndef CRUNCH /* skip "error #:" and "warning #:" clauses */ if (!strncmp(text + 1, "rror ", 5) || !strncmp(text + 1, "arning ", 7) || !strncmp(text + 1, "atal error", 10)) { do { text++; } while (*text && *text != ':'); continue; }# endif /* anything other than whitespace or a colon is important */ if (!isspace(*text) && *text != ':') { errmsg = text; break; } /* else keep looking... */ text++; } return errmsg;# endif /* not COHERENT */}/*ARGSUSED*/void cmd_errlist(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ static long endline;/* original number of lines in this file */ static long offset; /* offset of the next line in the errlist file */ int i; char *errmsg; /* if a new errlist file is named, open it */ if (extra && extra[0]) { /* close the old one */ if (errfd >= 0) { close(errfd); } /* open the new one */ errfd = open(extra, O_RDONLY); offset = 0L; endline = nlines; } else if (errfd < 0) { /* open the default file */ errfd = open(ERRLIST, O_RDONLY); offset = 0L; endline = nlines; } /* do we have an errlist file now? */ if (errfd < 0) { msg("There is no errlist file"); beep(); return; } /* find the next error message in the file */ do { /* read the next line from the errlist */ lseek(errfd, offset, 0); if (tread(errfd, tmpblk.c, (unsigned)BLKSIZE) <= 0) { msg("No more errors"); beep(); close(errfd); errfd = -2; return; } for (i = 0; tmpblk.c[i] != '\n'; i++) { } tmpblk.c[i++] = 0; /* look for an error message in the line */ errmsg = parse_errmsg(tmpblk.c); if (!errmsg) { offset += i; } } while (!errmsg); /* switch to the file containing the error, if this isn't it */ if (strcmp(origname, errfile)) { if (!tmpabort(bang)) { msg("Use :er! to abort changes, or :w to save changes"); beep(); return; } tmpstart(errfile); endline = nlines; } else if (endline == 0L) { endline = nlines; } /* go to the line where the error was detected */ cursor = MARK_AT_LINE(errline + (nlines - endline)); if (cursor > MARK_LAST) { cursor = MARK_LAST; } if (mode == MODE_VI) { redraw(cursor, FALSE); } /* display the error message */#ifdef CRUNCH msg("%.70s", errmsg);#else if (nlines > endline) { msg("line %ld(+%ld): %.60s", errline, nlines - endline, errmsg); } else if (nlines < endline) { msg("line %ld(-%ld): %.60s", errline, endline - nlines, errmsg); } else { msg("line %ld: %.65s", errline, errmsg); }#endif /* remember where the NEXT error line will start */ offset += i;}/*ARGSUSED*/void cmd_make(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ BLK buf; /* if the file hasn't been saved, then complain unless ! */ if (tstflag(file, MODIFIED) && !bang) { msg("\"%s\" not saved yet", origname); return; } /* build the command */ sprintf(buf.c, "%s %s %s%s", (cmd == CMD_CC ? o_cc : o_make), extra, REDIRECT, ERRLIST); qaddstr(buf.c); addch('\n'); /* close the old errlist file, if any */ if (errfd >= 0) { close(errfd); errfd = -3; } /* run the command, with curses temporarily disabled */ suspend_curses(); system(buf.c); resume_curses(mode == MODE_EX); if (mode == MODE_COLON) mode = MODE_VI; /* run the "errlist" command */ cmd_errlist(MARK_UNSET, MARK_UNSET, cmd, bang, ERRLIST);}#endif#ifndef NO_COLOR/* figure out the number of text colors we use with this configuration */# ifndef NO_POPUP# ifndef NO_VISIBLE# define NCOLORS 7# else# define NCOLORS 6# endif# else# ifndef NO_VISIBLE# define NCOLORS 6# else# define NCOLORS 5# endif# endif/* the attribute bytes used in each of "when"s */static char bytes[NCOLORS];static struct{ char *word; /* a legal word */ int type; /* what type of word this is */ int val; /* some other value */} words[] ={ {"normal", 1, A_NORMAL}, /* all "when" names must come */ {"standout", 1, A_STANDOUT}, /* at the top of the list. */ {"bold", 1, A_BOLD}, /* The first 3 must be normal,*/ {"underlined", 1, A_UNDERLINE}, /* standout, and bold; the */ {"italics", 1, A_ALTCHARSET}, /* remaining names follow. */#ifndef NO_POPUP {"popup", 1, A_POPUP},#endif#ifndef NO_VISIBLE {"visible", 1, A_VISIBLE},#endif {"black", 3, 0x00}, /* The color names start right*/ {"blue", 3, 0x01}, /* after the "when" names. */ {"green", 3, 0x02}, {"cyan", 3, 0x03}, {"red", 3, 0x04}, {"magenta", 3, 0x05}, {"brown", 3, 0x06}, {"white", 3, 0x07}, {"yellow", 3, 0x0E}, /* bright brown */ {"gray", 3, 0x08}, /* bright black? of course! */ {"grey", 3, 0x08}, {"bright", 2, 0x08}, {"light", 2, 0x08}, {"blinking", 2, 0x80}, {"on", 0, 0}, {"n", 1, A_NORMAL}, {"s", 1, A_STANDOUT}, {"b", 1, A_BOLD}, {"u", 1, A_UNDERLINE}, {"i", 1, A_ALTCHARSET},#ifndef NO_POPUP {"p", 1, A_POPUP}, {"menu", 1, A_POPUP},#endif#ifndef NO_VISIBLE {"v", 1, A_VISIBLE},#endif {(char *)0, 0, 0}};/*ARGSUSED*/void cmd_color(frommark, tomark, cmd, bang, extra) MARK frommark, tomark; CMD cmd; int bang; char *extra;{ int attrbyte; int cmode; int nowbg; /* BOOLEAN: is the next color background? */ REG char *scan; REG i;#ifndef CRUNCH /* if no args are given, then report the current colors */ if (!*extra) { /* if no colors are set, then say so */ if (!bytes[0]) { msg("no colors have been set"); return; } /* report all five color combinations */ for (i = 0; i < NCOLORS; i++) { qaddstr("color "); qaddstr(words[i].word); qaddch(' '); if (bytes[i] & 0x80) qaddstr("blinking "); switch (bytes[i] & 0xf) { case 0x08: qaddstr("gray"); break; case 0x0e: qaddstr("yellow"); break; case 0x0f: qaddstr("bright white");break; default: if (bytes[i] & 0x08) qaddstr("light "); qaddstr(words[(bytes[i] & 0x07) + NCOLORS].word); } qaddstr(" on "); qaddstr(words[((bytes[i] >> 4) & 0x07) + NCOLORS].word); addch('\n'); exrefresh(); } return; }#endif /* The default background color is the same as "normal" chars. * There is no default foreground color. */ cmode = A_NORMAL; attrbyte = bytes[0] & 0x70; nowbg = FALSE; /* parse each word in the "extra" text */ for (scan = extra; *extra; extra = scan) { /* locate the end of the word */ while (*scan && *scan != ' ') { scan++; } /* skip whitespace at the end of the word */ while(*scan == ' ') { *scan++ = '\0'; } /* lookup the word */ for (i = 0; words[i].word && strcmp(words[i].word, extra); i++) { } /* if not a word, then complain */ if (!words[i].word) { msg("Invalid color name: %s", extra); return; } /* process the word */ switch (words[i].type) { case 1: cmode = words[i].val; break; case 2: attrbyte |= words[i].val; break; case 3: if (nowbg) attrbyte = ((attrbyte & ~0x70) | ((words[i].val & 0x07) << 4)); else attrbyte |= words[i].val; nowbg = TRUE; break; } } /* if nowbg isn't set now, then we were never given a foreground color */ if (!nowbg) { msg("usage: color [when] [\"bright\"] [\"blinking\"] foreground [background]"); return; } /* the first ":color" command MUST define the "normal" colors */ if (!bytes[0]) cmode = A_NORMAL; /* we should now have a cmode and an attribute byte... */ /* set the color */ setcolor(cmode, attrbyte); /* remember what we just did */ bytes[cmode] = attrbyte; /* if the other colors haven't been set yet, then set them to defaults */ if (!bytes[1]) { /* standout is the opposite of normal */ bytes[1] = ((attrbyte << 4) & 0x70 | (attrbyte >> 4) & 0x07); setcolor(A_STANDOUT, bytes[1]); /* if "normal" isn't bright, then bold defaults to normal+bright * else bold defaults to bright white. */ bytes[2] = attrbyte | ((attrbyte & 0x08) ? 0x0f : 0x08); setcolor(A_BOLD, bytes[2]); /* all others default to the "standout" colors, without blinking */ for (i = 3; i < NCOLORS; i++) { bytes[i] = (bytes[1] & 0x7f); setcolor(words[i].val, bytes[i]); } } /* force a redraw, so we see the new colors */ redraw(MARK_UNSET, FALSE);}void savecolor(fd) int fd; /* file descriptor to write colors to */{ int i; char buf[80]; /* if no colors are set, then return */ if (!bytes[0]) { return; } /* save all five color combinations */ for (i = 0; i < NCOLORS; i++) { strcpy(buf, "color "); strcat(buf, words[i].word); strcat(buf, " "); if (bytes[i] & 0x80) strcat(buf, "blinking "); switch (bytes[i] & 0xf) { case 0x08: strcat(buf, "gray"); break; case 0x0e: strcat(buf, "yellow"); break; case 0x0f: strcat(buf, "bright white");break; default: if (bytes[i] & 0x08) strcat(buf, "light "); strcat(buf, words[(bytes[i] & 0x07) + NCOLORS].word); } strcat(buf, " on "); strcat(buf, words[((bytes[i] >> 4) & 0x07) + NCOLORS].word); strcat(buf, "\n"); twrite(fd, buf, (unsigned)strlen(buf)); }}#endif#ifdef SIGTSTP/* temporarily suspend elvis *//*ARGSUSED*/void cmd_suspend(frommark, tomark, cmd, bang, extra) MARK frommark; MARK tomark; CMD cmd; int bang; char *extra;{ void (*func)(); /* stores the previous setting of SIGTSTP */#if ANY_UNIX /* the Bourne shell can't handle ^Z */ if (!strcmp(o_shell, "/bin/sh")) { msg("The /bin/sh shell doesn't support ^Z"); return; }#endif move(LINES - 1, 0); if (tstflag(file, MODIFIED)) { addstr("Warning: \""); addstr(origname); addstr("\" modified but not yet saved"); clrtoeol(); } refresh(); suspend_curses(); func = signal(SIGTSTP, SIG_DFL); kill (0, SIGTSTP); /* the process stops and resumes here */ signal(SIGTSTP, func); resume_curses(TRUE); if (mode == MODE_VI || mode == MODE_COLON) redraw(MARK_UNSET, FALSE); else refresh ();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -