tmpfs - Fix mount_tmpfs -C
[dragonfly.git] / usr.bin / expand / expand.c
blobc62ec85705fccf6ea9db5b531bd6a510cc0625d4
1 /*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * @(#) Copyright (c) 1980, 1993 The Regents of the University of California. All rights reserved.
30 * @(#)expand.c 8.1 (Berkeley) 6/9/93
31 * $FreeBSD: head/usr.bin/expand/expand.c 227238 2011-11-06 18:49:30Z ed $
34 #include <ctype.h>
35 #include <err.h>
36 #include <locale.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <wchar.h>
41 #include <wctype.h>
44 * expand - expand tabs to equivalent spaces
46 static int nstops;
47 static int tabstops[100];
49 static void getstops(char *);
50 static void usage(void);
52 int
53 main(int argc, char *argv[])
55 const char *curfile;
56 wint_t wc;
57 int c, column;
58 int n;
59 int rval;
60 int width;
62 setlocale(LC_CTYPE, "");
64 /* handle obsolete syntax */
65 while (argc > 1 && argv[1][0] == '-' &&
66 isdigit((unsigned char)argv[1][1])) {
67 getstops(&argv[1][1]);
68 argc--; argv++;
71 while ((c = getopt (argc, argv, "t:")) != -1) {
72 switch (c) {
73 case 't':
74 getstops(optarg);
75 break;
76 case '?':
77 default:
78 usage();
79 /* NOTREACHED */
82 argc -= optind;
83 argv += optind;
85 rval = 0;
86 do {
87 if (argc > 0) {
88 if (freopen(argv[0], "r", stdin) == NULL) {
89 warn("%s", argv[0]);
90 rval = 1;
91 argc--, argv++;
92 continue;
94 curfile = argv[0];
95 argc--, argv++;
96 } else
97 curfile = "stdin";
98 column = 0;
99 while ((wc = getwchar()) != WEOF) {
100 switch (wc) {
101 case '\t':
102 if (nstops == 0) {
103 do {
104 putwchar(' ');
105 column++;
106 } while (column & 07);
107 continue;
109 if (nstops == 1) {
110 do {
111 putwchar(' ');
112 column++;
113 } while (((column - 1) % tabstops[0]) != (tabstops[0] - 1));
114 continue;
116 for (n = 0; n < nstops; n++)
117 if (tabstops[n] > column)
118 break;
119 if (n == nstops) {
120 putwchar(' ');
121 column++;
122 continue;
124 while (column < tabstops[n]) {
125 putwchar(' ');
126 column++;
128 continue;
130 case '\b':
131 if (column)
132 column--;
133 putwchar('\b');
134 continue;
136 default:
137 putwchar(wc);
138 if ((width = wcwidth(wc)) > 0)
139 column += width;
140 continue;
142 case '\n':
143 putwchar(wc);
144 column = 0;
145 continue;
148 if (ferror(stdin)) {
149 warn("%s", curfile);
150 rval = 1;
152 } while (argc > 0);
153 exit(rval);
156 static void
157 getstops(char *cp)
159 int i;
161 nstops = 0;
162 for (;;) {
163 i = 0;
164 while (*cp >= '0' && *cp <= '9')
165 i = i * 10 + *cp++ - '0';
166 if (i <= 0)
167 errx(1, "bad tab stop spec");
168 if (nstops > 0 && i <= tabstops[nstops-1])
169 errx(1, "bad tab stop spec");
170 if (nstops == sizeof(tabstops) / sizeof(*tabstops))
171 errx(1, "too many tab stops");
172 tabstops[nstops++] = i;
173 if (*cp == 0)
174 break;
175 if (*cp != ',' && !isblank((unsigned char)*cp))
176 errx(1, "bad tab stop spec");
177 cp++;
181 static void
182 usage(void)
184 fprintf(stderr, "usage: expand [-t tablist] [file ...]\n");
185 exit(1);