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