dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / expand / expand.c
blob49f3e082550dd595613fcabfaeca5ac224b9adf9
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
40 #pragma ident "%Z%%M% %I% %E% SMI"
42 #include <stdio.h>
43 #include <libintl.h>
44 #include <locale.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <ctype.h>
48 #include <limits.h>
49 #include <wchar.h>
52 * expand - expand tabs to equivalent spaces
54 static int nstops = 0;
55 static int tabstops[100];
56 static int isClocale;
58 static void getstops(const char *);
59 static void usage(void);
61 int
62 main(argc, argv)
63 int argc;
64 char *argv[];
66 static char ibuf[BUFSIZ];
67 register int c, column;
68 register int n;
69 register int i, j;
70 char *locale;
71 int flag, tflag = 0;
72 int len;
73 int p_col;
74 wchar_t wc;
75 char *p1, *p2;
77 (void) setlocale(LC_ALL, "");
78 locale = setlocale(LC_CTYPE, NULL);
79 isClocale = (strcmp(locale, "C") == 0);
80 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
81 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
82 #endif
83 (void) textdomain(TEXT_DOMAIN);
86 * First, look for and extract any "-<number>" args then pass
87 * them to getstops().
89 for (i = 1; i < argc; i++) {
90 if (strcmp(argv[i], "--") == 0)
91 break;
93 if (*argv[i] != '-')
94 continue;
95 if (!isdigit(*(argv[i]+1)))
96 continue;
98 getstops(argv[i]+1);
99 tflag++;
101 /* Pull this arg from list */
102 for (j = i; j < (argc-1); j++)
103 argv[j] = argv[j+1];
104 argc--;
107 while ((flag = getopt(argc, argv, "t:")) != EOF) {
108 switch (flag) {
109 case 't':
110 if (tflag)
111 usage();
113 getstops(optarg);
114 break;
116 default:
117 usage();
118 break;
122 argc -= optind;
123 argv = &argv[optind];
125 do {
126 if (argc > 0) {
127 if (freopen(argv[0], "r", stdin) == NULL) {
128 perror(argv[0]);
129 exit(1);
130 /* NOTREACHED */
132 argc--;
133 argv++;
136 column = 0;
137 p1 = p2 = ibuf;
138 for (;;) {
139 if (p1 >= p2) {
140 p1 = ibuf;
141 if ((len = fread(p1, 1, BUFSIZ, stdin)) <= 0)
142 break;
143 p2 = p1 + len;
146 c = *p1++;
147 switch (c) {
148 case '\t':
149 if (nstops == 0) {
150 do {
151 (void) putchar(' ');
152 column++;
153 } while (column & 07);
154 continue;
156 if (nstops == 1) {
157 do {
158 (void) putchar(' ');
159 column++;
160 } while (
161 ((column - 1) % tabstops[0]) !=
162 (tabstops[0] - 1));
163 continue;
165 for (n = 0; n < nstops; n++)
166 if (tabstops[n] > column)
167 break;
168 if (n == nstops) {
169 (void) putchar(' ');
170 column++;
171 continue;
173 while (column < tabstops[n]) {
174 (void) putchar(' ');
175 column++;
177 continue;
179 case '\b':
180 if (column)
181 column--;
182 (void) putchar('\b');
183 continue;
185 default:
186 if (isClocale) {
187 (void) putchar(c);
188 column++;
189 continue;
192 if (isascii(c)) {
193 (void) putchar(c);
194 column++;
195 continue;
198 p1--;
199 if ((len = (p2 - p1)) <
200 (unsigned int)MB_CUR_MAX) {
201 for (n = 0; n < len; n++)
202 ibuf[n] = *p1++;
203 p1 = ibuf;
204 p2 = p1 + n;
205 if ((len = fread(p2, 1, BUFSIZ - n,
206 stdin)) > 0)
207 p2 += len;
209 if ((len = (p2 - p1)) >
210 (unsigned int)MB_CUR_MAX)
211 len = (unsigned int)MB_CUR_MAX;
213 if ((len = mbtowc(&wc, p1, len)) <= 0) {
214 (void) putchar(c);
215 column++;
216 p1++;
217 continue;
220 if ((p_col = wcwidth(wc)) < 0)
221 p_col = len;
222 p1 += len;
223 (void) putwchar(wc);
224 column += p_col;
225 continue;
227 case '\n':
228 (void) putchar(c);
229 column = 0;
230 continue;
233 } while (argc > 0);
235 return (0);
236 /* NOTREACHED */
239 static void
240 getstops(const char *cp)
242 register int i;
244 for (;;) {
245 i = 0;
246 while (*cp >= '0' && *cp <= '9')
247 i = i * 10 + *cp++ - '0';
249 if (i <= 0 || i > INT_MAX) {
250 (void) fprintf(stderr, gettext(
251 "expand: invalid tablist\n"));
252 usage();
255 if (nstops > 0 && i <= tabstops[nstops-1]) {
256 (void) fprintf(stderr, gettext(
257 "expand: tablist must be increasing\n"));
258 usage();
261 tabstops[nstops++] = i;
262 if (*cp == 0)
263 break;
265 if (*cp != ',' && *cp != ' ') {
266 (void) fprintf(stderr, gettext(
267 "expand: invalid tablist\n"));
268 usage();
270 cp++;
274 static void
275 usage(void)
277 (void) fprintf(stderr, gettext(
278 "usage: expand [-t tablist] [file ...]\n"
279 " expand [-tabstop] [-tab1,tab2,...,tabn] [file ...]\n"));
280 exit(2);
281 /* NOTREACHED */