Home | History | Annotate | Download | only in asa
      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 
     44 static	void usage(void);
     45 static	void disp_file(FILE *f, char *filename);
     46 static	FILE *get_next_file(int, char *, char *[], int);
     47 static	void finish(int need_a_newline);
     48 
     49 int estatus = 0;	/* exit status */
     50 int i;			/* argv index */
     51 
     52 int
     53 main(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 
    172 static void
    173 usage(void)
    174 {
    175 	(void) fprintf(stderr, gettext("usage: asa [-f] [-|file...]\n"));
    176 	exit(1);
    177 }
    178 
    179 
    180 static	void
    181 disp_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 
    202 static	FILE *
    203 get_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 
    239 static	void
    240 finish(int need_a_newline)
    241 {
    242 	if (need_a_newline)
    243 		(void) putchar(NL);
    244 	exit(estatus);
    245 }
    246