xref: /netbsd-src/libexec/getNAME/getNAME.c (revision a5a68ff5f29de57339ca14f6c671c0a87714f1f8)
1 /*	$NetBSD: getNAME.c,v 1.4 1997/10/07 10:59:23 mrg 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 #if 0
41 static char sccsid[] = "@(#)getNAME.c	8.1 (Berkeley) 6/30/93";
42 #else
43 __RCSID("$NetBSD: getNAME.c,v 1.4 1997/10/07 10:59:23 mrg Exp $");
44 #endif
45 #endif /* not lint */
46 
47 /*
48  * Get name sections from manual pages.
49  *	-t	for building toc
50  *	-i	for building intro entries
51  *	other	apropos database
52  */
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 
57 int tocrc;
58 int intro;
59 int typeflag;
60 
61 void doname __P((char *));
62 void dorefname __P((char *));
63 void getfrom __P((char *));
64 void split __P((char *, char *));
65 void trimln __P((char *));
66 void usage __P((void));
67 int main __P((int, char *[]));
68 
69 int
70 main(argc, argv)
71 	int argc;
72 	char *argv[];
73 {
74 	extern int optind;
75 	int ch;
76 
77 	while ((ch = getopt(argc, argv, "itw")) != EOF)
78 		switch(ch) {
79 		case 'i':
80 			intro = 1;
81 			break;
82 		case 't':
83 			tocrc = 1;
84 			break;
85 		case 'w':
86 			typeflag = 1;
87 			break;
88 		case '?':
89 		default:
90 			usage();
91 		}
92 	argc -= optind;
93 	argv += optind;
94 
95 	if (!*argv)
96 		usage();
97 
98 	for (; *argv; ++argv)
99 		getfrom(*argv);
100 	exit(0);
101 }
102 
103 void
104 getfrom(pathname)
105 	char *pathname;
106 {
107 	int i = 0;
108 	char *name, *loc;
109 	char headbuf[BUFSIZ];
110 	char linbuf[BUFSIZ];
111 
112 	if (freopen(pathname, "r", stdin) == 0) {
113 		perror(pathname);
114 		return;
115 	}
116 	if ((name = strrchr(pathname, '/')))
117 		name++;
118 	else
119 		name = pathname;
120 	for (;;) {
121 		if (fgets(headbuf, sizeof headbuf, stdin) == NULL) {
122 			if (typeflag)
123 				printf("%-60s	UNKNOWN\n", pathname);
124 			return;
125 		}
126 		if (headbuf[0] != '.')
127 			continue;
128 		if ((headbuf[1] == 'T' && headbuf[2] == 'H') ||
129 		    (headbuf[1] == 't' && headbuf[2] == 'h'))
130 			break;
131 		if (headbuf[1] == 'D' && headbuf[2] == 't') {
132 			if (typeflag) {
133 				printf("%-60s	NEW\n", pathname);
134 				return;
135 			}
136 			goto newman;
137 		}
138 	}
139 	if (typeflag) {
140 		printf("%-60s	OLD\n", pathname);
141 		return;
142 	}
143 	for (;;) {
144 		if (fgets(linbuf, sizeof linbuf, stdin) == NULL)
145 			return;
146 		if (linbuf[0] != '.')
147 			continue;
148 		if (linbuf[1] == 'S' && linbuf[2] == 'H')
149 			break;
150 		if (linbuf[1] == 's' && linbuf[2] == 'h')
151 			break;
152 	}
153 	trimln(headbuf);
154 	if (tocrc)
155 		doname(name);
156 	if (!tocrc && !intro)
157 		printf("%s\t", headbuf);
158 	linbuf[0] = '\0';
159 	for (;;) {
160 		if (fgets(headbuf, sizeof headbuf, stdin) == NULL)
161 			break;
162 		if (headbuf[0] == '.') {
163 			if (headbuf[1] == 'S' && headbuf[2] == 'H')
164 				break;
165 			if (headbuf[1] == 's' && headbuf[2] == 'h')
166 				break;
167 		}
168 		if (i != 0)
169 			strcat(linbuf, " ");
170 		i++;
171 		trimln(headbuf);
172 		strcat(linbuf, headbuf);
173 	}
174 	if (intro)
175 		split(linbuf, name);
176 	else
177 		printf("%s\n", linbuf);
178 	return;
179 
180 newman:
181 	for (;;) {
182 		if (fgets(linbuf, sizeof linbuf, stdin) == NULL)
183 			return;
184 		if (linbuf[0] != '.')
185 			continue;
186 		if (linbuf[1] == 'S' && linbuf[2] == 'h')
187 			break;
188 	}
189 	trimln(headbuf);
190 	if (tocrc)
191 		doname(name);
192 	if (!tocrc && !intro)
193 		printf(".TH%s\t", &headbuf[3]);
194 	linbuf[0] = '\0';
195 	for (;;) {
196 		if (fgets(headbuf, sizeof headbuf, stdin) == NULL)
197 			break;
198 		if (headbuf[0] == '.') {
199 			if (headbuf[1] == 'S' && headbuf[2] == 'h')
200 				break;
201 		}
202 		if (i != 0)
203 			strcat(linbuf, " ");
204 		i++;
205 		trimln(headbuf);
206 		for (loc = strchr(headbuf, ' '); loc; loc = strchr(loc, ' '))
207 			if (loc[1] == ',')
208 				strcpy(loc, &loc[1]);
209 			else
210 				loc++;
211 		if (headbuf[0] != '.') {
212 			strcat(linbuf, headbuf);
213 		} else {
214 			/*
215 			 * Get rid of quotes in macros.
216 			 */
217 			for (loc = strchr(&headbuf[4], '"'); loc; ) {
218 				strcpy(loc, &loc[1]);
219 				loc = strchr(loc, '"');
220 			}
221 			/*
222 			 * Handle cross references
223 			 */
224 			if (headbuf[1] == 'X' && headbuf[2] == 'r') {
225 				for (loc = &headbuf[4]; *loc != ' '; loc++)
226 					continue;
227 				loc[0] = '(';
228 				loc[2] = ')';
229 				loc[3] = '\0';
230 			}
231 			/*
232 			 * Put dash between names and description.
233 			 */
234 			if (headbuf[1] == 'N' && headbuf[2] == 'd')
235 				strcat(linbuf, "\\- ");
236 			/*
237 			 * Skip over macro names.
238 			 */
239 			strcat(linbuf, &headbuf[4]);
240 		}
241 	}
242 	if (intro)
243 		split(linbuf, name);
244 	else
245 		printf("%s\n", linbuf);
246 }
247 
248 void
249 trimln(cp)
250 	register char *cp;
251 {
252 
253 	while (*cp)
254 		cp++;
255 	if (*--cp == '\n')
256 		*cp = 0;
257 }
258 
259 void
260 doname(name)
261 	char *name;
262 {
263 	register char *dp = name, *ep;
264 
265 again:
266 	while (*dp && *dp != '.')
267 		putchar(*dp++);
268 	if (*dp)
269 		for (ep = dp+1; *ep; ep++)
270 			if (*ep == '.') {
271 				putchar(*dp++);
272 				goto again;
273 			}
274 	putchar('(');
275 	if (*dp)
276 		dp++;
277 	while (*dp)
278 		putchar (*dp++);
279 	putchar(')');
280 	putchar(' ');
281 }
282 
283 void
284 split(line, name)
285 	char *line, *name;
286 {
287 	register char *cp, *dp;
288 	char *sp, *sep;
289 
290 	cp = strchr(line, '-');
291 	if (cp == 0)
292 		return;
293 	sp = cp + 1;
294 	for (--cp; *cp == ' ' || *cp == '\t' || *cp == '\\'; cp--)
295 		;
296 	*++cp = '\0';
297 	while (*sp && (*sp == ' ' || *sp == '\t'))
298 		sp++;
299 	for (sep = "", dp = line; dp && *dp; dp = cp, sep = "\n") {
300 		cp = strchr(dp, ',');
301 		if (cp) {
302 			register char *tp;
303 
304 			for (tp = cp - 1; *tp == ' ' || *tp == '\t'; tp--)
305 				;
306 			*++tp = '\0';
307 			for (++cp; *cp == ' ' || *cp == '\t'; cp++)
308 				;
309 		}
310 		printf("%s%s\t", sep, dp);
311 		dorefname(name);
312 		printf("\t%s", sp);
313 	}
314 }
315 
316 void
317 dorefname(name)
318 	char *name;
319 {
320 	register char *dp = name, *ep;
321 
322 again:
323 	while (*dp && *dp != '.')
324 		putchar(*dp++);
325 	if (*dp)
326 		for (ep = dp+1; *ep; ep++)
327 			if (*ep == '.') {
328 				putchar(*dp++);
329 				goto again;
330 			}
331 	putchar('.');
332 	if (*dp)
333 		dp++;
334 	while (*dp)
335 		putchar (*dp++);
336 }
337 
338 void
339 usage()
340 {
341 	(void)fprintf(stderr, "usage: getNAME [-it] file ...\n");
342 	exit(1);
343 }
344