tac.c a program to print lines in reverse order in linear time
trb at masscomp.UUCP
trb at masscomp.UUCP
Sat Sep 22 02:12:26 AEST 1984
This program was first posted to net.sources in Oct 1982. What comes
around goes around, I always say, so here it is, tac.c.
Tac does not read stdin. Why? Think about it.
I think research!rob modified this to do squashing of multiple blank
lines and printing of control characters as ^X, but he wouldn't let me
give it out.
Andy Tannenbaum Masscomp Inc Westford MA (617) 692-6200 x274
<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
# include <stdio.h>
# include <sys/types.h>
# include <sys/stat.h>
/* tac.c (backwards cat) */
main(argc, argv)
int argc;
char **argv;
{
register char *p, *q;
register int i;
struct stat st;
off_t off, lseek();
char buffer[ 1 + BUFSIZ + BUFSIZ + 1 ];
char *buf;
char *readerr = "Read error at offset %lu of %s\n";
int fd, any;
void output(), utcopyn();
if (argc < 2) {
(void) fprintf(stderr, "Usage: tac file ...\n");
exit(1);
}
buf = buffer;
*buf++ = '\n';
any = 0;
while (--argc) {
if (stat(p = *++argv, &st) == -1) {
(void) fprintf(stderr , "Bad status for %s\n", p);
any++;
continue;
}
if ((off = st.st_size) == 0) continue;
if ((fd = open(p, 0)) == -1) {
(void) fprintf(stderr, "Can't open %s\n", p);
any++;
continue;
}
if ((i = off % BUFSIZ ) == 0) i = BUFSIZ;
off -= i;
(void) lseek(fd, off, 0);
if (read(fd, buf, i) != i) {
(void) fprintf(stderr, readerr, off, p);
(void) close(fd);
any++;
continue;
}
p = q = buf + i;
if (*--p == '\n') q = p;
for (;;) {
while (*--p != '\n');
if (p < buf) {
if (off == 0) {
output(p, q);
(void) close(fd);
break;
}
(void) lseek(fd, off -= BUFSIZ, 0);
if ((i = q - buf) > BUFSIZ) {
(void) fprintf(stderr, "Line too long\n");
any++;
i = BUFSIZ;
}
utcopyn(p = buf + BUFSIZ, buf, i);
q = p + i;
if (read(fd, buf, BUFSIZ) != BUFSIZ) {
(void) fprintf(stderr, readerr, off, *argv);
any++;
(void) close(fd);
break;
}
continue;
}
output(p, q);
q = p;
}
}
exit(any);
}
static void
output(p, q)
register char *p,*q;
{
register FILE *iop;
for (iop = stdout, p++; p < q; (void) putc(*p++, iop));
(void) putc('\n', iop);
}
static void
utcopyn(tp, fp, n)
register char *tp, *fp;
register int n;
{
while (--n >= 0) *tp++ = *fp++;
return;
}
/* end of tac.c */
More information about the Comp.sources.unix
mailing list