getNAME.c revision 1.3 1 /*-
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 static char copyright[] =
36 "@(#) Copyright (c) 1980, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
38 #endif /* not lint */
39
40 #ifndef lint
41 static char rcsid[] = "$Id: getNAME.c,v 1.3 1997/04/29 20:39:11 tls Exp $";
42 #if 0
43 static char sccsid[] = "@(#)getNAME.c 8.1 (Berkeley) 6/30/93";
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
68 int
69 main(argc, argv)
70 int argc;
71 char *argv[];
72 {
73 extern int optind;
74 int ch;
75
76 while ((ch = getopt(argc, argv, "itw")) != EOF)
77 switch(ch) {
78 case 'i':
79 intro = 1;
80 break;
81 case 't':
82 tocrc = 1;
83 break;
84 case 'w':
85 typeflag = 1;
86 break;
87 case '?':
88 default:
89 usage();
90 }
91 argc -= optind;
92 argv += optind;
93
94 if (!*argv)
95 usage();
96
97 for (; *argv; ++argv)
98 getfrom(*argv);
99 exit(0);
100 }
101
102 void
103 getfrom(pathname)
104 char *pathname;
105 {
106 int i = 0;
107 char *name, *loc;
108 char headbuf[BUFSIZ];
109 char linbuf[BUFSIZ];
110
111 if (freopen(pathname, "r", stdin) == 0) {
112 perror(pathname);
113 return;
114 }
115 if (name = strrchr(pathname, '/'))
116 name++;
117 else
118 name = pathname;
119 for (;;) {
120 if (fgets(headbuf, sizeof headbuf, stdin) == NULL) {
121 if (typeflag)
122 printf("%-60s UNKNOWN\n", pathname);
123 return;
124 }
125 if (headbuf[0] != '.')
126 continue;
127 if ((headbuf[1] == 'T' && headbuf[2] == 'H') ||
128 (headbuf[1] == 't' && headbuf[2] == 'h'))
129 break;
130 if (headbuf[1] == 'D' && headbuf[2] == 't') {
131 if (typeflag) {
132 printf("%-60s NEW\n", pathname);
133 return;
134 }
135 goto newman;
136 }
137 }
138 if (typeflag) {
139 printf("%-60s OLD\n", pathname);
140 return;
141 }
142 for (;;) {
143 if (fgets(linbuf, sizeof linbuf, stdin) == NULL)
144 return;
145 if (linbuf[0] != '.')
146 continue;
147 if (linbuf[1] == 'S' && linbuf[2] == 'H')
148 break;
149 if (linbuf[1] == 's' && linbuf[2] == 'h')
150 break;
151 }
152 trimln(headbuf);
153 if (tocrc)
154 doname(name);
155 if (!tocrc && !intro)
156 printf("%s\t", headbuf);
157 linbuf[0] = '\0';
158 for (;;) {
159 if (fgets(headbuf, sizeof headbuf, stdin) == NULL)
160 break;
161 if (headbuf[0] == '.') {
162 if (headbuf[1] == 'S' && headbuf[2] == 'H')
163 break;
164 if (headbuf[1] == 's' && headbuf[2] == 'h')
165 break;
166 }
167 if (i != 0)
168 strcat(linbuf, " ");
169 i++;
170 trimln(headbuf);
171 strcat(linbuf, headbuf);
172 }
173 if (intro)
174 split(linbuf, name);
175 else
176 printf("%s\n", linbuf);
177 return;
178
179 newman:
180 for (;;) {
181 if (fgets(linbuf, sizeof linbuf, stdin) == NULL)
182 return;
183 if (linbuf[0] != '.')
184 continue;
185 if (linbuf[1] == 'S' && linbuf[2] == 'h')
186 break;
187 }
188 trimln(headbuf);
189 if (tocrc)
190 doname(name);
191 if (!tocrc && !intro)
192 printf(".TH%s\t", &headbuf[3]);
193 linbuf[0] = '\0';
194 for (;;) {
195 if (fgets(headbuf, sizeof headbuf, stdin) == NULL)
196 break;
197 if (headbuf[0] == '.') {
198 if (headbuf[1] == 'S' && headbuf[2] == 'h')
199 break;
200 }
201 if (i != 0)
202 strcat(linbuf, " ");
203 i++;
204 trimln(headbuf);
205 for (loc = strchr(headbuf, ' '); loc; loc = strchr(loc, ' '))
206 if (loc[1] == ',')
207 strcpy(loc, &loc[1]);
208 else
209 loc++;
210 if (headbuf[0] != '.') {
211 strcat(linbuf, headbuf);
212 } else {
213 /*
214 * Get rid of quotes in macros.
215 */
216 for (loc = strchr(&headbuf[4], '"'); loc; ) {
217 strcpy(loc, &loc[1]);
218 loc = strchr(loc, '"');
219 }
220 /*
221 * Handle cross references
222 */
223 if (headbuf[1] == 'X' && headbuf[2] == 'r') {
224 for (loc = &headbuf[4]; *loc != ' '; loc++)
225 continue;
226 loc[0] = '(';
227 loc[2] = ')';
228 loc[3] = '\0';
229 }
230 /*
231 * Put dash between names and description.
232 */
233 if (headbuf[1] == 'N' && headbuf[2] == 'd')
234 strcat(linbuf, "\\- ");
235 /*
236 * Skip over macro names.
237 */
238 strcat(linbuf, &headbuf[4]);
239 }
240 }
241 if (intro)
242 split(linbuf, name);
243 else
244 printf("%s\n", linbuf);
245 }
246
247 void
248 trimln(cp)
249 register char *cp;
250 {
251
252 while (*cp)
253 cp++;
254 if (*--cp == '\n')
255 *cp = 0;
256 }
257
258 void
259 doname(name)
260 char *name;
261 {
262 register char *dp = name, *ep;
263
264 again:
265 while (*dp && *dp != '.')
266 putchar(*dp++);
267 if (*dp)
268 for (ep = dp+1; *ep; ep++)
269 if (*ep == '.') {
270 putchar(*dp++);
271 goto again;
272 }
273 putchar('(');
274 if (*dp)
275 dp++;
276 while (*dp)
277 putchar (*dp++);
278 putchar(')');
279 putchar(' ');
280 }
281
282 void
283 split(line, name)
284 char *line, *name;
285 {
286 register char *cp, *dp;
287 char *sp, *sep;
288
289 cp = strchr(line, '-');
290 if (cp == 0)
291 return;
292 sp = cp + 1;
293 for (--cp; *cp == ' ' || *cp == '\t' || *cp == '\\'; cp--)
294 ;
295 *++cp = '\0';
296 while (*sp && (*sp == ' ' || *sp == '\t'))
297 sp++;
298 for (sep = "", dp = line; dp && *dp; dp = cp, sep = "\n") {
299 cp = strchr(dp, ',');
300 if (cp) {
301 register char *tp;
302
303 for (tp = cp - 1; *tp == ' ' || *tp == '\t'; tp--)
304 ;
305 *++tp = '\0';
306 for (++cp; *cp == ' ' || *cp == '\t'; cp++)
307 ;
308 }
309 printf("%s%s\t", sep, dp);
310 dorefname(name);
311 printf("\t%s", sp);
312 }
313 }
314
315 void
316 dorefname(name)
317 char *name;
318 {
319 register char *dp = name, *ep;
320
321 again:
322 while (*dp && *dp != '.')
323 putchar(*dp++);
324 if (*dp)
325 for (ep = dp+1; *ep; ep++)
326 if (*ep == '.') {
327 putchar(*dp++);
328 goto again;
329 }
330 putchar('.');
331 if (*dp)
332 dp++;
333 while (*dp)
334 putchar (*dp++);
335 }
336
337 void
338 usage()
339 {
340 (void)fprintf(stderr, "usage: getNAME [-it] file ...\n");
341 exit(1);
342 }
343