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