Annotation of src/usr.bin/expand/expand.c, Revision 1.4
1.4 ! mpech 1: /* $OpenBSD: expand.c,v 1.3 1998/01/22 17:41:09 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: expand.c,v 1.5 1995/09/02 06:19:46 jtc Exp $ */
3:
4: /*
5: * Copyright (c) 1980, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1980, 1993\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "@(#)expand.c 8.1 (Berkeley) 6/9/93";
46: #endif
1.4 ! mpech 47: static char rcsid[] = "$OpenBSD: expand.c,v 1.3 1998/01/22 17:41:09 deraadt Exp $";
1.1 deraadt 48: #endif /* not lint */
49:
50: #include <stdio.h>
51: #include <stdlib.h>
52: #include <ctype.h>
53: #include <unistd.h>
54:
55: /*
56: * expand - expand tabs to equivalent spaces
57: */
58: int nstops;
59: int tabstops[100];
60:
61: static void getstops();
62: static void usage();
63:
64: int
65: main(argc, argv)
66: int argc;
67: char *argv[];
68: {
1.4 ! mpech 69: int c, column;
! 70: int n;
1.1 deraadt 71:
72: /* handle obsolete syntax */
1.3 deraadt 73: while (argc > 1 && argv[1][0] == '-' && isdigit(argv[1][1])) {
1.1 deraadt 74: getstops(&argv[1][1]);
75: argc--; argv++;
76: }
77:
78: while ((c = getopt (argc, argv, "t:")) != -1) {
79: switch (c) {
80: case 't':
81: getstops(optarg);
82: break;
83: case '?':
84: default:
85: usage();
86: /* NOTREACHED */
87: }
88: }
89: argc -= optind;
90: argv += optind;
91:
92: do {
93: if (argc > 0) {
94: if (freopen(argv[0], "r", stdin) == NULL) {
95: perror(argv[0]);
96: exit(1);
97: }
98: argc--, argv++;
99: }
100: column = 0;
101: while ((c = getchar()) != EOF) {
102: switch (c) {
103: case '\t':
104: if (nstops == 0) {
105: do {
106: putchar(' ');
107: column++;
108: } while (column & 07);
109: continue;
110: }
111: if (nstops == 1) {
112: do {
113: putchar(' ');
114: column++;
115: } while (((column - 1) % tabstops[0]) != (tabstops[0] - 1));
116: continue;
117: }
118: for (n = 0; n < nstops; n++)
119: if (tabstops[n] > column)
120: break;
121: if (n == nstops) {
122: putchar(' ');
123: column++;
124: continue;
125: }
126: while (column < tabstops[n]) {
127: putchar(' ');
128: column++;
129: }
130: continue;
131:
132: case '\b':
133: if (column)
134: column--;
135: putchar('\b');
136: continue;
137:
138: default:
139: putchar(c);
140: column++;
141: continue;
142:
143: case '\n':
144: putchar(c);
145: column = 0;
146: continue;
147: }
148: }
149: } while (argc > 0);
150: exit(0);
151: }
152:
153: static void
154: getstops(cp)
1.4 ! mpech 155: char *cp;
1.1 deraadt 156: {
1.4 ! mpech 157: int i;
1.1 deraadt 158:
159: nstops = 0;
160: for (;;) {
161: i = 0;
162: while (*cp >= '0' && *cp <= '9')
163: i = i * 10 + *cp++ - '0';
164: if (i <= 0 || i > 256) {
165: bad:
166: fprintf(stderr, "Bad tab stop spec\n");
167: exit(1);
168: }
169: if (nstops > 0 && i <= tabstops[nstops-1])
170: goto bad;
171: tabstops[nstops++] = i;
172: if (*cp == 0)
173: break;
174: if (*cp != ',' && *cp != ' ')
175: goto bad;
176: cp++;
177: }
178: }
179:
180: static void
181: usage()
182: {
183: (void)fprintf (stderr, "usage: expand [-t tablist] [file ...]\n");
184: exit(1);
185: }