aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pw.113
-rw-r--r--pw.c30
2 files changed, 38 insertions, 5 deletions
diff --git a/pw.1 b/pw.1
index 5a580db..a333a9f 100644
--- a/pw.1
+++ b/pw.1
@@ -564,6 +564,19 @@ to the specified decimal integer value. The default value is 15.
This value must be positive, and is clipped to the number of display lines
available in the terminal, less one.
+.IP "\fB-m\fP \fIinteger\fP"
+Set the maximum line length to
+.IR integer .
+The default value is 4095. Values smaller than 72 are adjusted to 72.
+The length is measured in display characters, not original characters.
+A control character like
+.B ^C
+counts as two characters. The behavior of
+.I pw
+is that when it is collecting a line, and the line has reached the maximum
+length, it keeps reading characters from the standard input, but discards
+them, while remaining responsive to TTY input.
+
.IP \fB-d\fP
Disable auto-quit: when no more input is available, instead of updating
the display one last time and terminating,
diff --git a/pw.c b/pw.c
index 6538cbd..f25a414 100644
--- a/pw.c
+++ b/pw.c
@@ -28,6 +28,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
@@ -51,6 +52,7 @@
#define DEL 127
#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
#ifdef __GNUC__
#define printf_attr(fmtpos, vargpos) __attribute__ ((format (printf, \
@@ -151,8 +153,11 @@ static void dsdrop(char *str)
static size_t dslen(const char *str)
{
- const dstr *ds = dstr_of(str);
- return ds->len;
+ if (str) {
+ const dstr *ds = dstr_of(str);
+ return ds->len;
+ }
+ return 0;
}
static char *dsgrow(char *str, size_t len)
@@ -691,6 +696,7 @@ int main(int argc, char **argv)
unsigned stat = 0;
FILE *tty = fopen("/dev/tty", "r+");
int maxlines = 15, nlines = 0, maxed = 0;
+ size_t maxlen = 2047;
int opt;
int ifd = fileno(stdin);
int ttyfd = tty ? fileno(tty) : -1;
@@ -728,7 +734,7 @@ int main(int argc, char **argv)
}
}
- while ((opt = getopt(argc, argv, "n:i:l:dEBg:q:")) != -1) {
+ while ((opt = getopt(argc, argv, "n:i:l:dEBg:q:m:")) != -1) {
switch (opt) {
case 'n':
{
@@ -802,6 +808,20 @@ int main(int argc, char **argv)
stat |= stat_grep;
}
break;
+ case 'm':
+ {
+ char *err;
+ int val = getzp(optarg, &err);
+ if (val < 0) {
+ error("-%c option: bad value %s: %s\n", opt, optarg, err);
+ return EXIT_FAILURE;
+ }
+
+ if ((int) (size_t) val != val)
+ val = -1;
+ maxlen = max(72, val);
+ }
+ break;
default:
usage();
}
@@ -865,7 +885,7 @@ int main(int argc, char **argv)
if ((stat & stat_eof) == 0) {
int ch;
- while ((ch = getc(stdin)) != EOF && ch != '\n')
+ while ((ch = getc(stdin)) != EOF && ch != '\n' && dslen(line) < maxlen)
line = addchesc(line, ch);
if (ch == EOF) {
if (feof(stdin) || (errno != EAGAIN && errno != EWOULDBLOCK)) {
@@ -882,7 +902,7 @@ int main(int argc, char **argv)
drawstatus(hist, columns, stat, curcmd);
}
clearerr(stdin);
- } else {
+ } else if (ch == '\n') {
nfds = 1;
line = addch(line, 0);
if ((stat & stat_grep)) {