summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-06-04 23:50:36 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-06-04 23:50:36 +0000
commit4abc28629403036905c54b7d3d7956da5a52bfa9 (patch)
tree7e96472fae8342ec2c5293b6a9ab3df368096abe
parent75bac4fc9e4edcfdfbc8c39c3ef9cc2986fc283f (diff)
Handle arbitrarily long lines and add a special case for \r\n pair;
just ignore the \r, otherwise we end up with a blank line. An \r in the middle of a line is left as-is.
-rw-r--r--distrib/special/more/more.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/distrib/special/more/more.c b/distrib/special/more/more.c
index de029193027..79420cc2f9e 100644
--- a/distrib/special/more/more.c
+++ b/distrib/special/more/more.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: more.c,v 1.22 2003/06/04 03:49:53 millert Exp $ */
+/* $OpenBSD: more.c,v 1.23 2003/06/04 23:50:35 millert Exp $ */
/*-
* Copyright (c) 1980 The Regents of the University of California.
@@ -39,7 +39,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)more.c 5.28 (Berkeley) 3/1/93";
#else
-static const char rcsid[] = "$OpenBSD: more.c,v 1.22 2003/06/04 03:49:53 millert Exp $";
+static const char rcsid[] = "$OpenBSD: more.c,v 1.23 2003/06/04 23:50:35 millert Exp $";
#endif
#endif /* not lint */
@@ -52,6 +52,12 @@ static const char rcsid[] = "$OpenBSD: more.c,v 1.22 2003/06/04 03:49:53 millert
* modified by John Foderaro, UCB to add -c and MORE environment variable
*/
+/*
+ * TODO (millert)
+ * o deal with large files (use off_t and ftello(), fseeko())
+ * o POSIX compliance
+ */
+
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/ioctl.h>
@@ -122,7 +128,8 @@ char **fnames; /* The list of file names */
int nfiles; /* Number of files left to process */
char *shell; /* The name of the shell to use */
int shellp; /* A previous shell command exists */
-char Line[LINSIZ]; /* Line buffer */
+char Lineb[LINSIZ]; /* Line buffer */
+char *Line = Lineb; /* Line pointer */
int Lpp = 24; /* lines per page */
char *Clear; /* clear screen */
char *eraseln; /* erase line */
@@ -140,6 +147,7 @@ int soglitch; /* terminal has standout mode glitch */
int ulglitch; /* terminal has underline mode glitch */
int pstate = 0; /* current UL state */
int altscr = 0; /* terminal supports an alternate screen */
+size_t linsize = LINSIZ;
volatile sig_atomic_t signo; /* signal received */
@@ -181,6 +189,7 @@ void set_tty(void);
void show(int);
void skipf(int);
void skiplns(int, FILE *);
+char *resize_line(char *);
FILE *checkf(char *, int *);
__dead void usage(void);
struct sigaction sa;
@@ -648,19 +657,24 @@ prompt(char *filename)
int
getline(FILE *f, int *length)
{
- int ch;
- char *p;
+ int ch, lastch;
+ char *p, *ep;
int column;
static int colflg;
p = Line;
+ ep = Line + linsize - 1;
column = 0;
ch = Getc(f);
if (colflg && ch == '\n') {
Currline++;
ch = Getc(f);
}
- while (p < &Line[LINSIZ - 1]) {
+ for (;;) {
+ if (p >= ep) {
+ p = resize_line(p);
+ ep = Line + linsize - 1;
+ }
if (ch == EOF) {
if (p > Line) {
*p = '\0';
@@ -682,7 +696,11 @@ getline(FILE *f, int *length)
tputs(eraseln, 1, putch);
promptlen = 0;
} else {
- for (--p; p < &Line[LINSIZ - 1];) {
+ for (--p;;) {
+ if (p >= ep) {
+ p = resize_line(p);
+ ep = Line + linsize - 1;
+ }
*p++ = ' ';
if ((++column & 7) == 0)
break;
@@ -694,8 +712,6 @@ getline(FILE *f, int *length)
column = 1 + (column | 7);
} else if (ch == '\b' && column > 0)
column--;
- else if (ch == '\r')
- column = 0;
else if (ch == '\f' && stop_opt) {
p[-1] = '^';
*p++ = 'L';
@@ -708,15 +724,27 @@ getline(FILE *f, int *length)
column++;
if (column >= Mcol && fold_opt)
break;
+ lastch = ch;
ch = Getc(f);
+ if (lastch == '\r') {
+ /*
+ * Reset column to 0 for carriage return unless
+ * immediately followed by a newline.
+ */
+ if (ch != '\n')
+ column = 0;
+ else
+ p--;
+ }
}
+ /* XXX - potential oflow */
if (column >= Mcol && Mcol > 0 && !Wrap)
*p++ = '\n';
colflg = (column == Mcol && fold_opt);
if (colflg && eatnl && Wrap)
*p++ = '\n'; /* simulate normal wrap */
*length = p - Line;
- *p = 0;
+ *p = '\0';
return (column);
}
@@ -1222,7 +1250,7 @@ search(char *buf, FILE *file, int n)
line3 = line2;
line2 = line1;
line1 = Ftell(file);
- rdline (file);
+ rdline(file);
lncount++;
if ((rv = regexec(&reg, Line, 0, NULL, 0)) == 0) {
if (--n == 0) {
@@ -1784,16 +1812,44 @@ void
rdline(FILE *f)
{
int ch;
- char *p;
+ char *p, *ep;
p = Line;
- while ((ch = Getc(f)) != '\n' && ch != EOF && p - Line < LINSIZ - 1)
+ ep = Line + linsize - 1;
+ while ((ch = Getc(f)) != '\n' && ch != EOF) {
+ if (p >= ep) {
+ p = resize_line(p);
+ ep = Line + linsize - 1;
+ }
*p++ = (char)ch;
+ }
if (ch == '\n')
Currline++;
*p = '\0';
}
+char *
+resize_line(char *pos)
+{
+ char *np;
+
+ linsize *= 2;
+ if (Line != Lineb)
+ np = realloc(Line, linsize);
+ else if ((np = malloc(linsize)) != NULL)
+ memcpy(np, Lineb, sizeof(Lineb));
+ if (np == NULL) {
+ kill_line();
+ fputs("out of memory!\n", stdout);
+ reset_tty();
+ exit(1);
+ }
+ pos = np + (pos - Line);
+ Line = np;
+
+ return (pos);
+}
+
/*
* Come here when we get a signal we can handle.
*/