/* $NetBSD: asa.c,v 1.17 2016/09/05 00:40:28 sevan Exp $ */12/*-3* SPDX-License-Identifier: BSD-4-Clause4*5* Copyright (c) 1993,94 Winning Strategies, Inc.6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13* 2. Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in the15* documentation and/or other materials provided with the distribution.16* 3. All advertising materials mentioning features or use of this software17* must display the following acknowledgement:18* This product includes software developed by Winning Strategies, Inc.19* 4. The name of the author may not be used to endorse or promote products20* derived from this software without specific prior written permission21*22* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR23* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES24* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.25* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,26* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT27* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,28* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY29* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT30* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF31* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.32*/3334#include <err.h>35#include <stdbool.h>36#include <stdio.h>37#include <stdlib.h>38#include <string.h>39#include <unistd.h>4041static void asa(FILE *);42static void usage(void) __dead2;4344int45main(int argc, char *argv[])46{47FILE *fp;48int ch, exval;4950while ((ch = getopt(argc, argv, "")) != -1) {51switch (ch) {52default:53usage();54}55}56argc -= optind;57argv += optind;5859exval = 0;60if (*argv == NULL) {61asa(stdin);62} else {63do {64if (strcmp(*argv, "-") == 0) {65asa(stdin);66} else if ((fp = fopen(*argv, "r")) == NULL) {67warn("%s", *argv);68exval = 1;69} else {70asa(fp);71fclose(fp);72}73} while (*++argv != NULL);74}7576if (fflush(stdout) != 0)77err(1, "stdout");7879exit(exval);80}8182static void83usage(void)84{85fprintf(stderr, "usage: asa [file ...]\n");86exit(1);87}8889static void90asa(FILE *f)91{92char *buf;93size_t len;94bool eol = false;9596while ((buf = fgetln(f, &len)) != NULL) {97/* in all cases but '+', terminate previous line, if any */98if (buf[0] != '+' && eol)99putchar('\n');100/* examine and translate the control character */101switch (buf[0]) {102default:103/*104* “It is suggested that implementations treat105* characters other than 0, 1, and '+' as <space>106* in the absence of any compelling reason to do107* otherwise” (POSIX.1-2017)108*/109case ' ':110/* nothing */111break;112case '0':113putchar('\n');114break;115case '1':116putchar('\f');117break;118case '+':119/*120* “If the '+' is the first character in the121* input, it shall be equivalent to <space>.”122* (POSIX.1-2017)123*/124if (eol)125putchar('\r');126break;127}128/* trim newline if there is one */129if ((eol = (buf[len - 1] == '\n')))130--len;131/* print the rest of the input line */132if (len > 1 && buf[0] && buf[1])133fwrite(buf + 1, 1, len - 1, stdout);134}135/* terminate the last line, if any */136if (eol)137putchar('\n');138/* check for output errors */139if (ferror(stdout) != 0)140err(1, "stdout");141}142143144