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