xref: /freebsd/usr.bin/asa/asa.c (revision c2356a440db91c106867d45c94b3d6d7bc0e50f0)
1*c2356a44SDag-Erling Smørgrav /*	$NetBSD: asa.c,v 1.17 2016/09/05 00:40:28 sevan Exp $	*/
23990fae7STim J. Robbins 
31de7b4b8SPedro F. Giffuni /*-
41de7b4b8SPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
51de7b4b8SPedro F. Giffuni  *
63990fae7STim J. Robbins  * Copyright (c) 1993,94 Winning Strategies, Inc.
73990fae7STim J. Robbins  * All rights reserved.
83990fae7STim J. Robbins  *
93990fae7STim J. Robbins  * Redistribution and use in source and binary forms, with or without
103990fae7STim J. Robbins  * modification, are permitted provided that the following conditions
113990fae7STim J. Robbins  * are met:
123990fae7STim J. Robbins  * 1. Redistributions of source code must retain the above copyright
133990fae7STim J. Robbins  *    notice, this list of conditions and the following disclaimer.
143990fae7STim J. Robbins  * 2. Redistributions in binary form must reproduce the above copyright
153990fae7STim J. Robbins  *    notice, this list of conditions and the following disclaimer in the
163990fae7STim J. Robbins  *    documentation and/or other materials provided with the distribution.
173990fae7STim J. Robbins  * 3. All advertising materials mentioning features or use of this software
183990fae7STim J. Robbins  *    must display the following acknowledgement:
193990fae7STim J. Robbins  *      This product includes software developed by Winning Strategies, Inc.
203990fae7STim J. Robbins  * 4. The name of the author may not be used to endorse or promote products
213990fae7STim J. Robbins  *    derived from this software without specific prior written permission
223990fae7STim J. Robbins  *
233990fae7STim J. Robbins  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
243990fae7STim J. Robbins  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
253990fae7STim J. Robbins  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
263990fae7STim J. Robbins  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
273990fae7STim J. Robbins  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
283990fae7STim J. Robbins  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
293990fae7STim J. Robbins  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
303990fae7STim J. Robbins  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
313990fae7STim J. Robbins  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
323990fae7STim J. Robbins  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
333990fae7STim J. Robbins  */
343990fae7STim J. Robbins 
3581c126e7STim J. Robbins #include <err.h>
36*c2356a44SDag-Erling Smørgrav #include <stdbool.h>
373990fae7STim J. Robbins #include <stdio.h>
383990fae7STim J. Robbins #include <stdlib.h>
39f08f90e6SDag-Erling Smørgrav #include <string.h>
40a3778ff6STim J. Robbins #include <unistd.h>
413990fae7STim J. Robbins 
428a99cbd5STim J. Robbins static void asa(FILE *);
43498a0a9cSAlfonso Gregory static void usage(void) __dead2;
443990fae7STim J. Robbins 
453990fae7STim J. Robbins int
main(int argc,char * argv[])468a99cbd5STim J. Robbins main(int argc, char *argv[])
473990fae7STim J. Robbins {
483990fae7STim J. Robbins 	FILE *fp;
49*c2356a44SDag-Erling Smørgrav 	int ch, exval;
503990fae7STim J. Robbins 
5166562e1aSTim J. Robbins 	while ((ch = getopt(argc, argv, "")) != -1) {
5266562e1aSTim J. Robbins 		switch (ch) {
5366562e1aSTim J. Robbins 		default:
5466562e1aSTim J. Robbins 			usage();
5566562e1aSTim J. Robbins 		}
5666562e1aSTim J. Robbins 	}
5766562e1aSTim J. Robbins 	argc -= optind;
5866562e1aSTim J. Robbins 	argv += optind;
593990fae7STim J. Robbins 
6066562e1aSTim J. Robbins 	exval = 0;
61*c2356a44SDag-Erling Smørgrav 	if (*argv == NULL) {
62f08f90e6SDag-Erling Smørgrav 		asa(stdin);
63f08f90e6SDag-Erling Smørgrav 	} else {
64*c2356a44SDag-Erling Smørgrav 		do {
65*c2356a44SDag-Erling Smørgrav 			if (strcmp(*argv, "-") == 0) {
66*c2356a44SDag-Erling Smørgrav 				asa(stdin);
67*c2356a44SDag-Erling Smørgrav 			} else if ((fp = fopen(*argv, "r")) == NULL) {
68*c2356a44SDag-Erling Smørgrav 				warn("%s", *argv);
6966562e1aSTim J. Robbins 				exval = 1;
70*c2356a44SDag-Erling Smørgrav 			} else {
713990fae7STim J. Robbins 				asa(fp);
7266562e1aSTim J. Robbins 				fclose(fp);
7366562e1aSTim J. Robbins 			}
74*c2356a44SDag-Erling Smørgrav 		} while (*++argv != NULL);
75f08f90e6SDag-Erling Smørgrav 	}
763990fae7STim J. Robbins 
779e379f96SDag-Erling Smørgrav 	if (fflush(stdout) != 0)
789e379f96SDag-Erling Smørgrav 		err(1, "stdout");
799e379f96SDag-Erling Smørgrav 
8066562e1aSTim J. Robbins 	exit(exval);
8166562e1aSTim J. Robbins }
8266562e1aSTim J. Robbins 
8366562e1aSTim J. Robbins static void
usage(void)8466562e1aSTim J. Robbins usage(void)
8566562e1aSTim J. Robbins {
8666562e1aSTim J. Robbins 	fprintf(stderr, "usage: asa [file ...]\n");
8766562e1aSTim J. Robbins 	exit(1);
883990fae7STim J. Robbins }
893990fae7STim J. Robbins 
903990fae7STim J. Robbins static void
asa(FILE * f)918a99cbd5STim J. Robbins asa(FILE *f)
923990fae7STim J. Robbins {
9381c126e7STim J. Robbins 	char *buf;
94*c2356a44SDag-Erling Smørgrav 	size_t len;
95*c2356a44SDag-Erling Smørgrav 	bool eol = false;
963990fae7STim J. Robbins 
973990fae7STim J. Robbins 	while ((buf = fgetln(f, &len)) != NULL) {
98*c2356a44SDag-Erling Smørgrav 		/* in all cases but '+', terminate previous line, if any */
99*c2356a44SDag-Erling Smørgrav 		if (buf[0] != '+' && eol)
100*c2356a44SDag-Erling Smørgrav 			putchar('\n');
101*c2356a44SDag-Erling Smørgrav 		/* examine and translate the control character */
1023990fae7STim J. Robbins 		switch (buf[0]) {
1033990fae7STim J. Robbins 		default:
104*c2356a44SDag-Erling Smørgrav 			/*
105*c2356a44SDag-Erling Smørgrav 			 * “It is suggested that implementations treat
106*c2356a44SDag-Erling Smørgrav 			 * characters other than 0, 1, and '+' as <space>
107*c2356a44SDag-Erling Smørgrav 			 * in the absence of any compelling reason to do
108*c2356a44SDag-Erling Smørgrav 			 * otherwise” (POSIX.1-2017)
109*c2356a44SDag-Erling Smørgrav 			 */
1103990fae7STim J. Robbins 		case ' ':
111*c2356a44SDag-Erling Smørgrav 			/* nothing */
1123990fae7STim J. Robbins 			break;
1133990fae7STim J. Robbins 		case '0':
1143990fae7STim J. Robbins 			putchar('\n');
1153990fae7STim J. Robbins 			break;
1163990fae7STim J. Robbins 		case '1':
1173990fae7STim J. Robbins 			putchar('\f');
1183990fae7STim J. Robbins 			break;
1193990fae7STim J. Robbins 		case '+':
120*c2356a44SDag-Erling Smørgrav 			/*
121*c2356a44SDag-Erling Smørgrav 			 * “If the '+' is the first character in the
122*c2356a44SDag-Erling Smørgrav 			 * input, it shall be equivalent to <space>.”
123*c2356a44SDag-Erling Smørgrav 			 * (POSIX.1-2017)
124*c2356a44SDag-Erling Smørgrav 			 */
125*c2356a44SDag-Erling Smørgrav 			if (eol)
1263990fae7STim J. Robbins 				putchar('\r');
1273990fae7STim J. Robbins 			break;
1283990fae7STim J. Robbins 		}
129*c2356a44SDag-Erling Smørgrav 		/* trim newline if there is one */
130*c2356a44SDag-Erling Smørgrav 		if ((eol = (buf[len - 1] == '\n')))
131*c2356a44SDag-Erling Smørgrav 			--len;
132*c2356a44SDag-Erling Smørgrav 		/* print the rest of the input line */
13381c126e7STim J. Robbins 		if (len > 1 && buf[0] && buf[1])
134*c2356a44SDag-Erling Smørgrav 			fwrite(buf + 1, 1, len - 1, stdout);
1353990fae7STim J. Robbins 	}
136*c2356a44SDag-Erling Smørgrav 	/* terminate the last line, if any */
137*c2356a44SDag-Erling Smørgrav 	if (eol)
1383990fae7STim J. Robbins 		putchar('\n');
139*c2356a44SDag-Erling Smørgrav 	/* check for output errors */
1409e379f96SDag-Erling Smørgrav 	if (ferror(stdout) != 0)
1419e379f96SDag-Erling Smørgrav 		err(1, "stdout");
1423990fae7STim J. Robbins }
143