From 5b0de797fd0249067fe06bf193cc22de50b4b47a Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Wed, 13 Dec 2017 19:40:42 +0100 Subject: initial import of rnl --- rnl.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 rnl.c (limited to 'rnl.c') diff --git a/rnl.c b/rnl.c new file mode 100644 index 0000000..b1bac2a --- /dev/null +++ b/rnl.c @@ -0,0 +1,113 @@ +/* rnl - remove final newlines */ + +#include +#include + +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int c; + int i, n = 0; + int mode = -1; + char nl = '\n'; + + while ((c = getopt(argc, argv, "01sz")) != -1) + switch (c) { + case '0': mode = 0; break; + case '1': mode = 1; break; + case 's': mode = -1; break; + case 'z': nl = '\0'; break; + default: + fprintf(stderr, +"Usage: %s [-01sz] < INPUT writes to stdout\n" +" %s [-01sz] INPUT... modifies in-place!\n" +" -0 strip all newlines at end\n" +" -1 strip one newline at end\n" +" -s default: strip all but one newline at end\n" +" -z strip NUL bytes instead of newlines\n", + argv[0], argv[0]); + exit(1); + } + + if (optind == argc) { + /* pipe mode stdin -> stdout */ + + while ((c = getchar()) != EOF) { + if (c == nl) { + n++; + continue; + } + for (i = 0; i < n; i++) + putchar(nl); + n = 0; + putchar(c); + } + if (mode == 1) + for (i = 0; i < n - 1; i++) + putchar(nl); + else if (mode == -1 && n > 0) + putchar(nl); + /* else (mode == 0) ; do nothing */ + + return 0; + } + + /* in-place mode */ + for (i = optind; i < argc; i++) { + int fd = open(argv[i], O_RDWR); + if (fd < 0) + perror("rnl: open"); + + off_t pos = lseek(fd, 0, SEEK_END); + + if (mode == 1) { + if (pos > 0) { + char buf; + if (pread(fd, &buf, 1, pos - 1) != 1) + perror("rnl: pread"); + if (buf == nl) + if (ftruncate(fd, pos - 1) < 0) + perror("rnl: ftruncate"); + + } + } else { + char buf[1024]; + off_t n = 0; + + off_t endpos = pos; + ssize_t rd; + do { + off_t l = sizeof buf; + if (pos > l) + pos -= l; + else { + l = pos; + pos = 0; + } + rd = pread(fd, buf, l, pos); + while (rd > 0 && buf[--rd] == nl) + n++; + } while (rd == 0 && n > 0 && pos > 0); + + if (rd < 0) + perror("rnl: pread"); + + if (mode == -1 && n > 0) + n--; + + if (n > 0) + if (ftruncate(fd, endpos - n) < 0) + perror("rnl: ftruncate"); + } + + close(fd); + } + + return 0; +} -- cgit 1.4.1