xref: /openbsd-src/usr.bin/rev/rev.c (revision ae3cb403620ab940fbaabb3055fac045a63d56b7)
1 /*	$OpenBSD: rev.c,v 1.13 2016/04/10 17:06:52 martijn Exp $	*/
2 /*	$NetBSD: rev.c,v 1.5 1995/09/28 08:49:40 tls Exp $	*/
3 
4 /*-
5  * Copyright (c) 1987, 1992, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include <sys/types.h>
34 
35 #include <err.h>
36 #include <errno.h>
37 #include <locale.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 
43 int isu8cont(unsigned char);
44 void usage(void);
45 
46 int
47 main(int argc, char *argv[])
48 {
49 	char *filename, *p = NULL, *t, *u;
50 	FILE *fp;
51 	ssize_t len;
52 	size_t ps = 0;
53 	int ch, rval;
54 
55 	setlocale(LC_CTYPE, "");
56 
57 	if (pledge("stdio rpath", NULL) == -1)
58 		err(1, "pledge");
59 
60 	while ((ch = getopt(argc, argv, "")) != -1)
61 		switch(ch) {
62 		default:
63 			usage();
64 		}
65 
66 	argc -= optind;
67 	argv += optind;
68 
69 	fp = stdin;
70 	filename = "stdin";
71 	rval = 0;
72 	do {
73 		if (*argv) {
74 			if ((fp = fopen(*argv, "r")) == NULL) {
75 				warn("%s", *argv);
76 				rval = 1;
77 				++argv;
78 				continue;
79 			}
80 			filename = *argv++;
81 		}
82 		while ((len = getline(&p, &ps, fp)) != -1) {
83 			if (p[len - 1] == '\n')
84 				--len;
85 			for (t = p + len - 1; t >= p; --t) {
86 				if (isu8cont(*t))
87 					continue;
88 				u = t;
89 				do {
90 					putchar(*u);
91 				} while (isu8cont(*(++u)));
92 			}
93 			putchar('\n');
94 		}
95 		if (ferror(fp)) {
96 			warn("%s", filename);
97 			rval = 1;
98 		}
99 		(void)fclose(fp);
100 	} while(*argv);
101 	return rval;
102 }
103 
104 int
105 isu8cont(unsigned char c)
106 {
107 	return MB_CUR_MAX > 1 && (c & (0x80 | 0x40)) == 0x80;
108 }
109 
110 void
111 usage(void)
112 {
113 	extern char *__progname;
114 
115 	(void)fprintf(stderr, "usage: %s [file ...]\n", __progname);
116 	exit(1);
117 }
118