diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-05-03 22:18:23 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-05-03 22:18:23 -0700 |
commit | 03e5e288e5e7bfbd8dc5d960856b82a6d123ca53 (patch) | |
tree | 10451f3bda818caae274611c03733c56da52fce4 | |
parent | e6beaea9003be2fabd5de898d30f5f7c876e2534 (diff) | |
download | pw-03e5e288e5e7bfbd8dc5d960856b82a6d123ca53.tar.gz pw-03e5e288e5e7bfbd8dc5d960856b82a6d123ca53.tar.bz2 pw-03e5e288e5e7bfbd8dc5d960856b82a6d123ca53.zip |
Impose limit on maximum line length, controlled by option.
-rw-r--r-- | pw.1 | 13 | ||||
-rw-r--r-- | pw.c | 30 |
2 files changed, 38 insertions, 5 deletions
@@ -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, @@ -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)) { |