Commit | Line | Data |
---|---|---|
5f5976fd | 1 | #ifndef lint |
44f2aab3 | 2 | static char *sccsid="@(#)showtc.c 1.9 (Berkeley) %G%"; |
977b5828 KL |
3 | #endif |
4 | ||
551db654 KL |
5 | /* |
6 | ** show termcap entries | |
7 | ** | |
8 | ** where: | |
ba9c0f2e | 9 | ** -D look for duplicate names and print termcap file |
551db654 | 10 | ** -S sort entries before display |
ba9c0f2e | 11 | ** -T trace (-DDEBUG only) |
322eb279 | 12 | ** -U print unknown capabilities |
551db654 | 13 | ** -b show bare entries |
ba9c0f2e | 14 | ** -d -D and stop |
551db654 | 15 | ** -f following arg is FULL PATHNAME of termcap file |
977b5828 | 16 | ** -g sort on generic names |
977b5828 KL |
17 | ** -s don't print two char name at the front of every line |
18 | ** -x expand tc= capabilities | |
551db654 KL |
19 | ** [ent] display specific entry. tc= will be expanded. |
20 | ** | |
21 | ** David L. Wasley, U.C.Berkeley | |
0b733427 KL |
22 | ** Kevin Layer: modified for 4.1c and misc changes. |
23 | ** Kevin Layer: added the printing of terminal capabilities | |
24 | ** in `human' readable form (like that in "man 5 termcap"). | |
551db654 KL |
25 | */ |
26 | ||
551db654 KL |
27 | #include <stdio.h> |
28 | #include <sys/file.h> | |
29 | #include <ctype.h> | |
302dad01 | 30 | #include <sys/param.h> |
551db654 KL |
31 | #include <sys/stat.h> |
32 | ||
33 | #define NO 0 | |
34 | #define YES 1 | |
35 | #define CNULL '\0' | |
36 | #define NOENTRIES 1024 | |
977b5828 | 37 | #define USAGE "usage: %s [-Sxdngb] [-f termcapfile] [entry] ...\n" |
551db654 | 38 | |
302dad01 S |
39 | #ifndef MAXPATHLEN |
40 | #define MAXPATHLEN 1024 | |
41 | #endif | |
42 | ||
551db654 KL |
43 | struct TcName { |
44 | char name_buf[124]; | |
45 | long file_pos; | |
46 | } tcNames[NOENTRIES]; | |
47 | ||
0b733427 KL |
48 | struct Caps { |
49 | char *cap; | |
50 | char *desc; | |
5f5976fd | 51 | } capList[] = |
0b733427 | 52 | { |
5f5976fd S |
53 | "AL", "Add N new blank lines", |
54 | "CC", "Command char in prototype if settable", | |
55 | "DC", "Delete N characters", | |
56 | "DL", "Delete N lines", | |
57 | "DO", "Move cursor down N lines", | |
58 | "IC", "Insert N blank characters", | |
59 | "LE", "Move cursor left N positions", | |
60 | "RI", "Move cursor right N positions", | |
61 | "UP", "Move cursor up N lines", | |
0b733427 KL |
62 | "ae", "End alternate character set", |
63 | "al", "Add new blank line", | |
64 | "am", "Has automatic margins", | |
65 | "as", "Start alternate character set", | |
66 | "bc", "Backspace if not ^H", | |
5f5976fd | 67 | "bl", "Audible Bell (default ^G)", |
0b733427 KL |
68 | "bs", "Can backspace with ^H", |
69 | "bt", "Back tab", | |
70 | "bw", "Backspace wraps from col 0 to last col", | |
0b733427 KL |
71 | "cd", "Clear to end of display", |
72 | "ce", "Clear to end of line", | |
73 | "ch", "Like cm, but horizontal motion only", | |
74 | "cl", "Clear screen", | |
75 | "cm", "Cursor motion", | |
76 | "co", "Number of columns in a line", | |
5f5976fd | 77 | "cr", "Carriage return (default ^M)", |
0b733427 | 78 | "cs", "Change scrolling region (vt100), like cm", |
5f5976fd | 79 | "ct", "Clear all tab stops", |
0b733427 | 80 | "cv", "Like ch but vertical only.", |
0b733427 | 81 | "dB", "Number of millisec of bs delay needed", |
0b733427 | 82 | "dC", "Number of millisec of cr delay needed", |
0b733427 | 83 | "dF", "Number of millisec of ff delay needed", |
5f5976fd S |
84 | "dN", "Number of millisec of nl delay needed", |
85 | "dT", "Number of millisec of tab delay needed", | |
86 | "da", "Display may be retained above", | |
87 | "db", "Display may be retained below", | |
88 | "dc", "Delete character", | |
0b733427 KL |
89 | "dl", "Delete line", |
90 | "dm", "Start Delete mode", | |
0b733427 | 91 | "do", "Down one line", |
180b3e99 | 92 | "ds", "Disable status display", |
0b733427 KL |
93 | "ed", "End delete mode", |
94 | "ei", "End insert mode;give \":ei=:\" if ic", | |
95 | "eo", "Can erase overstrikes with a blank", | |
180b3e99 | 96 | "es", "Escape seq's ok on status line", |
0b733427 KL |
97 | "ff", "Hardcopy page eject (default ^L)", |
98 | "fs", "From status line sequence", | |
99 | "hc", "Hardcopy terminal", | |
100 | "hd", "Half-line down (forward 1/2 lf)", | |
101 | "ho", "Home cursor (if no cm)", | |
5f5976fd | 102 | "hs", "Has status line", |
0b733427 KL |
103 | "hu", "Half-line up (reverse 1/2 lf)", |
104 | "hz", "Hazeltine; can't print ~'s", | |
5f5976fd | 105 | "i2", "Initialization string (used by sysline(1))", |
0b733427 KL |
106 | "ic", "Insert character", |
107 | "if", "Name of file containing is", | |
108 | "im", "Start insert mode;give \":im=:\" if ic", | |
109 | "in", "Insert mode distinguishes nulls on display", | |
110 | "ip", "Insert pad after character inserted", | |
111 | "is", "Initialization string", | |
5f5976fd S |
112 | "k0", "Sent by function key 0", |
113 | "k1", "Sent by function key 1", | |
114 | "k2", "Sent by function key 2", | |
115 | "k3", "Sent by function key 3", | |
116 | "k4", "Sent by function key 4", | |
117 | "k5", "Sent by function key 5", | |
118 | "k6", "Sent by function key 6", | |
119 | "k7", "Sent by function key 7", | |
120 | "k8", "Sent by function key 8", | |
121 | "k9", "Sent by function key 9", | |
0b733427 | 122 | "kb", "Sent by backspace key", |
5f5976fd | 123 | "kd", "Sent by down arrow key", |
0b733427 KL |
124 | "ke", "Out of \"keypad transmit\" mode", |
125 | "kh", "Sent by home key", | |
126 | "kl", "Sent by left arrow key", | |
5f5976fd | 127 | "km", "Has a \"meta\" key (shift, sets parity bit)", |
0b733427 KL |
128 | "kn", "Number of \"other\" keys", |
129 | "ko", "Tc entries for other non-function keys", | |
130 | "kr", "Sent by right arrow key", | |
131 | "ks", "Put in \"keypad transmit\" mode", | |
132 | "ku", "Sent by up arrow key", | |
5f5976fd S |
133 | "l0", "Label on function key 0 (if not \"0\")", |
134 | "l1", "Label on function key 1 (if not \"1\")", | |
135 | "l2", "Label on function key 2 (if not \"2\")", | |
136 | "l3", "Label on function key 3 (if not \"3\")", | |
137 | "l4", "Label on function key 4 (if not \"4\")", | |
138 | "l5", "Label on function key 5 (if not \"5\")", | |
139 | "l6", "Label on function key 6 (if not \"6\")", | |
140 | "l7", "Label on function key 7 (if not \"7\")", | |
141 | "l8", "Label on function key 8 (if not \"8\")", | |
142 | "l9", "Label on function key 9 (if not \"9\")", | |
322eb279 | 143 | "le", "Move left", |
0b733427 KL |
144 | "li", "Number of lines on screen or page", |
145 | "ll", "Last line, first column (if no cm)", | |
146 | "ma", "Arrow key map, used by vi V2 only", | |
322eb279 KL |
147 | "mb", "Enter blinking mode", |
148 | "md", "Enter bold mode", | |
149 | "me", "Reset video attributes", | |
150 | "mh", "Enter halfbright mode", | |
0b733427 | 151 | "mi", "Safe to move while in insert mode", |
322eb279 | 152 | "mk", "Enter protected mode", |
0b733427 | 153 | "ml", "Memory lock on above cursor.", |
5f5976fd | 154 | "mp", "Turn on protected attribute", |
322eb279 | 155 | "mr", "Enter reverse video mode", |
0b733427 KL |
156 | "ms", "Ok to move while in standout/underline mode", |
157 | "mu", "Memory unlock (turn off memory lock).", | |
158 | "nc", "No working CR (DM2500,H2000)", | |
159 | "nd", "Non-destructive space (cursor right)", | |
160 | "nl", "Newline character (default \\n)", | |
161 | "ns", "Is a CRT but doesn't scroll.", | |
162 | "os", "Terminal overstrikes", | |
5f5976fd | 163 | "pb", "Lowest baud where delays are required", |
0b733427 | 164 | "pc", "Pad character (rather than null)", |
5f5976fd | 165 | "pl", "Program function key N to execute string S (terminfo only)", |
0b733427 | 166 | "pt", "Has hardware tabs (may need to use is)", |
5f5976fd S |
167 | "rc", "Restore cursor to position of last sc", |
168 | "rf", "Name of file containing reset codes", | |
169 | "rs", "Reset terminal completely to sane modes", | |
170 | "sc", "Save cursor position", | |
0b733427 KL |
171 | "se", "End stand out mode", |
172 | "sf", "Scroll forwards", | |
173 | "sg", "Number of blank chars left by so/se", | |
174 | "so", "Begin stand out mode", | |
175 | "sr", "Scroll reverse (backwards)", | |
5f5976fd | 176 | "st", "Set a tab in all rows, current column", |
0b733427 KL |
177 | "ta", "Tab (other than ^I or with padding)", |
178 | "tc", "Entry of similar terminal - must be last", | |
179 | "te", "String to end programs that use cm", | |
180 | "ti", "String to begin programs that use cm", | |
181 | "ts", "To status line sequence", | |
182 | "uc", "Underscore one char and move past it", | |
183 | "ue", "End underscore mode", | |
184 | "ug", "Number of blank chars left by us or ue", | |
185 | "ul", "Underlines, though no overstrike", | |
186 | "up", "Upline (cursor up)", | |
187 | "us", "Start underscore mode", | |
188 | "vb", "Visible bell (may not move cursor)", | |
189 | "ve", "Sequence to end open/visual mode", | |
190 | "vs", "Sequence to start open/visual mode", | |
5f5976fd | 191 | "vt", "Virtual terminal number (not supported on all systems)", |
0b733427 KL |
192 | "xb", "Beehive (f1=escape, f2=ctrl C)", |
193 | "xn", "A newline is ignored after a wrap (Concept)", | |
194 | "xr", "Return acts like ce \\r \\n (Delta Data)", | |
195 | "xs", "Standout not erased by writing over it (HP 264?)", | |
196 | "xt", "Destructive tabs, magic so char (Teleray 1061)" | |
197 | }; | |
198 | ||
5f5976fd S |
199 | #define NOCAPS (sizeof capList / sizeof *capList) |
200 | ||
551db654 KL |
201 | #ifdef DEBUG |
202 | int Dflag = NO; | |
203 | #endif | |
204 | int xflag = NO; | |
977b5828 KL |
205 | int Sflag = YES; |
206 | int sflag = NO; | |
551db654 KL |
207 | int dflag = NO; |
208 | int nflag = NO; | |
209 | int gflag = NO; | |
210 | int bflag = NO; | |
322eb279 | 211 | int Uflag = NO; |
551db654 KL |
212 | int tc_loopc; /* loop counter */ |
213 | char *tcfile; /* termcap database pathname */ | |
302dad01 | 214 | char cwd[MAXPATHLEN]; /* current working directory */ |
2d9f9d8c | 215 | char tcbuf[2048]; /* buffer for termcap description */ |
551db654 KL |
216 | char *lastchar(); |
217 | int name_cmp(); | |
218 | int ent_cmp(); | |
219 | struct TcName *find_name(); | |
220 | char *getenv(); | |
221 | char *ctime(); | |
222 | char *strncpy(); | |
223 | long ftell(); | |
224 | ||
225 | main(argc, argv, envp) | |
226 | int argc; | |
227 | char **argv; | |
228 | char **envp; | |
229 | { | |
230 | char *av; | |
231 | struct TcName *tn; | |
232 | register char *bp; | |
233 | long pos; | |
234 | int n; | |
235 | struct stat st; | |
236 | char envbuf[256]; | |
237 | FILE *tcfp; | |
238 | ||
239 | if ((bp = getenv("TERMCAP")) && *bp == '/') | |
240 | tcfile = bp; | |
241 | else | |
242 | tcfile = "/etc/termcap"; | |
243 | ||
244 | while (--argc > 0) | |
245 | { | |
246 | if (*(av = *++argv) == '-') | |
247 | { | |
248 | while (*++av) | |
249 | { | |
250 | switch (*av) | |
251 | { | |
252 | /* use alternate termcap file */ | |
253 | case 'f': | |
254 | if (argc-- <= 0) | |
255 | { | |
256 | fprintf(stderr, | |
257 | "-f needs a filename\n"); | |
258 | exit(1); | |
259 | } | |
260 | tcfile = *++argv; | |
261 | break; | |
262 | ||
263 | /* only check for dup names */ | |
ba9c0f2e | 264 | case 'd': |
551db654 KL |
265 | nflag = YES; |
266 | /* fall thru */ | |
267 | ||
268 | /* look for duplicated names */ | |
ba9c0f2e | 269 | case 'D': |
551db654 KL |
270 | dflag = YES; |
271 | continue; | |
272 | ||
322eb279 KL |
273 | case 'U': |
274 | Uflag = YES; | |
275 | continue; | |
276 | ||
977b5828 KL |
277 | /* strip the two name off */ |
278 | case 's': | |
279 | sflag = YES; | |
280 | continue; | |
281 | ||
551db654 KL |
282 | /* sort the name array */ |
283 | case 'S': | |
977b5828 | 284 | Sflag = NO; |
551db654 KL |
285 | continue; |
286 | ||
287 | #ifdef DEBUG | |
ba9c0f2e | 288 | case 'T': |
551db654 KL |
289 | Dflag = YES; |
290 | continue; | |
291 | #endif | |
292 | ||
293 | /* sort on generic names */ | |
294 | case 'g': | |
295 | gflag = YES; | |
296 | continue; | |
297 | ||
298 | /* expand entries in 'full mode' */ | |
299 | case 'x': | |
300 | xflag = YES; | |
301 | continue; | |
302 | ||
303 | /* show bare entry */ | |
304 | case 'b': | |
305 | bflag = YES; | |
306 | continue; | |
307 | ||
308 | default: | |
309 | fprintf(stderr, "showtc: unknown flag: -%c\n", *av); | |
310 | fprintf(stderr, USAGE, argv[0]); | |
311 | exit(1); | |
312 | } | |
313 | } | |
314 | } | |
315 | else | |
316 | break; | |
317 | } | |
318 | ||
319 | /* | |
320 | * insert the specified TERMCAP file into the environment | |
321 | */ | |
302dad01 S |
322 | if (*tcfile != '/') { |
323 | char *getwd(); | |
324 | ||
325 | if (getwd(cwd) == NULL) { | |
326 | fprintf(stderr, "showtc: %s\n", cwd); | |
327 | exit(1); | |
328 | } else if (strlen(cwd) + strlen(tcfile) + 2 > sizeof cwd) { | |
329 | fprintf(stderr, "showtc: %s\n", | |
330 | "Current working directory name too long"); | |
331 | exit(1); | |
332 | } else { | |
333 | if (cwd[strlen(cwd) - 1] != '/') | |
334 | strcat(cwd, "/"); | |
335 | strcat(cwd, tcfile); | |
336 | tcfile = cwd; | |
337 | } | |
338 | } | |
551db654 KL |
339 | (void) sprintf(envbuf, "TERMCAP=%s", tcfile); |
340 | while (*envp) | |
341 | { | |
342 | if (strncmp(*envp, "TERMCAP=", 8) == 0) | |
343 | { | |
344 | *envp = envbuf; | |
345 | break; | |
346 | } | |
347 | envp++; | |
348 | } | |
349 | if (! *envp) | |
350 | *envp = envbuf; /* this may be dangerous */ | |
351 | ||
352 | /* | |
353 | ** if user specified type(s), do only those | |
354 | */ | |
355 | if (argc > 0) | |
356 | { | |
357 | /* | |
358 | ** look for the users specified term types | |
359 | */ | |
360 | while (argc > 0) | |
361 | { | |
362 | switch (n = tgetent(tcbuf, *argv)) | |
363 | { | |
364 | case 1: | |
365 | if (bflag) | |
366 | (void) prnt_raw(tcbuf); | |
367 | else | |
368 | (void) prnt_ent(tcbuf); | |
369 | break; | |
370 | ||
371 | case 0: | |
372 | fprintf(stderr, | |
373 | "showtc: bad entry: %s\n", *argv); | |
374 | break; | |
375 | ||
376 | case -1: | |
377 | fputs("showtc: ", stderr); | |
378 | perror(tcfile); | |
379 | exit(1); | |
380 | ||
381 | default: | |
382 | fprintf(stderr, "bad return from tgetent: %d\n", n); | |
383 | exit(1); | |
384 | } | |
385 | argc--; | |
386 | argv++; | |
387 | } | |
388 | exit(0); | |
389 | } | |
390 | ||
391 | if (bflag) | |
392 | { | |
393 | fprintf(stderr, "showtc: -b flag with no entries makes no sense.\n"); | |
394 | exit(1); | |
395 | } | |
396 | ||
397 | ||
398 | /* | |
399 | ** if no type was specified, do the whole file | |
400 | */ | |
401 | if ((tcfp = fopen(tcfile, "r")) == NULL) | |
402 | { | |
403 | perror(tcfile); | |
404 | exit(1); | |
405 | } | |
406 | ||
407 | /* | |
408 | ** identify database, for the record | |
409 | */ | |
410 | if (stat(tcfile, &st)) | |
411 | { | |
412 | perror(tcfile); | |
413 | exit(1); | |
414 | } | |
415 | printf("File: %s, last modified: %s\n", tcfile, ctime(&st.st_mtime)); | |
416 | ||
417 | ||
418 | /* | |
419 | ** build termcap entry table | |
420 | */ | |
421 | tn = tcNames; | |
422 | pos = ftell(tcfp); | |
423 | bp = tcbuf; | |
424 | while (fgets(bp, sizeof (tcbuf), tcfp) != NULL) | |
425 | { | |
426 | if (tcbuf[0] == '#') | |
427 | { | |
428 | pos = ftell(tcfp); | |
429 | bp = tcbuf; | |
430 | continue; | |
431 | } | |
432 | ||
433 | tn->file_pos = pos; | |
434 | ||
435 | /* | |
436 | ** get full entry | |
437 | */ | |
438 | while (*(bp = lastchar(bp)) == '\\' && fgets(bp, (sizeof tcbuf) - (bp - tcbuf), tcfp)) | |
439 | ; | |
440 | /* | |
441 | ** save the names | |
442 | */ | |
443 | for (bp = tcbuf; *bp && *bp != ':'; bp++) | |
444 | ; | |
445 | *bp = '\0'; | |
446 | (void) strncpy(tn->name_buf, tcbuf, | |
447 | sizeof tcNames[0].name_buf); | |
448 | ||
449 | pos = ftell(tcfp); | |
450 | bp = tcbuf; | |
451 | tn++; | |
452 | } | |
453 | tn->file_pos = -1; | |
454 | ||
455 | /* | |
456 | ** Look for duplicate names | |
457 | */ | |
458 | if (dflag) | |
459 | check_dup(); | |
460 | if (nflag) | |
461 | exit(0); | |
462 | ||
463 | #ifdef DEBUG | |
464 | if (Dflag) | |
465 | { | |
466 | for (tn = tcNames; tn->file_pos >= 0; tn++) | |
467 | { | |
468 | printf("Entry #%d:\n\t%s\n\tfile_pos = %ld\n", | |
469 | tn - tcNames, tn->name_buf, tn->file_pos); | |
470 | } | |
471 | exit(0); | |
472 | } | |
473 | #endif | |
474 | ||
475 | /* | |
476 | ** Order the list | |
477 | */ | |
977b5828 | 478 | if (Sflag) |
551db654 KL |
479 | qsort((char *)tcNames, tn - tcNames, |
480 | sizeof (struct TcName), name_cmp); | |
481 | ||
482 | /* | |
483 | ** List termcap entry for each name in table | |
484 | */ | |
485 | for (tn = tcNames; tn->file_pos >= 0; tn++) | |
486 | { | |
487 | tc_loopc = 0; | |
488 | /*** working toward this ... | |
489 | (void) prnt_ent(tn); | |
490 | ***/ | |
491 | (void) fseek(tcfp, tn->file_pos, 0); | |
492 | bp = tcbuf; | |
493 | while (fgets(bp, (sizeof tcbuf) - (bp - tcbuf), tcfp) | |
494 | && *(bp = lastchar(bp)) == '\\') | |
495 | ; | |
496 | (void) prnt_ent(tcbuf); | |
497 | } | |
498 | } | |
499 | ||
500 | char * | |
501 | lastchar(b) | |
502 | char *b; | |
503 | { | |
504 | register char *p; | |
505 | ||
506 | p = b + strlen(b) - 1; | |
507 | while (*p == '\n' || *p == ' ') | |
508 | p--; | |
509 | return(p); | |
510 | } | |
511 | ||
512 | name_cmp(a, b) | |
513 | char *a, *b; | |
514 | { | |
515 | if (gflag) /* sort on generic names */ | |
516 | { | |
517 | a += 3; | |
518 | b += 3; | |
519 | while (*a && *b && *a != '|' && *a == *b) | |
520 | { | |
521 | a++; | |
522 | b++; | |
523 | } | |
524 | if (*a == '|' || *a == CNULL) | |
525 | return((*b == '|' || *b == CNULL)? 0:-1); | |
526 | if (*b == '|' || *b == CNULL) | |
527 | return(1); | |
528 | return(*a - *b); | |
529 | } | |
530 | return(strncmp(a, b, 2)); | |
531 | } | |
532 | ||
533 | prnt_ent(buf) | |
534 | register char *buf; | |
535 | { | |
536 | register char *name; | |
0b733427 | 537 | char *getdesc(); |
551db654 KL |
538 | char *caps[256]; |
539 | register char **cp; | |
540 | register char **tp; | |
541 | char tname[3]; | |
542 | ||
543 | cp = caps; | |
544 | name = buf; | |
545 | tname[3] = '\0'; | |
546 | ||
547 | while (*buf) | |
548 | { | |
549 | switch (*buf) | |
550 | { | |
551 | case ':': | |
552 | *buf++ = '\0'; | |
553 | while (*buf && !isalnum(*buf)) | |
554 | buf++; | |
555 | if (*buf) | |
556 | { | |
557 | /* | |
558 | * ignore duplicate cap entries | |
559 | */ | |
560 | for (tp = caps; tp < cp; tp++) | |
561 | if (strncmp(buf, *tp, 2) == 0) | |
562 | goto skip; | |
563 | *cp++ = buf; | |
564 | skip: | |
565 | /* | |
566 | * does user want tc= expanded? | |
567 | */ | |
568 | if (xflag && strncmp(buf, "tc=", 3) == 0) | |
569 | { | |
570 | /* | |
571 | * find end of tc= | |
572 | */ | |
573 | while (*buf != ':') | |
574 | buf++; | |
575 | *buf = '\0'; | |
576 | /* | |
577 | * save term name | |
578 | */ | |
579 | tname[0] = name[0]; | |
580 | tname[1] = name[1]; | |
581 | printf("%s: expanding %s\n", | |
582 | tname, cp[-1]); | |
583 | /* | |
584 | * let tgetent do the work | |
585 | */ | |
586 | tgetent(tcbuf, tname); | |
587 | prnt_ent(tcbuf); | |
588 | return; | |
589 | } | |
590 | } | |
591 | continue; | |
592 | ||
593 | case '|': | |
594 | *buf++ = ','; | |
595 | continue; | |
596 | ||
597 | default: | |
598 | buf++; | |
599 | } | |
600 | } | |
601 | *cp = CNULL; /* was (char *)0 */ | |
602 | ||
977b5828 | 603 | if (Sflag) |
551db654 KL |
604 | qsort((char *) caps, cp - caps, sizeof (char *), ent_cmp); |
605 | ||
606 | printf("%s\n", name); | |
607 | for (cp = caps; *cp; cp++) | |
322eb279 KL |
608 | if (Uflag) { |
609 | if (unknowncap(*cp)) { | |
610 | printf("%3.3s\n", *cp); | |
611 | } | |
612 | } else if (sflag) { | |
0b733427 | 613 | printf("%-45s %s\n", getdesc(*cp), *cp); |
322eb279 | 614 | } else { |
0b733427 KL |
615 | printf("%2.2s %-45s %s\n", name, getdesc(*cp), *cp); |
616 | } | |
551db654 KL |
617 | (void) putchar('\n'); |
618 | } | |
619 | ||
620 | prnt_raw(buf) | |
621 | char *buf; | |
622 | { | |
623 | register char *b; | |
624 | register int len; | |
625 | register int n; | |
626 | char *index(); | |
627 | ||
628 | len = 0; | |
629 | b = buf; | |
630 | while (*b) | |
631 | { | |
632 | if ((n = index(b, ':') - b + 1) <= 0) | |
633 | n = strlen(b); | |
634 | if (len == 0) /* first part */ | |
635 | { | |
636 | printf("%.*s\\\n\t:", n, b); | |
637 | len = 9 - n; | |
638 | } | |
639 | else | |
640 | { | |
641 | if ((len + n) >= 75) | |
642 | { | |
643 | printf("\\\n\t:"); | |
644 | len = 9; | |
645 | } | |
646 | printf("%.*s", n, b); | |
647 | } | |
648 | len += n; | |
649 | b += n; | |
650 | while (*b && index(" \t:\n", *b)) | |
651 | b++; | |
652 | } | |
653 | if (b[-1] != ':') | |
654 | (void) putchar(':'); | |
655 | (void) putchar('\n'); | |
656 | } | |
657 | ||
658 | ent_cmp(a, b) | |
659 | char **a, **b; | |
660 | { | |
661 | return(strncmp(*a, *b, 2)); | |
662 | } | |
663 | ||
664 | check_dup() | |
665 | { | |
666 | /* | |
667 | ** Look for duplicated names | |
668 | */ | |
669 | register char *p; | |
670 | register char *q; | |
671 | register struct TcName *tn; | |
672 | register struct TcName *tm; | |
673 | ||
674 | tn = tcNames; | |
675 | while (tn->file_pos >= 0) | |
676 | { | |
677 | p = q = tn->name_buf; | |
678 | while (*q) | |
679 | { | |
680 | while (*p && *p != '|') | |
681 | p++; | |
682 | if (p != q && (tm = find_name(q, tn + 1, p - q))) | |
683 | { | |
684 | fputs("Duplicate name: ", stdout); | |
685 | while (q != p) | |
686 | (void) putchar(*q++); | |
687 | (void) putchar('\n'); | |
688 | puts(tn->name_buf); | |
689 | puts(tm->name_buf); | |
690 | puts("---\n"); | |
691 | } | |
692 | if (*p == '|') | |
693 | p++; | |
694 | q = p; | |
695 | } | |
696 | tn++; | |
697 | } | |
698 | } | |
699 | ||
700 | struct TcName * | |
701 | find_name(name, tn, len) | |
702 | register char *name; | |
703 | register struct TcName *tn; | |
704 | register int len; | |
705 | { | |
706 | /* | |
707 | ** find name of length len in tcname structure buffers. | |
708 | */ | |
709 | register char *p; | |
710 | register char *buf; | |
711 | register int n; | |
712 | ||
713 | while (tn->file_pos >= 0) | |
714 | { | |
715 | buf = tn->name_buf; | |
716 | while (*buf) | |
717 | { | |
718 | p = name; | |
719 | n = len; | |
720 | if (*buf == '|') | |
721 | buf++; | |
722 | ||
723 | while (*buf && *buf != '|') | |
724 | { | |
725 | if (*p != *buf) | |
726 | { | |
727 | while (*buf && *buf != '|') | |
728 | buf++; | |
729 | break; | |
730 | } | |
731 | ||
732 | if (--n <= 0) | |
733 | { | |
734 | buf++; | |
735 | if (*buf == '|' || *buf == '\0') | |
736 | return(tn); | |
737 | while (*buf && *buf != '|') | |
738 | buf++; | |
739 | break; | |
740 | } | |
741 | buf++; | |
742 | p++; | |
743 | } | |
744 | } | |
745 | tn++; | |
746 | } | |
747 | return((struct TcName *)0); | |
748 | } | |
0b733427 KL |
749 | |
750 | char * | |
751 | getdesc(key) | |
752 | char *key; | |
753 | { | |
754 | register int i; | |
755 | ||
302dad01 | 756 | for (i = 0; i < NOCAPS; i++) |
0b733427 KL |
757 | if (strncmp(key, capList[i].cap, 2) == 0) |
758 | return (capList[i].desc); | |
ba9c0f2e | 759 | return(""); |
0b733427 | 760 | } |
322eb279 KL |
761 | |
762 | unknowncap(key) | |
763 | char *key; | |
764 | { | |
765 | register int i; | |
766 | ||
302dad01 | 767 | for (i = 0; i < NOCAPS; i++) |
322eb279 KL |
768 | if (strncmp(key, capList[i].cap, 2) == 0) |
769 | return (0); | |
770 | return(1); | |
771 | } |