xref: /original-bsd/usr.bin/expand/expand.c (revision a76afa45)
1 /*
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)expand.c	5.2 (Berkeley) 10/26/88";
26 #endif /* not lint */
27 
28 #include <stdio.h>
29 /*
30  * expand - expand tabs to equivalent spaces
31  */
32 int	nstops;
33 int	tabstops[100];
34 
35 main(argc, argv)
36 	int argc;
37 	char *argv[];
38 {
39 	register int c, column;
40 	register int n;
41 
42 	argc--, argv++;
43 	do {
44 		while (argc > 0 && argv[0][0] == '-') {
45 			getstops(argv[0]);
46 			argc--, argv++;
47 		}
48 		if (argc > 0) {
49 			if (freopen(argv[0], "r", stdin) == NULL) {
50 				perror(argv[0]);
51 				exit(1);
52 			}
53 			argc--, argv++;
54 		}
55 		column = 0;
56 		for (;;) {
57 			c = getc(stdin);
58 			if (c == -1)
59 				break;
60 			switch (c) {
61 
62 			case '\t':
63 				if (nstops == 0) {
64 					do {
65 						putchar(' ');
66 						column++;
67 					} while (column & 07);
68 					continue;
69 				}
70 				if (nstops == 1) {
71 					do {
72 						putchar(' ');
73 						column++;
74 					} while (((column - 1) % tabstops[0]) != (tabstops[0] - 1));
75 					continue;
76 				}
77 				for (n = 0; n < nstops; n++)
78 					if (tabstops[n] > column)
79 						break;
80 				if (n == nstops) {
81 					putchar(' ');
82 					column++;
83 					continue;
84 				}
85 				while (column < tabstops[n]) {
86 					putchar(' ');
87 					column++;
88 				}
89 				continue;
90 
91 			case '\b':
92 				if (column)
93 					column--;
94 				putchar('\b');
95 				continue;
96 
97 			default:
98 				putchar(c);
99 				column++;
100 				continue;
101 
102 			case '\n':
103 				putchar(c);
104 				column = 0;
105 				continue;
106 			}
107 		}
108 	} while (argc > 0);
109 	exit(0);
110 }
111 
112 getstops(cp)
113 	register char *cp;
114 {
115 	register int i;
116 
117 	nstops = 0;
118 	cp++;
119 	for (;;) {
120 		i = 0;
121 		while (*cp >= '0' && *cp <= '9')
122 			i = i * 10 + *cp++ - '0';
123 		if (i <= 0 || i > 256) {
124 bad:
125 			fprintf(stderr, "Bad tab stop spec\n");
126 			exit(1);
127 		}
128 		if (nstops > 0 && i <= tabstops[nstops-1])
129 			goto bad;
130 		tabstops[nstops++] = i;
131 		if (*cp == 0)
132 			break;
133 		if (*cp++ != ',')
134 			goto bad;
135 	}
136 }
137