2.9BSD/usr/src/ucb/vsh/show.c
#include "hd.h"
#include "strings.h"
#include "command.h"
#define SPAGELEN 12 /* Number of Lines per Page */
static char EONE [] = "+1"; /* Default editor parameter */
/* Global data about file being shown */
FILE *sstream; /* Stream being shown */
int cline; /* Current (next) line to be shown */
int tline; /* Top line of page */
char *sdesc [2] = {"Grep", "Make"};
showerror () {
return show (MAKEMODE);
}
showgrep () {
return show (GREPMODE);
}
show (p) int p; { /* Use parms GREPMODE or MAKEMODE */
FILE *showopen ();
int cmd, next, number, spaces;
int (*cproc)();
extern grep(), wmake(), showerror(), showgrep();
sstream = showopen ("r", p);
if (sstream == NULL) return NOREPLOT;
cline = 1;
next = REPLOT;
for (;;) {
if (next & REPLOT) {
sdisp (p);
number = spaces = 0;
}
if (number == 0) {
at (2301);
printf (" \r");
}
cmd = getch ();
next = REPLOT;
/* This accumulates a number */
if (NUMERIC (cmd) && spaces == 0) {
number = number * 10 + TONUM (cmd);
next = 0;
}
else if (cmd == '\b') {
if (spaces > 0) --spaces;
else number /= 10;
printf (" \b");
next = 0;
}
else if (cmd == ' ') {
if (number > 0) ++spaces;
next = 0;
}
/* These commands use number */
else if (cmd == LF || cmd == CR || cmd == 'e') {
putch (CR);
next = sedit (p, number);
number = spaces = 0;
}
else if (cmd == 'p') {
putch (CR);
seekline (number);
}
else {
number = spaces = 0; putch (CR);
cproc = cmdproc(cmd);
if (cproc == showerror || cproc == showgrep) {
next = cmd | REPLOT;
break;
}
else if (cmd == '?') {
next = help (SHOWHELP);
}
else if (cproc == grep) {
next = grep ();
if (next != FAILURE) break;
}
else if (cproc == wmake) {
next = wmake ();
if (next != FAILURE) break;
}
else if (cmd == 'q' || cmd == EOT) {
break;
}
else {
next = command (cmd, SHOWCMD);
}
if (next & ENTERDIR) break;
if (next & REPLOT) seekline (tline);
}
}
fclose (sstream);
return next | REPLOT;
}
/* Position show file at specified location */
seekline (line) int line; {
register ch;
cline = 1; rewind (sstream);
while (cline < line && (ch = getc (sstream)) != EOF)
if (ch == LF) cline++;
if (feof (sstream)) {
if (cline <= 2) {
rewind (sstream); cline = 1;
} else {
seekline (cline - 1);
}
}
}
sdisp (p) int p; { /* display sstream */
register ch; /* work char */
int eline; /* end line -- line to stop display */
short lflag; /* True if chars have printed on current line */
extern char wdname []; /* Name of working dir */
if (feof (sstream)) seekline (1);
tline = cline;
eline = cline + SPAGELEN;
clearmsg (-1); bufout (); tty_push (COOKEDMODE);
erase (); printf ("%s", wdname);
at (161); printf ("Showfile -- %s \n", sdesc [p]);
while (cline < eline) {
lflag = 0;
do {
ch = getc (sstream);
if (ch == EOF) ch = LF;
else if (!lflag) {
printf ("%4d ", cline);
lflag = 1;
}
putchar (ch);
} while (ch != LF);
cline++;
if (feof (sstream)) {
seekline (1); printf ("** End of File **\n");
break;
}
}
printf ("\nType the number of the line you wish to edit.\n");
printf ("Type ^D to Leave. Type ? for more options.");
at (2301); unbufout (); tty_pop ();
}
sedit (p, number) int p, number; {
char inbuf [STRMAX];
int oldline;
oldline = cline;
if (number == 0) return REPLOT;
seekline (number);
fgetline (sstream, inbuf);
if (p == GREPMODE && grepfmt (inbuf));
else if (p == MAKEMODE &&
(ccfmt (inbuf) || grepfmt (inbuf) || cmdfmt (inbuf)));
else {
putmsg ("Cannot find file name");
seekline (oldline);
return NOREPLOT;
}
seekline (number);
return REPLOT;
}
/* Extract file names and line numbers from various formats. */
ccfmt (inbuf) char inbuf [STRMAX]; { /* Error from C compiler */
char filebuf [STRMAX]; /* or lint */
char *enumber ();
register char *cpi, *cpo;
cpi = inbuf;
while (*cpi != '"') if (*cpi++ == 0) return 0;
cpi++; cpo = filebuf;
while (*cpi != '"') {
if (*cpi == 0) return 0;
*cpo++ = *cpi++;
}
*cpo = 0;
return nedit (filebuf, enumber (cpi));
}
grepfmt (inbuf) char inbuf [STRMAX]; { /* Line from grep */
char filebuf [STRMAX]; /* or C preprocessor */
char *enumber ();
register char *cpi, *cpo;
cpi = inbuf; cpo = filebuf;
while (*cpi != ':') {
if (*cpi == 0) return 0;
*cpo++ = *cpi++;
}
if (*cpi == 0) return 0;
*cpo = 0;
return nedit (filebuf, enumber (cpi));
}
cmdfmt (inbuf) char inbuf [STRMAX]; { /* Command line */
char filebuf [STRMAX];
register char *cpi, *cpo;
cpi = inbuf;
do {
while (!WHITESPACE (*cpi)) if (*cpi++ == 0) return 0;
while ( WHITESPACE (*cpi)) cpi++;
} while (*cpi == '-');
if (*cpi == 0) return 0;
cpo = filebuf;
while (!WHITESPACE (*cpi) && *cpi != 0) *cpo++ = *cpi++;
*cpo = 0;
return nedit (filebuf, EONE);
}
/* Extract number from line */
char *
enumber (cpi) register char *cpi; {
static char numbuf [8];
# define NUMBUFLIM (numbuf + sizeof numbuf)
register char *cpo;
cpo = numbuf; *cpo++ = '+';
while (!NUMERIC (*cpi)) if (*cpi++ == 0) return EONE;
while (NUMERIC (*cpi)) {
if (cpo >= NUMBUFLIM) return EONE;
*cpo++ = *cpi++;
}
*cpo = 0;
return numbuf;
}
nedit (file, number) char *file, *number; {
if (access (file, 4)) return FAILURE;
f_exec (EDITOR, EDITOR, number, file, 0);
return REPLOT;
}