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