soelim.c revision 1.5 1 /* $NetBSD: soelim.c,v 1.5 1997/12/21 17:04:16 christos 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.5 1997/12/21 17:04:16 christos 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 <stdio.h>
67 #include <string.h>
68 #include <stdlib.h>
69 #include <err.h>
70
71 #define STDIN_NAME "-"
72
73 struct path {
74 char **list;
75 size_t n, c;
76 };
77
78 static int process __P((struct path *, char *));
79 static void initpath __P((struct path *));
80 static void addpath __P((struct path *, const char *));
81 static FILE *openpath __P((struct path *, const char *, const char *));
82
83 int main __P((int, char **));
84
85
86 static void
87 initpath(p)
88 struct path *p;
89 {
90 p->list = NULL;
91 p->n = p->c = 0;
92 }
93
94 static void
95 addpath(p, dir)
96 struct path *p;
97 const char *dir;
98 {
99 if (p->list == NULL || p->n <= p->c - 2) {
100 p->n += 10;
101 p->list = realloc(p->list, p->n * sizeof(p->list[0]));
102 if (p->list == NULL)
103 err(1, "%s", "");
104 }
105
106 if ((p->list[p->c++] = strdup(dir)) == NULL)
107 err(1, "%s", "");
108
109 p->list[p->c] = NULL;
110 }
111
112 static FILE *
113 openpath(p, name, parm)
114 struct path *p;
115 const char *name;
116 const char *parm;
117 {
118 char filename[MAXPATHLEN];
119 const char *f;
120 FILE *fp;
121 size_t i;
122
123 if (*name == '/' || p->c == 0)
124 return fopen(name, parm);
125
126 for (i = 0; i < p->c; i++) {
127 if (p->list[i][0] == '\0')
128 f = name;
129 else {
130 (void)snprintf(filename, sizeof(filename), "%s/%s",
131 p->list[i], name);
132 f = filename;
133 }
134 if ((fp = fopen(f, parm)) != NULL)
135 return fp;
136 }
137 return NULL;
138 }
139
140 int
141 main(argc, argv)
142 int argc;
143 char *argv[];
144 {
145 extern char *__progname;
146 struct path p;
147 int c;
148
149 initpath(&p);
150 addpath(&p, ".");
151
152 while ((c = getopt(argc, argv, "I:")) != -1)
153 switch (c) {
154 case 'I':
155 addpath(&p, optarg);
156 break;
157 default:
158 (void)fprintf(stderr,
159 "Usage: %s [-I<dir>] [files...]\n", __progname);
160 exit(1);
161 }
162
163 argc -= optind;
164 argv += optind;
165
166 if (argc == 0) {
167 (void)process(&p, STDIN_NAME);
168 exit(0);
169 }
170 do {
171 (void)process(&p, argv[0]);
172 argv++;
173 argc--;
174 } while (argc > 0);
175 exit(0);
176 }
177
178 int
179 process(p, file)
180 struct path *p;
181 char *file;
182 {
183 char *cp;
184 int c;
185 char fname[BUFSIZ];
186 FILE *soee;
187 int isfile;
188
189 if (!strcmp(file, STDIN_NAME)) {
190 soee = stdin;
191 } else {
192 soee = openpath(p, file, "r");
193 if (soee == NULL) {
194 warn("Cannot open `%s'", file);
195 return(-1);
196 }
197 }
198 for (;;) {
199 c = getc(soee);
200 if (c == EOF)
201 break;
202 if (c != '.')
203 goto simple;
204 c = getc(soee);
205 if (c != 's') {
206 putchar('.');
207 goto simple;
208 }
209 c = getc(soee);
210 if (c != 'o') {
211 printf(".s");
212 goto simple;
213 }
214 do
215 c = getc(soee);
216 while (c == ' ' || c == '\t');
217 cp = fname;
218 isfile = 0;
219 for (;;) {
220 switch (c) {
221
222 case ' ':
223 case '\t':
224 case '\n':
225 case EOF:
226 goto donename;
227
228 default:
229 *cp++ = c;
230 c = getc(soee);
231 isfile++;
232 continue;
233 }
234 }
235 donename:
236 if (cp == fname) {
237 printf(".so");
238 goto simple;
239 }
240 *cp = 0;
241 if (process(p, fname) < 0)
242 if (isfile)
243 printf(".so %s\n", fname);
244 continue;
245 simple:
246 if (c == EOF)
247 break;
248 putchar(c);
249 if (c != '\n') {
250 c = getc(soee);
251 goto simple;
252 }
253 }
254 if (soee != stdin) {
255 fclose(soee);
256 }
257 return(0);
258 }
259