getNAME.c revision 1.4 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