[hackers] [sbase] tail: Process bytes with -c option, and add -m option for runes || Michael Forney
commit ea8622a4ce21e414050e116542cb76581d40d27a
Author: Michael Forney <mforney_AT_mforney.org>
AuthorDate: Mon Jul 3 14:58:52 2017 -0700
Commit: Anselm R Garbe <garbeam_AT_gmail.com>
CommitDate: Fri Jul 14 07:50:54 2017 +0200
tail: Process bytes with -c option, and add -m option for runes
POSIX says that -c specifies a number of bytes, not characters. This
flag is commonly used by scripts that operate on binary files to things
like extract a header. Treating the offsets as character offsets will
break things in mysterious ways.
Instead, add a -m option (chosen to match `wc -m`, which also operates
on characters) to handle character offsets.
diff --git a/tail.1 b/tail.1
index 433404d..281560d 100644
--- a/tail.1
+++ b/tail.1
_AT_@ -7,7 +7,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl f
-.Op Fl c Ar num | Fl n Ar num | Fl Ns Ar num
+.Op Fl c Ar num | Fl m Ar num | Fl n Ar num | Fl Ns Ar num
.Op Ar file ...
.Sh DESCRIPTION
.Nm
_AT_@ -20,10 +20,10 @@ is given,
reads from stdin.
.Sh OPTIONS
.Bl -tag -width Ds
-.It Fl c Ar num | Fl n Ar num | Fl Ns Ar num
+.It Fl c Ar num | Fl m Ar num | Fl n Ar num | Fl Ns Ar num
Display final
.Ar num
-characters | lines |
+bytes | characters | lines |
lines. If
.Ar num
begins with '+'
diff --git a/tail.c b/tail.c
index ce65a01..ce3be9d 100644
--- a/tail.c
+++ b/tail.c
_AT_@ -26,12 +26,23 @@ dropinit(int fd, const char *fname, size_t count)
goto copy;
count--; /* numbering starts at 1 */
while (count && (n = read(fd, buf, sizeof(buf))) > 0) {
- if (mode == 'n') {
+ switch (mode) {
+ case 'n': /* lines */
for (p = buf; count && n > 0; p++, n--) {
if (*p == '\n')
count--;
}
- } else {
+ break;
+ case 'c': /* bytes */
+ if (count > n) {
+ count -= n;
+ } else {
+ p = buf + count;
+ n -= count;
+ count = 0;
+ }
+ break;
+ case 'm': /* runes */
for (p = buf; count && n > 0; p += nr, n -= nr, count--) {
nr = charntorune(&r, p, n);
if (!nr) {
_AT_@ -42,6 +53,7 @@ dropinit(int fd, const char *fname, size_t count)
break;
}
}
+ break;
}
}
if (count) {
_AT_@ -90,7 +102,8 @@ taketail(int fd, const char *fname, size_t count)
if (n == 0)
break;
len += n;
- if (mode == 'n') {
+ switch (mode) {
+ case 'n': /* lines */
/* ignore the last character; if it is a newline, it
* ends the last line */
for (p = buf + len - 2, left = count; p >= buf; p--) {
_AT_@ -102,7 +115,11 @@ taketail(int fd, const char *fname, size_t count)
break;
}
}
- } else {
+ break;
+ case 'c': /* bytes */
+ p = count < len ? buf + len - count : buf;
+ break;
+ case 'm': /* runes */
for (p = buf + len - 1, left = count; p >= buf; p--) {
/* skip utf-8 continuation bytes */
if ((*p & 0xc0) == 0x80)
_AT_@ -111,6 +128,7 @@ taketail(int fd, const char *fname, size_t count)
if (!left)
break;
}
+ break;
}
if (p > buf) {
len -= p - buf;
_AT_@ -125,7 +143,7 @@ taketail(int fd, const char *fname, size_t count)
static void
usage(void)
{
- eprintf("usage: %s [-f] [-c num | -n num | -num] [file ...]\n", argv0);
+ eprintf("usage: %s [-f] [-c num | -m num | -n num | -num] [file ...]\n", argv0);
}
int
_AT_@ -143,6 +161,7 @@ main(int argc, char *argv[])
fflag = 1;
break;
case 'c':
+ case 'm':
case 'n':
mode = ARGC();
numstr = EARGF(usage());
Received on Fri Jul 14 2017 - 07:51:01 CEST
This archive was generated by hypermail 2.3.0
: Fri Jul 14 2017 - 08:01:29 CEST