GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/expand/expand.c Lines: 0 67 0.0 %
Date: 2016-12-06 Branches: 0 74 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: expand.c,v 1.14 2015/10/09 01:37:07 deraadt Exp $	*/
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. Neither the name of the University nor the names of its contributors
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>
37
#include <err.h>
38
39
/*
40
 * expand - expand tabs to equivalent spaces
41
 */
42
int	nstops;
43
int	tabstops[100];
44
45
static void getstops(char *);
46
static void usage(void);
47
48
int
49
main(int argc, char *argv[])
50
{
51
	int c, column;
52
	int n;
53
54
	if (pledge("stdio rpath wpath cpath", NULL) == -1)
55
		err(1, "pledge");
56
57
	/* handle obsolete syntax */
58
	while (argc > 1 && argv[1][0] == '-' &&
59
	    isdigit((unsigned char)argv[1][1])) {
60
		getstops(&argv[1][1]);
61
		argc--; argv++;
62
	}
63
64
	while ((c = getopt (argc, argv, "t:")) != -1) {
65
		switch (c) {
66
		case 't':
67
			getstops(optarg);
68
			break;
69
		case '?':
70
		default:
71
			usage();
72
			/* NOTREACHED */
73
		}
74
	}
75
	argc -= optind;
76
	argv += optind;
77
78
	do {
79
		if (argc > 0) {
80
			if (freopen(argv[0], "r", stdin) == NULL)
81
				err(1, "%s", argv[0]);
82
			argc--, argv++;
83
		}
84
		column = 0;
85
		while ((c = getchar()) != EOF) {
86
			switch (c) {
87
			case '\t':
88
				if (nstops == 0) {
89
					do {
90
						putchar(' ');
91
						column++;
92
					} while (column & 07);
93
					continue;
94
				}
95
				if (nstops == 1) {
96
					do {
97
						putchar(' ');
98
						column++;
99
					} while (((column - 1) %
100
					    tabstops[0]) != (tabstops[0] - 1));
101
					continue;
102
				}
103
				for (n = 0; n < nstops; n++)
104
					if (tabstops[n] > column)
105
						break;
106
				if (n == nstops) {
107
					putchar(' ');
108
					column++;
109
					continue;
110
				}
111
				while (column < tabstops[n]) {
112
					putchar(' ');
113
					column++;
114
				}
115
				continue;
116
117
			case '\b':
118
				if (column)
119
					column--;
120
				putchar('\b');
121
				continue;
122
123
			default:
124
				putchar(c);
125
				column++;
126
				continue;
127
128
			case '\n':
129
				putchar(c);
130
				column = 0;
131
				continue;
132
			}
133
		}
134
	} while (argc > 0);
135
	exit(0);
136
}
137
138
static void
139
getstops(char *cp)
140
{
141
	int i;
142
143
	nstops = 0;
144
	for (;;) {
145
		i = 0;
146
		while (*cp >= '0' && *cp <= '9')
147
			i = i * 10 + *cp++ - '0';
148
		if (i <= 0 || i > 256) {
149
bad:
150
			errx(1, "Bad tab stop spec");
151
		}
152
		if (nstops > 0 && i <= tabstops[nstops-1])
153
			goto bad;
154
		if (nstops >= sizeof(tabstops) / sizeof(tabstops[0]))
155
			errx(1, "Too many tab stops");
156
		tabstops[nstops++] = i;
157
		if (*cp == 0)
158
			break;
159
		if (*cp != ',' && *cp != ' ')
160
			goto bad;
161
		cp++;
162
	}
163
}
164
165
static void
166
usage(void)
167
{
168
	extern char *__progname;
169
	fprintf (stderr, "usage: %s [-t tablist] [file ...]\n", __progname);
170
	exit(1);
171
}