Annotation of src/usr.bin/expand/expand.c, Revision 1.11
1.11 ! deraadt 1: /* $OpenBSD: expand.c,v 1.10 2005/12/27 19:19:55 moritz 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.
1.5 millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: #include <stdio.h>
34: #include <stdlib.h>
35: #include <ctype.h>
36: #include <unistd.h>
1.8 mickey 37: #include <err.h>
1.1 deraadt 38:
39: /*
40: * expand - expand tabs to equivalent spaces
41: */
42: int nstops;
43: int tabstops[100];
44:
1.7 deraadt 45: static void getstops(char *);
46: static void usage(void);
1.1 deraadt 47:
48: int
1.6 deraadt 49: main(int argc, char *argv[])
1.1 deraadt 50: {
1.4 mpech 51: int c, column;
52: int n;
1.1 deraadt 53:
54: /* handle obsolete syntax */
1.3 deraadt 55: while (argc > 1 && argv[1][0] == '-' && isdigit(argv[1][1])) {
1.1 deraadt 56: getstops(&argv[1][1]);
57: argc--; argv++;
58: }
59:
60: while ((c = getopt (argc, argv, "t:")) != -1) {
61: switch (c) {
62: case 't':
63: getstops(optarg);
64: break;
65: case '?':
66: default:
67: usage();
68: /* NOTREACHED */
69: }
70: }
71: argc -= optind;
72: argv += optind;
73:
74: do {
75: if (argc > 0) {
1.8 mickey 76: if (freopen(argv[0], "r", stdin) == NULL)
1.9 cloder 77: err(1, "%s", argv[0]);
1.1 deraadt 78: argc--, argv++;
79: }
80: column = 0;
81: while ((c = getchar()) != EOF) {
82: switch (c) {
83: case '\t':
84: if (nstops == 0) {
85: do {
86: putchar(' ');
87: column++;
88: } while (column & 07);
89: continue;
90: }
91: if (nstops == 1) {
92: do {
93: putchar(' ');
94: column++;
1.6 deraadt 95: } while (((column - 1) %
96: tabstops[0]) != (tabstops[0] - 1));
1.1 deraadt 97: continue;
98: }
99: for (n = 0; n < nstops; n++)
100: if (tabstops[n] > column)
101: break;
102: if (n == nstops) {
103: putchar(' ');
104: column++;
105: continue;
106: }
107: while (column < tabstops[n]) {
108: putchar(' ');
109: column++;
110: }
111: continue;
112:
113: case '\b':
114: if (column)
115: column--;
116: putchar('\b');
117: continue;
118:
119: default:
120: putchar(c);
121: column++;
122: continue;
123:
124: case '\n':
125: putchar(c);
126: column = 0;
127: continue;
128: }
129: }
130: } while (argc > 0);
131: exit(0);
132: }
133:
134: static void
1.6 deraadt 135: getstops(char *cp)
1.1 deraadt 136: {
1.4 mpech 137: int i;
1.1 deraadt 138:
139: nstops = 0;
140: for (;;) {
141: i = 0;
142: while (*cp >= '0' && *cp <= '9')
143: i = i * 10 + *cp++ - '0';
144: if (i <= 0 || i > 256) {
145: bad:
1.8 mickey 146: errx(1, "Bad tab stop spec");
1.1 deraadt 147: }
148: if (nstops > 0 && i <= tabstops[nstops-1])
149: goto bad;
1.10 moritz 150: if (nstops >= sizeof(tabstops) / sizeof(tabstops[0]))
151: errx(1, "Too many tab stops");
1.1 deraadt 152: tabstops[nstops++] = i;
153: if (*cp == 0)
154: break;
155: if (*cp != ',' && *cp != ' ')
156: goto bad;
157: cp++;
158: }
159: }
160:
161: static void
1.6 deraadt 162: usage(void)
1.1 deraadt 163: {
1.8 mickey 164: extern char *__progname;
165: fprintf (stderr, "usage: %s [-t tablist] [file ...]\n", __progname);
1.1 deraadt 166: exit(1);
167: }