Expand PMF_FN_* macros.
[netbsd-mini2440.git] / usr.bin / soelim / soelim.c
blob81d5ca9f3e46759700b3521acd40bb420311ae4f
1 /* $NetBSD: soelim.c,v 1.13 2004/01/05 23:23:37 jmmv Exp $ */
3 /*
4 * Copyright (c) 1980, 1993
5 * The Regents of the University of California. All rights reserved.
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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
35 The Regents of the University of California. All rights reserved.");
36 #endif /* not lint */
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)soelim.c 8.1 (Berkeley) 6/6/93";
41 #endif
42 __RCSID("$NetBSD: soelim.c,v 1.13 2004/01/05 23:23:37 jmmv Exp $");
43 #endif /* not lint */
46 * soelim - a filter to process n/troff input eliminating .so's
48 * Author: Bill Joy UCB July 8, 1977
50 * This program eliminates .so's from a n/troff input stream.
51 * It can be used to prepare safe input for submission to the
52 * phototypesetter since the software supporting the operator
53 * doesn't let him do chdir.
55 * This is a kludge and the operator should be given the
56 * ability to do chdir.
58 * This program is more generally useful, it turns out, because
59 * the program tbl doesn't understand ".so" directives.
61 #include <sys/param.h>
62 #include <err.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 #include <unistd.h>
68 #define STDIN_NAME "-"
70 struct path {
71 char **list;
72 size_t n, c;
75 static int process(struct path *, const char *);
76 static void initpath(struct path *);
77 static void addpath(struct path *, const char *);
78 static FILE *openpath(struct path *, const char *, const char *);
80 int main(int, char **);
83 static void
84 initpath(struct path *p)
86 p->list = NULL;
87 p->n = p->c = 0;
90 static void
91 addpath(struct path *p, const char *dir)
93 char **n;
95 if (p->list == NULL || p->n <= p->c - 2) {
96 n = realloc(p->list, (p->n + 10) * sizeof(p->list[0]));
97 if (n == NULL)
98 err(1, NULL);
99 p->list = n;
100 p->n += 10;
103 if ((p->list[p->c++] = strdup(dir)) == NULL)
104 err(1, NULL);
106 p->list[p->c] = NULL;
109 static FILE *
110 openpath(struct path *p, const char *name, const char *parm)
112 char filename[MAXPATHLEN];
113 const char *f;
114 FILE *fp;
115 size_t i;
117 if (*name == '/' || p->c == 0)
118 return fopen(name, parm);
120 for (i = 0; i < p->c; i++) {
121 if (p->list[i][0] == '\0')
122 f = name;
123 else {
124 (void)snprintf(filename, sizeof(filename), "%s/%s",
125 p->list[i], name);
126 f = filename;
128 if ((fp = fopen(f, parm)) != NULL)
129 return fp;
131 return NULL;
135 main(int argc, char *argv[])
137 struct path p;
138 int c;
140 initpath(&p);
141 addpath(&p, ".");
143 while ((c = getopt(argc, argv, "I:")) != -1)
144 switch (c) {
145 case 'I':
146 addpath(&p, optarg);
147 break;
148 default:
149 (void)fprintf(stderr,
150 "usage: %s [-I<dir>] [files...]\n",
151 getprogname());
152 exit(1);
155 argc -= optind;
156 argv += optind;
158 if (argc == 0) {
159 (void)process(&p, STDIN_NAME);
160 exit(0);
162 do {
163 (void)process(&p, argv[0]);
164 argv++;
165 argc--;
166 } while (argc > 0);
167 exit(0);
171 process(struct path *p, const char *file)
173 char *cp;
174 int c;
175 char fname[BUFSIZ];
176 FILE *soee;
177 int isfile;
179 if (!strcmp(file, STDIN_NAME)) {
180 soee = stdin;
181 } else {
182 soee = openpath(p, file, "r");
183 if (soee == NULL) {
184 warn("Cannot open `%s'", file);
185 return(-1);
188 for (;;) {
189 c = getc(soee);
190 if (c == EOF)
191 break;
192 if (c != '.')
193 goto simple;
194 c = getc(soee);
195 if (c != 's') {
196 putchar('.');
197 goto simple;
199 c = getc(soee);
200 if (c != 'o') {
201 printf(".s");
202 goto simple;
205 c = getc(soee);
206 while (c == ' ' || c == '\t');
207 cp = fname;
208 isfile = 0;
209 for (;;) {
210 switch (c) {
212 case ' ':
213 case '\t':
214 case '\n':
215 case EOF:
216 goto donename;
218 default:
219 *cp++ = c;
220 c = getc(soee);
221 isfile++;
222 continue;
225 donename:
226 if (cp == fname) {
227 printf(".so");
228 goto simple;
230 *cp = 0;
231 if (process(p, fname) < 0)
232 if (isfile)
233 printf(".so %s\n", fname);
234 continue;
235 simple:
236 if (c == EOF)
237 break;
238 putchar(c);
239 if (c != '\n') {
240 c = getc(soee);
241 goto simple;
244 if (soee != stdin) {
245 fclose(soee);
247 return(0);