1 /* $NetBSD: getNAME.c,v 1.25 2006/09/12 21:56:43 hubertf Exp $ */
4 * Copyright (c) 1997, Christos Zoulas. All rights reserved.
5 * Copyright (c) 1980, 1993
6 * The Regents of the University of California. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
35 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\
36 The Regents of the University of California. All rights reserved.");
38 static char sccsid
[] = "@(#)getNAME.c 8.1 (Berkeley) 6/30/93";
40 __RCSID("$NetBSD: getNAME.c,v 1.25 2006/09/12 21:56:43 hubertf Exp $");
45 * Get name sections from manual pages.
47 * -i for building intro entries
48 * -w for querying type of manual source
50 * other apropos database
64 #define SLOP 10 /* strlen(" () - ") < 10 */
66 static char *linebuf
= NULL
;
67 static size_t maxlen
= 0;
70 static void doname(char *);
71 static void dorefname(char *);
72 static void getfrom(char *);
73 static void oldman(char *, char *);
74 static void newman(char *, char *);
75 static void remcomma(char *, size_t *);
76 static void remquote(char *, size_t *);
77 static void fixxref(char *, size_t *);
78 static void split(char *, char *);
79 static void usage(void);
81 int main(int, char *[]);
83 /* The .SH NAMEs that are allowed. */
84 static const char *names
[] = { "name", "namn", 0 };
87 main(int argc
, char *argv
[])
91 while ((ch
= getopt(argc
, argv
, "itvw")) != -1)
115 for (; *argv
; ++argv
)
121 getfrom(char *pathname
)
127 if (freopen(pathname
, "r", stdin
) == 0) {
128 warn("Cannot open `%s'", pathname
);
131 if ((name
= strrchr(pathname
, '/')) != NULL
)
136 if ((line
= fgetln(stdin
, &len
)) == NULL
) {
138 (void)printf("%-60s\tUNKNOWN\n", pathname
);
140 warnx("missing .TH or .Dt section in `%s'",
148 if ((line
[1] == 'T' && line
[2] == 'H') ||
149 (line
[1] == 't' && line
[2] == 'h')) {
150 oldman(pathname
, name
);
153 if (line
[1] == 'D' && line
[2] == 't') {
154 newman(pathname
, name
);
161 oldman(char *pathname
, char *name
)
163 char *line
, *ext
, *s
, *newlinebuf
;
164 size_t len
, i
, extlen
;
170 (void)printf("%-60s\tOLD\n", pathname
);
174 if ((line
= fgetln(stdin
, &len
)) == NULL
) {
176 warnx("missing .SH section in `%s'", pathname
);
183 if (line
[1] == 'S' && line
[2] == 'H')
185 if (line
[1] == 's' && line
[2] == 'h')
189 for (s
= &line
[3]; s
< &line
[len
] &&
190 (isspace((unsigned char) *s
) || *s
== '"' || *s
== '\''); s
++)
192 if (s
== &line
[len
]) {
193 warnx("missing argument to .SH in `%s'", pathname
);
196 for (i
= 0; names
[i
]; i
++)
197 if (strncasecmp(s
, names
[i
], strlen(names
[i
])) == 0)
199 if (names
[i
] == NULL
) {
200 warnx("first .SH section is not \"NAME\" in `%s'", pathname
);
209 if ((line
= fgetln(stdin
, &len
)) == NULL
)
211 if (line
[0] == '.') {
212 if (line
[1] == '\\' && line
[2] == '"')
213 continue; /* [nt]roff comment */
214 if (line
[1] == 'S' && line
[2] == 'H')
216 if (line
[1] == 's' && line
[2] == 'h')
218 if (line
[1] == 'P' && line
[2] == 'P')
220 if (line
[1] == 'b' && line
[2] == 'r') {
222 split(linebuf
, name
);
224 (void)printf("%s\n", linebuf
);
229 if (line
[len
- 1] == '\n') {
230 line
[len
- 1] = '\0';
233 if ((ext
= strrchr(name
, '.')) != NULL
) {
235 extlen
= strlen(ext
);
240 if (maxlen
+ extlen
< curlen
+ len
+ SLOP
) {
241 newmaxlen
= 2 * (curlen
+ len
) + SLOP
+ extlen
;
242 if ((newlinebuf
= realloc(linebuf
, newmaxlen
)) == NULL
)
244 linebuf
= newlinebuf
;
248 linebuf
[curlen
++] = ' ';
249 (void)memcpy(&linebuf
[curlen
], line
, len
);
252 linebuf
[curlen
] = '\0';
254 if(!tocrc
&& !intro
) {
255 /* change the \- into (N) - */
256 if ((s
= strstr(linebuf
, "\\-")) != NULL
) {
257 (void)memmove(s
+ extlen
+ 3, s
+ 1,
258 curlen
- (s
+ 1 - linebuf
));
266 curlen
+= extlen
+ 3;
268 linebuf
[curlen
] = '\0';
274 split(linebuf
, name
);
276 (void)printf("%s\n", linebuf
);
281 newman(char *pathname
, char *name
)
283 char *line
, *ext
, *s
, *newlinebuf
;
284 size_t len
, i
, extlen
;
289 (void)printf("%-60s\tNEW\n", pathname
);
293 if ((line
= fgetln(stdin
, &len
)) == NULL
) {
295 warnx("missing .Sh section in `%s'", pathname
);
300 if (line
[1] == 'S' && line
[2] == 'h')
304 for (s
= &line
[3]; s
< &line
[len
] && isspace((unsigned char) *s
); s
++)
306 if (s
== &line
[len
]) {
307 warnx("missing argument to .Sh in `%s'", pathname
);
310 for (i
= 0; names
[i
]; i
++)
311 if (strncasecmp(s
, names
[i
], strlen(names
[i
])) == 0)
313 if (names
[i
] == NULL
) {
314 warnx("first .SH section is not \"NAME\" in `%s'", pathname
);
322 if ((line
= fgetln(stdin
, &len
)) == NULL
)
325 if (line
[0] == '.') {
326 if (line
[1] == '\\' && line
[2] == '"')
327 continue; /* [nt]roff comment */
328 if (line
[1] == 'S' && line
[2] == 'h')
332 if (line
[len
- 1] == '\n') {
333 line
[len
- 1] = '\0';
337 if ((ext
= strrchr(name
, '.')) != NULL
) {
339 extlen
= strlen(ext
);
344 if (maxlen
+ extlen
< curlen
+ len
+ SLOP
) {
345 newmaxlen
= 2 * (curlen
+ len
) + SLOP
+ extlen
;
346 if ((newlinebuf
= realloc(linebuf
, newmaxlen
)) == NULL
)
348 linebuf
= newlinebuf
;
353 linebuf
[curlen
++] = ' ';
355 remcomma(line
, &len
);
357 if (line
[0] != '.') {
358 (void)memcpy(&linebuf
[curlen
], line
, len
);
362 remquote(line
, &len
);
366 * Put section and dash between names and description.
368 if (line
[1] == 'N' && line
[2] == 'd') {
369 if(!tocrc
&& !intro
) {
371 linebuf
[curlen
++] = '(';
373 linebuf
[curlen
++] = *ext
++;
374 linebuf
[curlen
++] = ')';
375 linebuf
[curlen
++] = ' ';
378 linebuf
[curlen
++] = '-';
379 linebuf
[curlen
++] = ' ';
382 * Skip over macro names.
386 (void)memcpy(&linebuf
[curlen
], &line
[4], len
- 4);
390 linebuf
[curlen
] = '\0';
392 split(linebuf
, name
);
394 (void)printf("%s\n", linebuf
);
398 * convert " ," -> " "
401 remcomma(char *line
, size_t *len
)
403 char *pline
= line
, *loc
;
406 while ((loc
= memchr(pline
, ' ', plen
)) != NULL
) {
407 plen
-= loc
- pline
+ 1;
410 (void)memcpy(loc
, &loc
[1], plen
);
419 * Get rid of quotes in macros.
422 remquote(char *line
, size_t *len
)
425 char *pline
= &line
[4];
426 size_t plen
= *len
- 4;
431 while ((loc
= memchr(pline
, '"', plen
)) != NULL
) {
432 plen
-= loc
- pline
+ 1;
434 (void)memcpy(loc
, &loc
[1], plen
);
440 * Handle cross references
443 fixxref(char *line
, size_t *len
)
446 char *pline
= &line
[4];
447 size_t plen
= *len
- 4;
452 if (line
[1] == 'X' && line
[2] == 'r') {
453 if ((loc
= memchr(pline
, ' ', plen
)) != NULL
) {
465 char *dp
= name
, *ep
;
468 while (*dp
&& *dp
!= '.')
469 (void)putchar(*dp
++);
471 for (ep
= dp
+1; *ep
; ep
++)
473 (void)putchar(*dp
++);
480 (void)putchar(*dp
++);
486 split(char *line
, char *name
)
492 cp
= strchr(line
, '-');
496 for (--cp
; *cp
== ' ' || *cp
== '\t' || *cp
== '\\'; cp
--)
499 while (*sp
&& (*sp
== ' ' || *sp
== '\t'))
501 for (sep
= "", dp
= line
; dp
&& *dp
; dp
= cp
, sep
= "\n") {
502 cp
= strchr(dp
, ',');
506 for (tp
= cp
- 1; *tp
== ' ' || *tp
== '\t'; tp
--)
509 for (++cp
; *cp
== ' ' || *cp
== '\t'; cp
++)
512 (void)printf("%s%s\t", sep
, dp
);
514 (void)printf("\t- %s", sp
);
520 dorefname(char *name
)
522 char *dp
= name
, *ep
;
525 while (*dp
&& *dp
!= '.')
526 (void)putchar(*dp
++);
528 for (ep
= dp
+1; *ep
; ep
++)
530 (void)putchar(*dp
++);
537 (void)putchar(*dp
++);
544 (void)fprintf(stderr
, "Usage: %s [-itw] file ...\n", getprogname());