xref: /original-bsd/usr.bin/expand/expand.c (revision c7de680c)
1 static char *sccsid = "@(#)expand.c	4.2 (Berkeley) 02/07/81";
2 #include <stdio.h>
3 /*
4  * expand - expand tabs to equivalent spaces
5  */
6 char	obuf[BUFSIZ];
7 int	nstops;
8 int	tabstops[100];
9 
10 main(argc, argv)
11 	int argc;
12 	char *argv[];
13 {
14 	register int c, column;
15 	register int n;
16 
17 	setbuf(stdout, obuf);
18 	argc--, argv++;
19 	do {
20 		while (argc > 0 && argv[0][0] == '-') {
21 			getstops(argv[0]);
22 			argc--, argv++;
23 		}
24 		if (argc > 0) {
25 			if (freopen(argv[0], "r", stdin) == NULL) {
26 				perror(argv[0]);
27 				exit(1);
28 			}
29 			argc--, argv++;
30 		}
31 		column = 0;
32 		for (;;) {
33 			c = getc(stdin);
34 			if (c == -1)
35 				break;
36 			switch (c) {
37 
38 			case '\t':
39 				if (nstops == 0) {
40 					do {
41 						putchar(' ');
42 						column++;
43 					} while (column & 07);
44 					continue;
45 				}
46 				if (nstops == 1) {
47 					do {
48 						putchar(' ');
49 						column++;
50 					} while (((column - 1) % tabstops[0]) != (tabstops[0] - 1));
51 					continue;
52 				}
53 				for (n = 0; n < nstops; n++)
54 					if (tabstops[n] > column)
55 						break;
56 				if (n == nstops) {
57 					putchar(' ');
58 					column++;
59 					continue;
60 				}
61 				while (column < tabstops[n]) {
62 					putchar(' ');
63 					column++;
64 				}
65 				continue;
66 
67 			case '\b':
68 				if (column)
69 					column--;
70 				putchar('\b');
71 				continue;
72 
73 			default:
74 				putchar(c);
75 				column++;
76 				continue;
77 
78 			case '\n':
79 				putchar(c);
80 				column = 0;
81 				continue;
82 			}
83 		}
84 	} while (argc > 0);
85 	exit(0);
86 }
87 
88 getstops(cp)
89 	register char *cp;
90 {
91 	register int i;
92 
93 	nstops = 0;
94 	cp++;
95 	for (;;) {
96 		i = 0;
97 		while (*cp >= '0' && *cp <= '9')
98 			i = i * 10 + *cp++ - '0';
99 		if (i <= 0 || i > 256) {
100 bad:
101 			fprintf(stderr, "Bad tab stop spec\n");
102 			exit(1);
103 		}
104 		if (nstops > 0 && i <= tabstops[nstops-1])
105 			goto bad;
106 		tabstops[nstops++] = i;
107 		if (*cp == 0)
108 			break;
109 		if (*cp++ != ',')
110 			goto bad;
111 	}
112 }
113