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