#define VI "vi" /* found on the user's path */
-#define Fopen(s,m) (ctl->Currline = 0, ctl->file_pos=0, fopen(s,m))
-#define Ftell(f) ctl->file_pos
-#define Fseek(f,off) (ctl->file_pos=off, fseek(f, off, 0))
-#define Getc(f) (++ctl->file_pos, getc(f))
-#define Ungetc(c,f) (--ctl->file_pos, ungetc(c,f))
-#define putcerr(c) fputc(c, stderr)
-#define putserr(s) fputs(s, stderr)
-#define putsout(s) fputs(s, stdout)
-
-#define stty(fd,argp) tcsetattr(fd,TCSANOW,argp)
-
#define BS "\b"
#define BSB "\b \b"
#define CARAT "^"
-
-#define ERASEONECOLUMN(x) \
- do { \
- if (x) \
- putserr(BSB); \
- else \
- putserr(BS); \
- } while(0)
+#define RINGBELL '\007'
#define TBUFSIZ 1024
#define LINSIZ 256 /* minimal Line buffer size */
}
}
+static void more_fseek(struct more_control *ctl, FILE *stream, long pos)
+{
+ ctl->file_pos = pos;
+ fseek(stream, pos, 0);
+}
+
+static int more_getc(struct more_control *ctl, FILE *stream)
+{
+ ctl->file_pos++;
+ return getc(stream);
+}
+
+static int more_ungetc(struct more_control *ctl, int c, FILE *stream)
+{
+ ctl->file_pos--;
+ return ungetc(c, stream);
+}
+
/* force clear to end of line */
static void cleareol(struct more_control *ctl)
{
printf(_("\n*** %s: directory ***\n\n"), fs);
return ((FILE *)NULL);
}
- if ((f = Fopen(fs, "r")) == NULL) {
+ ctl->Currline = 0;
+ ctl->file_pos = 0;
+ if ((f = fopen(fs, "r")) == NULL) {
fflush(stdout);
warn(_("cannot open %s"), fs);
return ((FILE *)NULL);
return ((FILE *)NULL);
}
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
- c = Getc(f);
+ c = more_getc(ctl, f);
*clearfirst = (c == '\f');
- Ungetc(c, f);
+ more_ungetc(ctl, c, f);
if ((ctl->file_size = stbuf.st_size) == 0)
ctl->file_size = LONG_MAX;
return (f);
size_t mbc_pos = 0; /* Position of the MBC. */
int use_mbc_buffer_flag = 0; /* If 1, mbc has data. */
int break_flag = 0; /* If 1, exit while(). */
- long file_pos_bak = Ftell(f);
+ long file_pos_bak = ctl->file_pos;
memset(&state, '\0', sizeof(mbstate_t));
#endif
p = ctl->Line;
column = 0;
- c = Getc(f);
+ c = more_getc(ctl, f);
if (colflg && c == '\n') {
ctl->Currline++;
- c = Getc(f);
+ c = more_getc(ctl, f);
}
while (p < &ctl->Line[ctl->LineLen - 1]) {
#ifdef HAVE_WIDECHAR
file_pos_bak++;
if (column >= ctl->Mcol) {
- Fseek(f, file_pos_bak);
+ more_fseek(ctl, f, file_pos_bak);
} else {
memmove(mbc, mbc + 1, --mbc_pos);
if (mbc_pos > 0) {
wc_width = wcwidth(wc);
if (column + wc_width > ctl->Mcol) {
- Fseek(f, file_pos_bak);
+ more_fseek(ctl, f, file_pos_bak);
break_flag = 1;
} else {
for (i = 0; p < &ctl->Line[ctl->LineLen - 1] &&
if (break_flag || column >= ctl->Mcol)
break;
- c = Getc(f);
+ c = more_getc(ctl, f);
continue;
}
#endif /* HAVE_WIDECHAR */
*p++ = c;
#if 0
if (c == '\033') { /* ESC */
- c = Getc(f);
+ c = more_getc(ctl, f);
while (c > ' ' && c < '0' && p < &Line[LineLen - 1]) {
*p++ = c;
- c = Getc(f);
+ c = more_getc(ctl, f);
}
if (c >= '0' && c < '\177' && p < &Line[LineLen - 1]) {
*p++ = c;
- c = Getc(f);
+ c = more_getc(ctl, f);
continue;
}
}
} else if (c == '\b' && column > 0) {
column--;
} else if (c == '\r') {
- int next = Getc(f);
+ int next = more_getc(ctl, f);
if (next == '\n') {
p--;
ctl->Currline++;
break;
}
- Ungetc(next, f);
+ more_ungetc(ctl, c, f);
column = 0;
} else if (c == '\f' && ctl->stop_opt) {
p[-1] = '^';
switch (mblength) {
case (size_t)-2:
p--;
- file_pos_bak = Ftell(f) - 1;
+ file_pos_bak = ctl->file_pos - 1;
state = state_bak;
use_mbc_buffer_flag = 1;
break;
* whole multibyte sequence */
break;
#endif
- c = Getc(f);
+ c = more_getc(ctl, f);
}
if (column >= ctl->Mcol && ctl->Mcol > 0) {
if (!ctl->Wrap) {
}
#endif
+static int wouldul(char *s, int n)
+{
+ if (n < 2)
+ return 0;
+ if ((s[0] == '_' && s[1] == '\b') || (s[1] == '\b' && s[2] == '_'))
+ return 1;
+ return 0;
+}
+
/* Print a buffer of n characters */
static void prbuf(struct more_control *ctl, register char *s, register int n)
{
register char c; /* next output character */
register int state; /* next output char's UL state */
-#define wouldul(s,n) ((n) >= 2 && (((s)[0] == '_' && (s)[1] == '\b') || ((s)[1] == '\b' && (s)[2] == '_')))
while (--n >= 0)
if (!ctl->ul_opt)
putchar(c);
#endif /* HAVE_WIDECHAR */
if (state && *ctl->chUL) {
- putsout(ctl->chBS);
+ fputs(ctl->chBS, stdout);
putstring(ctl->chUL);
}
ctl->pstate = state;
putchar('\r');
}
-#define ringbell() putcerr('\007')
-
static void prompt(struct more_control *ctl, char *filename)
{
if (ctl->clreol)
clreos(ctl);
fflush(stdout);
} else
- ringbell();
+ fputc(RINGBELL, stderr);
ctl->inwait++;
}
global_ctl->otty.c_lflag |= ICANON | ECHO;
global_ctl->otty.c_cc[VMIN] = global_ctl->savetty0.c_cc[VMIN];
global_ctl->otty.c_cc[VTIME] = global_ctl->savetty0.c_cc[VTIME];
- stty(fileno(stderr), &global_ctl->savetty0);
+ tcsetattr(STDERR_FILENO, TCSANOW, &global_ctl->savetty0);
}
/* Clean up terminal state and exit. Also come here if interrupt signal received */
kill_line(global_ctl);
fflush(stdout);
} else
- putcerr('\n');
+ fputc('\n', stderr);
free(global_ctl->previousre);
free(global_ctl->Line);
_exit(EXIT_SUCCESS);
if (ctl->clreol)
cleareol(ctl);
if (nskip > 0)
- putsout(_("...Skipping to file "));
+ fputs(_("...Skipping to file "), stdout);
else
- putsout(_("...Skipping back to file "));
+ fputs(_("...Skipping back to file "), stdout);
puts(ctl->fnames[ctl->fnum]);
if (ctl->clreol)
cleareol(ctl);
{
if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) {
c += (c == RUBOUT) ? -0100 : 0100;
- putserr(CARAT);
+ fputs(CARAT, stderr);
ctl->promptlen++;
}
- putcerr(c);
+ fputc(c, stderr);
ctl->promptlen++;
}
ctl->promptlen += strlen(mess);
if (ctl->Senter && ctl->Sexit) {
putp(ctl->Senter);
- putsout(mess);
+ fputs(mess, stdout);
putp(ctl->Sexit);
} else
- putsout(mess);
+ fputs(mess, stdout);
fflush(stdout);
ctl->errors++;
siglongjmp(ctl->restore, 1);
}
+static void erase_one_column(struct more_control *ctl)
+{
+ if (ctl->docrterase)
+ fputs(BSB, stderr);
+ else
+ fputs(BS, stderr);
+}
+
static void ttyin(struct more_control *ctl, char buf[], register int nmax, char pchar)
{
char *sp;
}
if (mblength == 1) {
- ERASEONECOLUMN(ctl->docrterase);
+ erase_one_column(ctl);
} else {
int wc_width;
wc_width = wcwidth(wc);
(wc_width <
1) ? 1 : wc_width;
while (wc_width--) {
- ERASEONECOLUMN(ctl->docrterase);
+ erase_one_column(ctl);
}
}
#endif /* HAVE_WIDECHAR */
{
--ctl->promptlen;
- ERASEONECOLUMN(ctl->docrterase);
+ erase_one_column(ctl);
--sp;
}
if ((*sp < ' ' && *sp != '\n') || *sp == RUBOUT) {
--ctl->promptlen;
- ERASEONECOLUMN(ctl->docrterase);
+ erase_one_column(ctl);
}
continue;
} else {
erasep(ctl, 1);
else if (ctl->docrtkill)
while (ctl->promptlen-- > 1)
- putserr(BSB);
+ fputs(BSB, stderr);
ctl->promptlen = 1;
}
sp = buf;
}
if (slash && ((cc_t) c == ctl->otty.c_cc[VKILL]
|| (cc_t) c == ctl->otty.c_cc[VERASE])) {
- ERASEONECOLUMN(ctl->docrterase);
+ erase_one_column(ctl);
--sp;
}
if (c != '\\')
*sp++ = c;
if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) {
c += (c == RUBOUT) ? -0100 : 0100;
- putserr(CARAT);
+ fputs(CARAT, stderr);
ctl->promptlen++;
}
if (c != '\n' && c != ESC) {
- putcerr(c);
+ fputc(c, stderr);
ctl->promptlen++;
} else
break;
ctl->otty.c_lflag &= ~(ICANON | ECHO);
ctl->otty.c_cc[VMIN] = 1; /* read at least 1 char */
ctl->otty.c_cc[VTIME] = 0; /* no timeout */
- stty(fileno(stderr), &ctl->otty);
+ tcsetattr(STDERR_FILENO, TCSANOW, &ctl->otty);
}
/* Come here if a quit signal is received */
execvp(cmd, args);
errsv = errno;
- putserr(_("exec failed\n"));
+ fputs(_("exec failed\n"), stderr);
exit(errsv == ENOENT ? EX_EXEC_ENOENT : EX_EXEC_FAILED);
}
if (id > 0) {
if (ctl->catch_susp)
signal(SIGTSTP, onsusp);
} else
- putserr(_("can't fork\n"));
+ fputs(_("can't fork\n"), stderr);
set_tty(ctl);
puts("------------------------");
prompt(ctl, filename);
fflush(stdout);
ctl->promptlen = 1;
if (ctl->lastp)
- putsout(ctl->shell_line);
+ fputs(ctl->shell_line, stdout);
else {
ttyin(ctl, cmdbuf, sizeof(cmdbuf) - 2, '!');
expanded = NULL;
free(expanded);
}
if (rc < 0) {
- putserr(_(" Overflow\n"));
+ fputs(_(" Overflow\n"), stderr);
prompt(ctl, filename);
return;
} else if (rc > 0) {
}
}
fflush(stdout);
- putcerr('\n');
+ fputc('\n', stderr);
ctl->promptlen = 0;
ctl->shellp = 1;
execute(ctl, filename, ctl->shell, ctl->shell, "-c", ctl->shell_line, 0);
return (0);
case 'p':
if (ctl->no_intty) {
- ringbell();
+ fputc(RINGBELL, stderr);
return (-1);
}
putchar('\r');
case 'Q':
end_it(0);
default:
- ringbell();
+ fputc(RINGBELL, stderr);
return (-1);
}
}
register int c;
while (n > 0) {
- while ((c = Getc(f)) != '\n')
+ while ((c = more_getc(ctl, f)) != '\n')
if (c == EOF)
return;
n--;
prepare_line_buffer(ctl);
p = ctl->Line;
- while ((c = Getc(f)) != '\n' && c != EOF
+ while ((c = more_getc(ctl, f)) != '\n' && c != EOF
&& (size_t)(p - ctl->Line) < ctl->LineLen - 1)
*p++ = c;
if (c == '\n')
* the file */
static void search(struct more_control *ctl, char buf[], FILE *file, register int n)
{
- long startline = Ftell(file);
+ long startline = ctl->file_pos;
register long line1 = startline;
register long line2 = startline;
register long line3;
while (!feof(file)) {
line3 = line2;
line2 = line1;
- line1 = Ftell(file);
+ line1 = ctl->file_pos;
rdline(ctl, file);
lncount++;
if (regexec(&re, ctl->Line, 0, NULL, 0) == 0) {
putchar('\n');
if (ctl->clreol)
cleareol(ctl);
- putsout(_("...skipping\n"));
+ fputs(_("...skipping\n"), stdout);
}
if (!ctl->no_intty) {
ctl->Currline -=
(lncount >= 3 ? 3 : lncount);
- Fseek(file, line3);
+ more_fseek(ctl, file, line3);
if (ctl->noscroll) {
if (ctl->clreol) {
home(ctl);
if (feof(file)) {
if (!ctl->no_intty) {
ctl->Currline = saveln;
- Fseek(file, startline);
+ more_fseek(ctl, file, startline);
} else {
- putsout(_("\nPattern not found\n"));
+ fputs(_("\nPattern not found\n"), stdout);
end_it(0);
}
free(ctl->previousre);
int done;
char comchar, cmdbuf[INIT_BUF];
-#define ret(val) retval=val;done++;break
-
done = 0;
if (!ctl->errors)
prompt(ctl, filename);
register int initline;
if (ctl->no_intty) {
- ringbell();
+ fputc(RINGBELL, stderr);
return (-1);
}
--initline;
if (initline < 0)
initline = 0;
- Fseek(f, 0L);
+ more_fseek(ctl, f, 0L);
ctl->Currline = 0; /* skiplns() will make Currline correct */
skiplns(ctl, initline, f);
if (!ctl->noscroll) {
- ret(ctl->dlines + 1);
+ retval = ctl->dlines + 1;
} else {
- ret(ctl->dlines);
+ retval = ctl->dlines;
}
+ done = 1;
+ break;
}
case ' ':
case 'z':
nlines = ctl->dlines;
else if (comchar == 'z')
ctl->dlines = nlines;
- ret(nlines);
+ retval = nlines;
+ done = 1;
+ break;
case 'd':
case ctrl('D'):
if (nlines != 0)
ctl->nscroll = nlines;
- ret(ctl->nscroll);
+ retval = ctl->nscroll;
+ done = 1;
+ break;
case 'q':
case 'Q':
end_it(0);
putchar('\n');
while (nlines > 0) {
- while ((c = Getc(f)) != '\n')
+ while ((c = more_getc(ctl, f)) != '\n')
if (c == EOF) {
retval = 0;
done++;
ctl->Currline++;
nlines--;
}
- ret(ctl->dlines);
+ retval = ctl->dlines;
+ done = 1;
+ break;
case '\n':
if (nlines != 0)
ctl->dlines = nlines;
else
nlines = 1;
- ret(nlines);
+ retval = nlines;
+ done = 1;
+ break;
case '\f':
if (!ctl->no_intty) {
doclear(ctl);
- Fseek(f, ctl->screen_start.chrctr);
+ more_fseek(ctl, f, ctl->screen_start.chrctr);
ctl->Currline = ctl->screen_start.line;
- ret(ctl->dlines);
+ retval = ctl->dlines;
+ done = 1;
+ break;
} else {
- ringbell();
+ fputc(RINGBELL, stderr);
break;
}
case '\'':
if (!ctl->no_intty) {
kill_line(ctl);
- putsout(_("\n***Back***\n\n"));
- Fseek(f, ctl->context.chrctr);
+ fputs(_("\n***Back***\n\n"), stdout);
+ more_fseek(ctl, f, ctl->context.chrctr);
ctl->Currline = ctl->context.line;
- ret(ctl->dlines);
+ retval = ctl->dlines;
+ done = 1;
+ break;
} else {
- ringbell();
+ fputc(RINGBELL, stderr);
break;
}
case '=':
ctl->promptlen = 1;
fflush(stdout);
if (ctl->lastp) {
- putcerr('\r');
+ fputc('\r', stderr);
search(ctl, ctl->previousre, f, nlines);
} else {
ttyin(ctl, cmdbuf, sizeof(cmdbuf) - 2, '/');
- putcerr('\r');
+ fputc('\r', stderr);
free(ctl->previousre);
ctl->previousre = xstrdup(cmdbuf);
search(ctl, cmdbuf, f, nlines);
}
- ret(ctl->dlines - 1);
+ retval = ctl->dlines - 1;
+ done = 1;
+ break;
case '!':
do_shell(ctl, filename);
break;
case 'h':
if (ctl->noscroll)
doclear(ctl);
- putsout(_("\n"
+ fputs(_("\n"
"Most commands optionally preceded by integer argument k. "
"Defaults in brackets.\n"
- "Star (*) indicates argument becomes new default.\n"));
+ "Star (*) indicates argument becomes new default.\n"), stdout);
puts("---------------------------------------"
"----------------------------------------");
- putsout(_
+ fputs(_
("<space> Display next k lines of text [current screen size]\n"
"z Display next k lines of text [current screen size]*\n"
"<return> Display next k lines of text [1]*\n"
":n Go to kth next file [1]\n"
":p Go to kth previous file [1]\n"
":f Display current file name and line number\n"
- ". Repeat previous command\n"));
+ ". Repeat previous command\n"), stdout);
puts("---------------------------------------"
"----------------------------------------");
prompt(ctl, filename);
("[Press 'h' for instructions.]"));
fflush(stdout);
} else
- ringbell();
+ fputc(RINGBELL, stderr);
break;
}
if (done)
ctl->pstate = 0;
}
fflush(stdout);
- if ((c = Getc(f)) == EOF) {
+ if ((c = more_getc(ctl, f)) == EOF) {
if (ctl->clreol)
clreos(ctl);
return;
if (ctl->Pause && ctl->clreol)
clreos(ctl);
- Ungetc(c, f);
+ more_ungetc(ctl, c, f);
sigsetjmp(ctl->restore, 1);
ctl->Pause = 0;
ctl->startup = 0;
doclear(ctl);
}
ctl->screen_start.line = ctl->Currline;
- ctl->screen_start.chrctr = Ftell(f);
+ ctl->screen_start.chrctr = ctl->file_pos;
}
}
signal(SIGTSTP, onsusp);
ctl.catch_susp++;
}
- stty(fileno(stderr), &ctl.otty);
+ tcsetattr(STDERR_FILENO, TCSANOW, &ctl.otty);
}
if (ctl.no_intty) {
if (ctl.no_tty)
erasep(&ctl, 0);
if (ctl.clreol)
cleareol(&ctl);
- putsout("::::::::::::::");
+ fputs("::::::::::::::", stdout);
if (ctl.promptlen > 14)
erasep(&ctl, 14);
putchar('\n');
puts(ctl.fnames[ctl.fnum]);
if (ctl.clreol)
cleareol(&ctl);
- puts("::::::::::::::");
+ fputs("::::::::::::::\n", stdout);
if (left > ctl.Lpp - 4)
left = ctl.Lpp - 4;
}