1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29
30#include <ctype.h>
31#include <limits.h>
32#include <locale.h>
33#include <nl_types.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include <unistd.h>
38#include <errno.h>
39
40#define	FF '\f'
41#define	NL '\n'
42#define	NUL '\0'
43
44static	void usage(void);
45static	void disp_file(FILE *f, char *filename);
46static	FILE *get_next_file(int, char *, char *[], int);
47static	void finish(int need_a_newline);
48
49int estatus = 0;	/* exit status */
50int i;			/* argv index */
51
52int
53main(int argc, char *argv[])
54{
55	int c;
56	int form_feeds		= 0;
57	int need_a_newline	= 0;
58	char *filename		= NULL;
59	FILE *f;
60
61	(void) setlocale(LC_ALL, "");
62#if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
63#define	TEXT_DOMAIN "SYS_TEST"  /* Use this only if it were not */
64#endif
65
66	(void) textdomain(TEXT_DOMAIN);
67
68	while ((c = getopt(argc, argv, "f")) != EOF) {
69		switch (c) {
70		case 'f':
71			form_feeds = 1;
72			break;
73
74		case '?':
75			usage();
76		}
77	}
78
79	i = optind;
80	if (argc <= i) {
81		filename = NULL;
82		f = stdin;
83	} else {
84		f = get_next_file(need_a_newline, filename, argv, argc);
85	}
86
87	need_a_newline = 0;
88	for (;;) {
89		/* interpret the first character in the line */
90
91		c = getc(f);
92		switch (c) {
93		case EOF:
94			disp_file(f, filename);
95
96			if (i >= argc)
97				finish(need_a_newline);
98
99			f = get_next_file(need_a_newline, filename, argv, argc);
100
101			if (need_a_newline) {
102				(void) putchar(NL);
103				need_a_newline = 0;
104			}
105
106			if (form_feeds)
107				(void) putchar(FF);
108
109			continue;
110
111		case NL:
112			if (need_a_newline)
113				(void) putchar(NL);
114			need_a_newline = 1;
115			continue;
116
117		case '+':
118			if (need_a_newline)
119				(void) putchar('\r');
120			break;
121
122		case '0':
123			if (need_a_newline)
124				(void) putchar(NL);
125			(void) putchar(NL);
126			break;
127
128		case '1':
129			if (need_a_newline)
130				(void) putchar(NL);
131			(void) putchar(FF);
132			break;
133
134		case ' ':
135		default:
136			if (need_a_newline)
137				(void) putchar(NL);
138			break;
139		}
140
141		need_a_newline = 0;
142
143		for (;;) {
144			c = getc(f);
145			if (c == NL) {
146				need_a_newline = 1;
147				break;
148			} else if (c == EOF) {
149				disp_file(f, filename);
150
151				if (i >= argc)
152					finish(need_a_newline);
153
154				f = get_next_file(need_a_newline, filename,
155				    argv, argc);
156
157				if (form_feeds) {
158					(void) putchar(NL);
159					(void) putchar(FF);
160					need_a_newline = 0;
161					break;
162				}
163			} else {
164				(void) putchar(c);
165			}
166		}
167	}
168	/* NOTREACHED */
169	return (0);
170}
171
172static void
173usage(void)
174{
175	(void) fprintf(stderr, gettext("usage: asa [-f] [-|file...]\n"));
176	exit(1);
177}
178
179
180static	void
181disp_file(FILE *f, char *filename)
182{
183
184	if (ferror(f)) {
185		int	serror = errno;
186		if (filename) {
187			(void) fprintf(stderr, gettext(
188			    "asa: read error on file %s\n"), filename);
189		} else {
190			(void) fprintf(stderr, gettext(
191			    "asa: read error on standard input\n"));
192		}
193		errno = serror;
194		perror("");
195		estatus = 1;
196	}
197
198	(void) fclose(f);
199
200}
201
202static	FILE *
203get_next_file(int need_a_newline, char *filename, char *argv[], int argc)
204{
205	FILE	*f;
206	if (strcmp(argv[i], "-") == 0) {
207		filename = NULL;
208		f = stdin;
209	} else {
210		/*
211		 * Process each file operand.  If unsuccessful, affect the
212		 * exit status and continue processing the next operand.
213		 */
214		filename = argv[i];
215		while ((f = fopen(filename, "r")) == NULL) {
216			int	serror = errno;
217			(void) fprintf(stderr,
218				gettext("asa: cannot open %s:"), filename);
219			errno = serror;
220			perror("");
221			estatus = 1;
222			if (++i < argc) {
223				if (strcmp(argv[i], "-") == 0) {
224					filename = NULL;
225					f = stdin;
226					break;
227				} else {
228					filename = argv[i];
229				}
230			} else {
231				finish(need_a_newline);
232			}
233		}
234	}
235	++i;
236	return (f);
237}
238
239static	void
240finish(int need_a_newline)
241{
242	if (need_a_newline)
243		(void) putchar(NL);
244	exit(estatus);
245}
246