📄 more.c
字号:
putchar ('\r'); erase (0); skipf (nlines); return (0); case 'p': if (no_intty) { write (2, &bell, 1); return (-1); } putchar ('\r'); erase (0); if (nlines == 0) nlines++; skipf (-nlines); return (0); case '!': do_shell (filename); return (-1); case 'q': case 'Q': end_it (); default: write (2, &bell, 1); return (-1); }}/*** Read a decimal number from the terminal. Set cmd to the non-digit which** terminates the number.*/number(cmd)char *cmd;{ register int i; i = 0; ch = otty.sg_kill; for (;;) { ch = readch (); if (ch >= '0' && ch <= '9') i = i*10 + ch - '0'; else if (ch == otty.sg_kill) i = 0; else { *cmd = ch; break; } } return (i);}do_shell (filename)char *filename;{ char cmdbuf[80]; kill_line (); pr ("!"); fflush (stdout); promptlen = 1; if (lastp) pr (shell_line); else { ttyin (cmdbuf, 78, '!'); if (expand (shell_line, cmdbuf)) { kill_line (); promptlen = prtf ("!%s", shell_line); } } fflush (stdout); write (2, "\n", 1); promptlen = 0; shellp = 1; execute (filename, shell, shell, "-c", shell_line, 0);}/*** Search for nth ocurrence of regular expression contained in buf in the file*/search (buf, file, n)char buf[];FILE *file;register int n;{ long startline = Ftell (file); register long line1 = startline; register long line2 = startline; register long line3 = startline; register int lncount; int saveln, rv, re_exec(); char *s, *re_comp(); context.line = saveln = Currline; context.chrctr = startline; lncount = 0; if ((s = re_comp (buf)) != 0) error (s); while (!feof (file)) { line3 = line2; line2 = line1; line1 = Ftell (file); rdline (file); lncount++; if ((rv = re_exec (Line)) == 1) if (--n == 0) { if (lncount > 3 || (lncount > 1 && no_intty)) { pr ("\n"); if (clreol) cleareol (); pr("...skipping\n"); } if (!no_intty) { Currline -= (lncount >= 3 ? 3 : lncount); Fseek (file, line3); if (noscroll) if (clreol) { home (); cleareol (); } else doclear (); } else { kill_line (); if (noscroll) if (clreol) { home (); cleareol (); } else doclear (); pr (Line); putchar ('\n'); } break; } else if (rv == -1) error ("Regular expression botch"); } if (feof (file)) { if (!no_intty) { /* file->_flag &= ~_IOEOF; /* why doesn't fseek do this ??!!??! */ Currline = saveln; Fseek (file, startline); } else { pr ("\nPattern not found\n"); end_it (); } error ("Pattern not found"); }}/*VARARGS2*/execute (filename, cmd, va_alist)char *filename;char *cmd;va_dcl{ int id; int n; va_list argp; fflush (stdout); reset_tty (); for (n = 10; (id = fork ()) < 0 && n > 0; n--) sleep (5); if (id == 0) { if (!isatty(0)) { close(0); open("/dev/tty", 0); } va_start(argp); execv (cmd, argp); write (2, "exec failed\n", 12); exit (1); va_end(argp); /* balance {}'s for some UNIX's */ } if (id > 0) { signal (SIGINT, SIG_IGN); signal (SIGQUIT, SIG_IGN); if (catch_susp) signal(SIGTSTP, SIG_DFL); while (wait(0) > 0); signal (SIGINT, end_it); signal (SIGQUIT, onquit); if (catch_susp) signal(SIGTSTP, onsusp); } else write(2, "can't fork\n", 11); set_tty (); pr ("------------------------\n"); prompt (filename);}/*** Skip n lines in the file f*/skiplns (n, f)register int n;register FILE *f;{ register char c; while (n > 0) { while ((c = Getc (f)) != '\n') if (c == EOF) return; n--; Currline++; }}/*** Skip nskip files in the file list (from the command line). Nskip may be** negative.*/skipf (nskip)register int nskip;{ if (nskip == 0) return; if (nskip > 0) { if (fnum + nskip > nfiles - 1) nskip = nfiles - fnum - 1; } else if (within) ++fnum; fnum += nskip; if (fnum < 0) fnum = 0; pr ("\n...Skipping "); pr ("\n"); if (clreol) cleareol (); pr ("...Skipping "); pr (nskip > 0 ? "to file " : "back to file "); pr (fnames[fnum]); pr ("\n"); if (clreol) cleareol (); pr ("\n"); --fnum;}/*----------------------------- Terminal I/O -------------------------------*/initterm (){ char buf[TBUFSIZ]; static char clearbuf[TBUFSIZ]; char *clearptr, *padstr; int ldisc; int lmode; char *term; int tgrp; struct winsize win; char *tgoto();retry: if (!(no_tty = ioctl(fileno(stdout), TIOCGETP, &otty))) { if (ioctl(fileno(stdout), TIOCLGET, &lmode) < 0) { perror("TIOCLGET"); exit(1); } docrterase = ((lmode & LCRTERA) != 0); docrtkill = ((lmode & LCRTKIL) != 0); /* * Wait until we're in the foreground before we save the * the terminal modes. */ if (ioctl(fileno(stdout), TIOCGPGRP, &tgrp) < 0) { perror("TIOCGPGRP"); exit(1); } if (tgrp != getpgrp(0)) { kill(0, SIGTTOU); goto retry; } if ((term = getenv("TERM")) == 0 || tgetent(buf, term) <= 0) { dumb++; ul_opt = 0; } else { if (ioctl(fileno(stdout), TIOCGWINSZ, &win) < 0) { Lpp = tgetnum("li"); Mcol = tgetnum("co"); } else { if ((Lpp = win.ws_row) == 0) Lpp = tgetnum("li"); if ((Mcol = win.ws_col) == 0) Mcol = tgetnum("co"); } if ((Lpp <= 0) || tgetflag("hc")) { hard++; /* Hard copy terminal */ Lpp = 24; } if (tgetflag("xn")) eatnl++; /* Eat newline at last column + 1; dec, concept */ if (Mcol <= 0) Mcol = 80; if (tailequ (fnames[0], "page") || !hard && tgetflag("ns")) noscroll++; Wrap = tgetflag("am"); bad_so = tgetflag ("xs"); clearptr = clearbuf; eraseln = tgetstr("ce",&clearptr); Clear = tgetstr("cl", &clearptr); Senter = tgetstr("so", &clearptr); Sexit = tgetstr("se", &clearptr); if ((soglitch = tgetnum("sg")) < 0) soglitch = 0; /* * Set up for underlining: some terminals don't need it; * others have start/stop sequences, still others have an * underline char sequence which is assumed to move the * cursor forward one character. If underline sequence * isn't available, settle for standout sequence. */ if (tgetflag("ul") || tgetflag("os")) ul_opt = 0; if ((chUL = tgetstr("uc", &clearptr)) == NULL ) chUL = ""; if (((ULenter = tgetstr("us", &clearptr)) == NULL || (ULexit = tgetstr("ue", &clearptr)) == NULL) && !*chUL) { if ((ULenter = Senter) == NULL || (ULexit = Sexit) == NULL) { ULenter = ""; ULexit = ""; } else ulglitch = soglitch; } else { if ((ulglitch = tgetnum("ug")) < 0) ulglitch = 0; } if (padstr = tgetstr("pc", &clearptr)) PC = *padstr; Home = tgetstr("ho",&clearptr); if (Home == 0 || *Home == '\0') { if ((cursorm = tgetstr("cm", &clearptr)) != NULL) { strcpy(cursorhome, tgoto(cursorm, 0, 0)); Home = cursorhome; } } EodClr = tgetstr("cd", &clearptr); if ((chBS = tgetstr("bc", &clearptr)) == NULL) chBS = "\b"; } if ((shell = getenv("SHELL")) == NULL) shell = "/bin/sh"; } no_intty = ioctl(fileno(stdin), TIOCGETP, &otty); (void)ioctl(fileno(stderr), TIOCGETP, &otty); savetty = otty; ospeed = otty.sg_ospeed; slow_tty = ospeed < B1200; hardtabs = (otty.sg_flags & TBDELAY) != XTABS; if (!no_tty) { otty.sg_flags &= ~ECHO; if (MBIT == CBREAK || !slow_tty) otty.sg_flags |= MBIT; }}readch (){ char ch; extern int errno; errno = 0; if (read (2, &ch, 1) <= 0) if (errno != EINTR) end_it(); else ch = otty.sg_kill; return (ch);}static char BS = '\b';static char *BSB = "\b \b";static char CARAT = '^';#define ERASEONECHAR \ if (docrterase) \ write (2, BSB, sizeof(BSB)); \ else \ write (2, &BS, sizeof(BS));ttyin (buf, nmax, pchar)char buf[];register int nmax;char pchar;{ register char *sptr; register char ch; register int slash = 0; int maxlen; char cbuf; sptr = buf; maxlen = 0; while (sptr - buf < nmax) { if (promptlen > maxlen) maxlen = promptlen; ch = readch (); if (ch == '\\') { slash++; } else if ((ch == otty.sg_erase) && !slash) { if (sptr > buf) { --promptlen; ERASEONECHAR --sptr; if ((*sptr < ' ' && *sptr != '\n') || *sptr == RUBOUT) { --promptlen; ERASEONECHAR } continue; } else { if (!eraseln) promptlen = maxlen; longjmp (restore, 1); } } else if ((ch == otty.sg_kill) && !slash) { if (hard) { show (ch); putchar ('\n'); putchar (pchar); } else { putchar ('\r'); putchar (pchar); if (eraseln) erase (1); else if (docrtkill) while (promptlen-- > 1) write (2, BSB, sizeof(BSB)); promptlen = 1; } sptr = buf; fflush (stdout); continue; } if (slash && (ch == otty.sg_kill || ch == otty.sg_erase)) { ERASEONECHAR --sptr; } if (ch != '\\') slash = 0; *sptr++ = ch; if ((ch < ' ' && ch != '\n' && ch != ESC) || ch == RUBOUT) { ch += ch == RUBOUT ? -0100 : 0100; write (2, &CARAT, 1); promptlen++; } cbuf = ch; if (ch != '\n' && ch != ESC) { write (2, &cbuf, 1); promptlen++; } else break; } *--sptr = '\0'; if (!eraseln) promptlen = maxlen; if (sptr - buf >= nmax - 1) error ("Line too long");}expand (outbuf, inbuf)char *outbuf;char *inbuf;{ register char *instr; register char *outstr; register char ch; char temp[200]; int changed = 0; instr = inbuf; outstr = temp; while ((ch = *instr++) != '\0') switch (ch) { case '%': if (!no_intty) { strcpy (outstr, fnames[fnum]); outstr += strlen (fnames[fnum]); changed++; } else *outstr++ = ch; break; case '!': if (!shellp) error ("No previous command to substitute for"); strcpy (outstr, shell_line); outstr += strlen (shell_line); changed++; break; case '\\': if (*instr == '%' || *instr == '!') { *outstr++ = *instr++; break; } default: *outstr++ = ch; } *outstr++ = '\0'; strcpy (outbuf, temp); return (changed);}show (ch)register char ch;{ char cbuf; if ((ch < ' ' && ch != '\n' && ch != ESC) || ch == RUBOUT) { ch += ch == RUBOUT ? -0100 : 0100; write (2, &CARAT, 1); promptlen++; } cbuf = ch; write (2, &cbuf, 1); promptlen++;}error (mess)char *mess;{ if (clreol) cleareol (); else kill_line (); promptlen += strlen (mess); if (Senter && Sexit) { tputs (Senter, 1, putch); pr(mess); tputs (Sexit, 1, putch); } else pr (mess); fflush(stdout); errors++; longjmp (restore, 1);}set_tty (){ otty.sg_flags |= MBIT; otty.sg_flags &= ~ECHO; stty(fileno(stderr), &otty);}reset_tty (){ if (no_tty) return; if (pstate) { tputs(ULexit, 1, putch); fflush(stdout); pstate = 0; } otty.sg_flags |= ECHO; otty.sg_flags &= ~MBIT; stty(fileno(stderr), &savetty);}rdline (f)register FILE *f;{ register char c; register char *p; p = Line; while ((c = Getc (f)) != '\n' && c != EOF && p - Line < LINSIZ - 1) *p++ = c; if (c == '\n') Currline++; *p = '\0';}/* Come here when we get a suspend signal from the terminal */voidonsusp (){ /* ignore SIGTTOU so we don't get stopped if csh grabs the tty */ signal(SIGTTOU, SIG_IGN); reset_tty (); fflush (stdout); signal(SIGTTOU, SIG_DFL); /* Send the TSTP signal to suspend our process group */ signal(SIGTSTP, SIG_DFL); sigsetmask(0); kill (0, SIGTSTP); /* Pause for station break */ /* We're back */ signal (SIGTSTP, onsusp); set_tty (); if (inwait) longjmp (restore, 1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -