Annotation of src/usr.bin/expand/expand.c, Revision 1.12
1.12 ! deraadt 1: /* $OpenBSD: expand.c,v 1.11 2009/10/27 23:59:37 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.
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.12 ! deraadt 55: while (argc > 1 && argv[1][0] == '-' &&
! 56: isdigit((unsigned char)argv[1][1])) {
1.1 deraadt 57: getstops(&argv[1][1]);
58: argc--; argv++;
59: }
60:
61: while ((c = getopt (argc, argv, "t:")) != -1) {
62: switch (c) {
63: case 't':
64: getstops(optarg);
65: break;
66: case '?':
67: default:
68: usage();
69: /* NOTREACHED */
70: }
71: }
72: argc -= optind;
73: argv += optind;
74:
75: do {
76: if (argc > 0) {
1.8 mickey 77: if (freopen(argv[0], "r", stdin) == NULL)
1.9 cloder 78: err(1, "%s", argv[0]);
1.1 deraadt 79: argc--, argv++;
80: }
81: column = 0;
82: while ((c = getchar()) != EOF) {
83: switch (c) {
84: case '\t':
85: if (nstops == 0) {
86: do {
87: putchar(' ');
88: column++;
89: } while (column & 07);
90: continue;
91: }
92: if (nstops == 1) {
93: do {
94: putchar(' ');
95: column++;
1.6 deraadt 96: } while (((column - 1) %
97: tabstops[0]) != (tabstops[0] - 1));
1.1 deraadt 98: continue;
99: }
100: for (n = 0; n < nstops; n++)
101: if (tabstops[n] > column)
102: break;
103: if (n == nstops) {
104: putchar(' ');
105: column++;
106: continue;
107: }
108: while (column < tabstops[n]) {
109: putchar(' ');
110: column++;
111: }
112: continue;
113:
114: case '\b':
115: if (column)
116: column--;
117: putchar('\b');
118: continue;
119:
120: default:
121: putchar(c);
122: column++;
123: continue;
124:
125: case '\n':
126: putchar(c);
127: column = 0;
128: continue;
129: }
130: }
131: } while (argc > 0);
132: exit(0);
133: }
134:
135: static void
1.6 deraadt 136: getstops(char *cp)
1.1 deraadt 137: {
1.4 mpech 138: int i;
1.1 deraadt 139:
140: nstops = 0;
141: for (;;) {
142: i = 0;
143: while (*cp >= '0' && *cp <= '9')
144: i = i * 10 + *cp++ - '0';
145: if (i <= 0 || i > 256) {
146: bad:
1.8 mickey 147: errx(1, "Bad tab stop spec");
1.1 deraadt 148: }
149: if (nstops > 0 && i <= tabstops[nstops-1])
150: goto bad;
1.10 moritz 151: if (nstops >= sizeof(tabstops) / sizeof(tabstops[0]))
152: errx(1, "Too many tab stops");
1.1 deraadt 153: tabstops[nstops++] = i;
154: if (*cp == 0)
155: break;
156: if (*cp != ',' && *cp != ' ')
157: goto bad;
158: cp++;
159: }
160: }
161:
162: static void
1.6 deraadt 163: usage(void)
1.1 deraadt 164: {
1.8 mickey 165: extern char *__progname;
166: fprintf (stderr, "usage: %s [-t tablist] [file ...]\n", __progname);
1.1 deraadt 167: exit(1);
168: }