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