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