master xplshn/aruu / cmd / pseudo / rev.c
 1/* See LICENSE file for copyright and license details. */
 2
 3
 4#include <stdio.h>
 5#include <string.h>
 6#include <unistd.h>
 7
 8#include "text.h"
 9#include "util.h"
10
11static void
12usage(void)
13{
14	eprintf("usage: %s [file ...]\n", argv0);
15}
16
17static void
18rev(FILE *fp)
19{
20	static char *line = NULL;
21	static size_t size = 0;
22	size_t i;
23	ssize_t n;
24	int lf;
25
26	while ((n = getline(&line, &size, fp)) > 0) {
27		lf = n && line[n - 1] == '\n';
28		i = n -= lf;
29		for (n = 0; i--;) {
30			if (UTF8_POINT(line[i])) {
31				n++;
32			} else {
33				fwrite(line + i, 1, n + 1, stdout);
34				n = 0;
35			}
36		}
37		if (n)
38			fwrite(line, 1, n, stdout);
39		if (lf)
40			fputc('\n', stdout);
41	}
42}
43
44// ?man rev: reverse lines
45// ?man arguments: file ...
46// ?man reverse the order of characters in each line of input
47int
48main(int argc, char *argv[])
49{
50	FILE *fp;
51	int ret = 0;
52
53	ARGBEGIN {
54	default:
55		usage();
56	} ARGEND
57
58	if (!argc) {
59		rev(stdin);
60	} else {
61		for (; *argv; argc--, argv++) {
62			if (!strcmp(*argv, "-")) {
63				*argv = "<stdin>";
64				fp = stdin;
65			} else if (!(fp = fopen(*argv, "r"))) {
66				weprintf("fopen %s:", *argv);
67				ret = 1;
68				continue;
69			}
70			rev(fp);
71			if (fp != stdin && fshut(fp, *argv))
72				ret = 1;
73		}
74	}
75
76	ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
77
78	return ret;
79}