soelim.c revision 1.6 1 /* $NetBSD: soelim.c,v 1.6 1998/02/03 04:12:24 perry Exp $ */
2
3 /*
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
39 The Regents of the University of California. All rights reserved.\n");
40 #endif /* not lint */
41
42 #ifndef lint
43 #if 0
44 static char sccsid[] = "@(#)soelim.c 8.1 (Berkeley) 6/6/93";
45 #endif
46 __RCSID("$NetBSD: soelim.c,v 1.6 1998/02/03 04:12:24 perry Exp $");
47 #endif /* not lint */
48
49 /*
50 * soelim - a filter to process n/troff input eliminating .so's
51 *
52 * Author: Bill Joy UCB July 8, 1977
53 *
54 * This program eliminates .so's from a n/troff input stream.
55 * It can be used to prepare safe input for submission to the
56 * phototypesetter since the software supporting the operator
57 * doesn't let him do chdir.
58 *
59 * This is a kludge and the operator should be given the
60 * ability to do chdir.
61 *
62 * This program is more generally useful, it turns out, because
63 * the program tbl doesn't understand ".so" directives.
64 */
65 #include <sys/param.h>
66 #include <err.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <unistd.h>
71
72 #define STDIN_NAME "-"
73
74 struct path {
75 char **list;
76 size_t n, c;
77 };
78
79 static int process __P((struct path *, char *));
80 static void initpath __P((struct path *));
81 static void addpath __P((struct path *, const char *));
82 static FILE *openpath __P((struct path *, const char *, const char *));
83
84 int main __P((int, char **));
85
86
87 static void
88 initpath(p)
89 struct path *p;
90 {
91 p->list = NULL;
92 p->n = p->c = 0;
93 }
94
95 static void
96 addpath(p, dir)
97 struct path *p;
98 const char *dir;
99 {
100 if (p->list == NULL || p->n <= p->c - 2) {
101 p->n += 10;
102 p->list = realloc(p->list, p->n * sizeof(p->list[0]));
103 if (p->list == NULL)
104 err(1, "%s", "");
105 }
106
107 if ((p->list[p->c++] = strdup(dir)) == NULL)
108 err(1, "%s", "");
109
110 p->list[p->c] = NULL;
111 }
112
113 static FILE *
114 openpath(p, name, parm)
115 struct path *p;
116 const char *name;
117 const char *parm;
118 {
119 char filename[MAXPATHLEN];
120 const char *f;
121 FILE *fp;
122 size_t i;
123
124 if (*name == '/' || p->c == 0)
125 return fopen(name, parm);
126
127 for (i = 0; i < p->c; i++) {
128 if (p->list[i][0] == '\0')
129 f = name;
130 else {
131 (void)snprintf(filename, sizeof(filename), "%s/%s",
132 p->list[i], name);
133 f = filename;
134 }
135 if ((fp = fopen(f, parm)) != NULL)
136 return fp;
137 }
138 return NULL;
139 }
140
141 int
142 main(argc, argv)
143 int argc;
144 char *argv[];
145 {
146 extern char *__progname;
147 struct path p;
148 int c;
149
150 initpath(&p);
151 addpath(&p, ".");
152
153 while ((c = getopt(argc, argv, "I:")) != -1)
154 switch (c) {
155 case 'I':
156 addpath(&p, optarg);
157 break;
158 default:
159 (void)fprintf(stderr,
160 "Usage: %s [-I<dir>] [files...]\n", __progname);
161 exit(1);
162 }
163
164 argc -= optind;
165 argv += optind;
166
167 if (argc == 0) {
168 (void)process(&p, STDIN_NAME);
169 exit(0);
170 }
171 do {
172 (void)process(&p, argv[0]);
173 argv++;
174 argc--;
175 } while (argc > 0);
176 exit(0);
177 }
178
179 int
180 process(p, file)
181 struct path *p;
182 char *file;
183 {
184 char *cp;
185 int c;
186 char fname[BUFSIZ];
187 FILE *soee;
188 int isfile;
189
190 if (!strcmp(file, STDIN_NAME)) {
191 soee = stdin;
192 } else {
193 soee = openpath(p, file, "r");
194 if (soee == NULL) {
195 warn("Cannot open `%s'", file);
196 return(-1);
197 }
198 }
199 for (;;) {
200 c = getc(soee);
201 if (c == EOF)
202 break;
203 if (c != '.')
204 goto simple;
205 c = getc(soee);
206 if (c != 's') {
207 putchar('.');
208 goto simple;
209 }
210 c = getc(soee);
211 if (c != 'o') {
212 printf(".s");
213 goto simple;
214 }
215 do
216 c = getc(soee);
217 while (c == ' ' || c == '\t');
218 cp = fname;
219 isfile = 0;
220 for (;;) {
221 switch (c) {
222
223 case ' ':
224 case '\t':
225 case '\n':
226 case EOF:
227 goto donename;
228
229 default:
230 *cp++ = c;
231 c = getc(soee);
232 isfile++;
233 continue;
234 }
235 }
236 donename:
237 if (cp == fname) {
238 printf(".so");
239 goto simple;
240 }
241 *cp = 0;
242 if (process(p, fname) < 0)
243 if (isfile)
244 printf(".so %s\n", fname);
245 continue;
246 simple:
247 if (c == EOF)
248 break;
249 putchar(c);
250 if (c != '\n') {
251 c = getc(soee);
252 goto simple;
253 }
254 }
255 if (soee != stdin) {
256 fclose(soee);
257 }
258 return(0);
259 }
260