|
|
1.1 ! root 1: /* Work-alike for termcap, plus extra features. ! 2: Copyright (C) 1985, 1986 Free Software Foundation, Inc. ! 3: ! 4: NO WARRANTY ! 5: ! 6: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY ! 7: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT ! 8: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, ! 9: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" ! 10: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, ! 11: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND ! 12: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY ! 13: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE ! 14: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR ! 15: CORRECTION. ! 16: ! 17: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. ! 18: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY ! 19: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE ! 20: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR ! 21: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE ! 22: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR ! 23: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR ! 24: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS ! 25: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH ! 26: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. ! 27: ! 28: GENERAL PUBLIC LICENSE TO COPY ! 29: ! 30: 1. You may copy and distribute verbatim copies of this source file ! 31: as you receive it, in any medium, provided that you conspicuously and ! 32: appropriately publish on each copy a valid copyright notice "Copyright ! 33: (C) 1986 Free Software Foundation, Inc."; and include following the ! 34: copyright notice a verbatim copy of the above disclaimer of warranty ! 35: and of this License. You may charge a distribution fee for the ! 36: physical act of transferring a copy. ! 37: ! 38: 2. You may modify your copy or copies of this source file or ! 39: any portion of it, and copy and distribute such modifications under ! 40: the terms of Paragraph 1 above, provided that you also do the following: ! 41: ! 42: a) cause the modified files to carry prominent notices stating ! 43: that you changed the files and the date of any change; and ! 44: ! 45: b) cause the whole of any work that you distribute or publish, ! 46: that in whole or in part contains or is a derivative of this ! 47: program or any part thereof, to be licensed at no charge to all ! 48: third parties on terms identical to those contained in this ! 49: License Agreement (except that you may choose to grant more extensive ! 50: warranty protection to some or all third parties, at your option). ! 51: ! 52: c) You may charge a distribution fee for the physical act of ! 53: transferring a copy, and you may at your option offer warranty ! 54: protection in exchange for a fee. ! 55: ! 56: Mere aggregation of another unrelated program with this program (or its ! 57: derivative) on a volume of a storage or distribution medium does not bring ! 58: the other program under the scope of these terms. ! 59: ! 60: 3. You may copy and distribute this program (or a portion or derivative ! 61: of it, under Paragraph 2) in object code or executable form under the terms ! 62: of Paragraphs 1 and 2 above provided that you also do one of the following: ! 63: ! 64: a) accompany it with the complete corresponding machine-readable ! 65: source code, which must be distributed under the terms of ! 66: Paragraphs 1 and 2 above; or, ! 67: ! 68: b) accompany it with a written offer, valid for at least three ! 69: years, to give any third party free (except for a nominal ! 70: shipping charge) a complete machine-readable copy of the ! 71: corresponding source code, to be distributed under the terms of ! 72: Paragraphs 1 and 2 above; or, ! 73: ! 74: c) accompany it with the information you received as to where the ! 75: corresponding source code may be obtained. (This alternative is ! 76: allowed only for noncommercial distribution and only if you ! 77: received the program in object code or executable form alone.) ! 78: ! 79: For an executable file, complete source code means all the source code for ! 80: all modules it contains; but, as a special exception, it need not include ! 81: source code for modules which are standard libraries that accompany the ! 82: operating system on which the executable file runs. ! 83: ! 84: 4. You may not copy, sublicense, distribute or transfer this program ! 85: except as expressly provided under this License Agreement. Any attempt ! 86: otherwise to copy, sublicense, distribute or transfer this program is void and ! 87: your rights to use the program under this License agreement shall be ! 88: automatically terminated. However, parties who have received computer ! 89: software programs from you with this License Agreement will not have ! 90: their licenses terminated so long as such parties remain in full compliance. ! 91: ! 92: 5. If you wish to incorporate parts of this program into other free ! 93: programs whose distribution conditions are different, write to the Free ! 94: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet ! 95: worked out a simple rule that can be stated here, but we will often permit ! 96: this. We will be guided by the two goals of preserving the free status of ! 97: all derivatives of our free software and of promoting the sharing and reuse of ! 98: software. ! 99: ! 100: ! 101: In other words, you are welcome to use, share and improve this program. ! 102: You are forbidden to forbid anyone else to use, share and improve ! 103: what you give them. Help stamp out software-hoarding! */ ! 104: ! 105: ! 106: ! 107: /* BUFSIZE is the initial size allocated for the buffer ! 108: for reading the termcap file. ! 109: It is not a limit. ! 110: Make it large normally for speed. ! 111: Make it variable when debugging, so can exercise ! 112: increasing the space dynamically. */ ! 113: ! 114: #ifdef emacs ! 115: #include "config.h" ! 116: #endif ! 117: ! 118: #ifndef BUFSIZE ! 119: #ifdef DEBUG ! 120: #define BUFSIZE bufsize ! 121: ! 122: int bufsize = 128; ! 123: #else ! 124: #define BUFSIZE 2048 ! 125: #endif ! 126: #endif ! 127: ! 128: #ifndef emacs ! 129: static ! 130: memory_out () ! 131: { ! 132: write (2, "Virtual memory exhausted\n", 25); ! 133: exit (1); ! 134: } ! 135: ! 136: static int ! 137: xmalloc (size) ! 138: int size; ! 139: { ! 140: register tem = malloc (size); ! 141: if (!tem) ! 142: memory_out (); ! 143: return tem; ! 144: } ! 145: ! 146: static int ! 147: xrealloc (ptr, size) ! 148: int ptr; ! 149: int size; ! 150: { ! 151: register tem = realloc (ptr, size); ! 152: if (!tem) ! 153: memory_out (); ! 154: return tem; ! 155: } ! 156: #endif /* not emacs */ ! 157: ! 158: /* Looking up capabilities in the entry already found */ ! 159: ! 160: /* The pointer to the data made by tgetent is left here ! 161: for tgetnum, tgetflag and tgetstr to find. */ ! 162: ! 163: static char *term_entry; ! 164: ! 165: static char *tgetst1 (); ! 166: ! 167: /* This is the main subroutine that is used to search ! 168: an entry for a particular capability */ ! 169: ! 170: static char * ! 171: find_capability (bp, cap) ! 172: register char *bp, *cap; ! 173: { ! 174: for (; *bp; bp++) ! 175: if (bp[0] == ':' ! 176: && bp[1] == cap[0] ! 177: && bp[2] == cap[1]) ! 178: return &bp[4]; ! 179: return 0; ! 180: } ! 181: ! 182: int ! 183: tgetnum (cap) ! 184: char *cap; ! 185: { ! 186: register char *ptr = find_capability (term_entry, cap); ! 187: if (!ptr || ptr[-1] != '#') ! 188: return -1; ! 189: return atoi (ptr); ! 190: } ! 191: ! 192: int ! 193: tgetflag (cap) ! 194: char *cap; ! 195: { ! 196: register char *ptr = find_capability (term_entry, cap); ! 197: return 0 != ptr && ptr[-1] == ':'; ! 198: } ! 199: ! 200: /* Look up a string-valued capability `cap'. ! 201: If `area' is nonzero, it points to a pointer to a block in which ! 202: to store the string. That pointer is advanced over the space used. ! 203: If `area' is zero, space is allocated with `malloc'. */ ! 204: ! 205: char * ! 206: tgetstr (cap, area) ! 207: char *cap; ! 208: char **area; ! 209: { ! 210: register char *ptr = find_capability (term_entry, cap); ! 211: if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~')) ! 212: return 0; ! 213: return tgetst1 (ptr, area); ! 214: } ! 215: ! 216: /* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted, ! 217: gives meaning of character following \, or a space if no special meaning. ! 218: Eight characters per line within the string. */ ! 219: ! 220: static char esctab[] ! 221: = " \007\010 \033\014 \ ! 222: \012 \ ! 223: \015 \011 \013 \ ! 224: "; ! 225: ! 226: /* Given a pointer to a string value inside a termcap entry (`ptr'), ! 227: copy the value and process \ and ^ abbreviations. ! 228: Copy into block that *area points to, ! 229: or to newly allocated storage if area is 0. */ ! 230: ! 231: static char * ! 232: tgetst1 (ptr, area) ! 233: char *ptr; ! 234: char **area; ! 235: { ! 236: register char *p, *r; ! 237: register int c; ! 238: register int size; ! 239: char *ret; ! 240: register int c1; ! 241: ! 242: if (!ptr) ! 243: return 0; ! 244: ! 245: /* `ret' gets address of where to store the string */ ! 246: if (!area) ! 247: { ! 248: /* Compute size of block needed (may overestimate) */ ! 249: p = ptr; ! 250: while ((c = *p++) && c != ':' && c != '\n'); ! 251: ret = (char *) xmalloc (p - ptr + 1); ! 252: } ! 253: else ! 254: ret = *area; ! 255: ! 256: /* Copy the string value, stopping at null or colon. */ ! 257: /* Also process ^ and \ abbreviations. */ ! 258: p = ptr; ! 259: r = ret; ! 260: while ((c = *p++) && c != ':' && c != '\n') ! 261: { ! 262: if (c == '^') ! 263: c = *p++ & 037; ! 264: else if (c == '\\') ! 265: { ! 266: c = *p++; ! 267: if (c >= '0' && c <= '7') ! 268: { ! 269: c -= '0'; ! 270: size = 0; ! 271: ! 272: while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7') ! 273: { ! 274: c *= 8; ! 275: c += c1 - '0'; ! 276: p++; ! 277: } ! 278: } ! 279: else if (c >= 0100 && c < 0200) ! 280: { ! 281: c1 = esctab[(c & ~040) - 0100]; ! 282: if (c1 != ' ') ! 283: c = c1; ! 284: } ! 285: } ! 286: *r++ = c; ! 287: } ! 288: *r = 0; ! 289: /* Update *area */ ! 290: if (area) ! 291: *area = r + 1; ! 292: return ret; ! 293: } ! 294: ! 295: /* Outputting a string with padding */ ! 296: ! 297: short ospeed; ! 298: char PC; ! 299: ! 300: /* Actual baud rate if positive; ! 301: - baud rate / 100 if negative. */ ! 302: ! 303: static short speeds[] = ! 304: { ! 305: #ifdef VMS ! 306: 0, 50, 75, 110, 134, 150, -3, -6, -12, -18, ! 307: -20, -24, -36, -48, -72, -96, -192 ! 308: #else /* not VMS */ ! 309: 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, ! 310: -18, -24, -48, -96, -192, -384 ! 311: #endif /* not VMS */ ! 312: }; ! 313: ! 314: tputs (string, nlines, outfun) ! 315: register char *string; ! 316: int nlines; ! 317: register int (*outfun) (); ! 318: { ! 319: register int padcount = 0; ! 320: ! 321: if (string == (char *) 0) ! 322: return; ! 323: while (*string >= '0' && *string <= '9') ! 324: { ! 325: padcount += *string++ - '0'; ! 326: padcount *= 10; ! 327: } ! 328: if (*string == '.') ! 329: { ! 330: string++; ! 331: padcount += *string++ - '0'; ! 332: } ! 333: if (*string == '*') ! 334: { ! 335: string++; ! 336: padcount *= nlines; ! 337: } ! 338: while (*string) ! 339: (*outfun) (*string++); ! 340: ! 341: /* padcount is now in units of tenths of msec. */ ! 342: padcount *= speeds[ospeed]; ! 343: padcount += 500; ! 344: padcount /= 1000; ! 345: if (speeds[ospeed] < 0) ! 346: padcount = -padcount; ! 347: else ! 348: { ! 349: padcount += 50; ! 350: padcount /= 100; ! 351: } ! 352: ! 353: while (padcount-- > 0) ! 354: (*outfun) (PC); ! 355: } ! 356: ! 357: /* Finding the termcap entry in the termcap data base */ ! 358: ! 359: struct buffer ! 360: { ! 361: char *beg; ! 362: int size; ! 363: char *ptr; ! 364: int ateof; ! 365: int full; ! 366: }; ! 367: ! 368: /* Forward declarations of static functions */ ! 369: ! 370: static int scan_file (); ! 371: static char *gobble_line (); ! 372: static int compare_contin (); ! 373: static int name_match (); ! 374: ! 375: #ifdef VMS ! 376: ! 377: #include <rmsdef.h> ! 378: #include <fab.h> ! 379: #include <nam.h> ! 380: ! 381: static int ! 382: legal_filename_p (fn) ! 383: char *fn; ! 384: { ! 385: struct FAB fab = cc$rms_fab; ! 386: struct NAM nam = cc$rms_nam; ! 387: char esa[NAM$C_MAXRSS]; ! 388: ! 389: fab.fab$l_fna = fn; ! 390: fab.fab$b_fns = strlen(fn); ! 391: fab.fab$l_nam = &nam; ! 392: fab.fab$l_fop = FAB$M_NAM; ! 393: ! 394: nam.nam$l_esa = esa; ! 395: nam.nam$b_ess = sizeof esa; ! 396: ! 397: return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL; ! 398: } ! 399: ! 400: #endif /* VMS */ ! 401: ! 402: /* Find the termcap entry data for terminal type `name' ! 403: and store it in the block that `bp' points to. ! 404: Record its address for future use. ! 405: ! 406: If `bp' is zero, space is dynamically allocated. */ ! 407: ! 408: int ! 409: tgetent (bp, name) ! 410: char *bp, *name; ! 411: { ! 412: register char *tem; ! 413: register int fd; ! 414: struct buffer buf; ! 415: register char *bp1; ! 416: char *bp2; ! 417: char *term; ! 418: int malloc_size = 0; ! 419: register int c; ! 420: char *tcenv; /* TERMCAP value, if it contais :tc=. */ ! 421: char *indirect = 0; /* Terminal type in :tc= in TERMCAP value. */ ! 422: int filep; ! 423: ! 424: tem = (char *) getenv ("TERMCAP"); ! 425: if (tem && *tem == 0) tem = 0; ! 426: ! 427: #ifdef VMS ! 428: filep = tem && legal_filename_p (tem); ! 429: #else ! 430: filep = tem && (*tem == '/'); ! 431: #endif /* VMS */ ! 432: ! 433: /* If tem is non-null and starts with / (in the un*x case, that is), ! 434: it is a file name to use instead of /etc/termcap. ! 435: If it is non-null and does not start with /, ! 436: it is the entry itself, but only if ! 437: the name the caller requested matches the TERM variable. */ ! 438: ! 439: if (tem && !filep && !strcmp (name, getenv ("TERM"))) ! 440: { ! 441: indirect = tgetst1 (find_capability (tem, "tc"), 0); ! 442: if (!indirect) ! 443: { ! 444: if (!bp) ! 445: bp = tem; ! 446: else ! 447: strcpy (bp, tem); ! 448: goto ret; ! 449: } ! 450: else ! 451: { /* we will need to read /etc/termcap */ ! 452: tcenv = tem; ! 453: tem = 0; ! 454: } ! 455: } ! 456: else ! 457: indirect = (char *) 0; ! 458: ! 459: if (!tem) ! 460: #ifdef VMS ! 461: tem = "emacs_library:[etc]termcap.dat"; ! 462: #else ! 463: tem = "/usr/share/misc/termcap"; ! 464: #endif ! 465: ! 466: /* Here we know we must search a file and tem has its name. */ ! 467: ! 468: fd = open (tem, 0, 0); ! 469: if (fd < 0) ! 470: return -1; ! 471: ! 472: buf.size = BUFSIZE; ! 473: buf.beg = (char *) xmalloc (buf.size); ! 474: term = indirect ? indirect : name; ! 475: ! 476: if (!bp) ! 477: { ! 478: malloc_size = indirect ? strlen (tcenv) + 1 : buf.size; ! 479: bp = (char *) xmalloc (malloc_size); ! 480: } ! 481: bp1 = bp; ! 482: ! 483: if (indirect) /* copy the data from the environment variable */ ! 484: { ! 485: strcpy (bp, tcenv); ! 486: bp1 += strlen (tcenv); ! 487: } ! 488: ! 489: while (term) ! 490: { ! 491: /* Scan file, reading it via buf, till find start of main entry */ ! 492: if (scan_file (term, fd, &buf) == 0) ! 493: return 0; ! 494: ! 495: /* Free old `term' if appropriate. */ ! 496: if (term != name) ! 497: free (term); ! 498: ! 499: /* If `bp' is malloc'd by us, make sure it is big enough. */ ! 500: if (malloc_size) ! 501: { ! 502: malloc_size = bp1 - bp + buf.size; ! 503: tem = (char *) xrealloc (bp, malloc_size); ! 504: bp1 += tem - bp; ! 505: bp = tem; ! 506: } ! 507: ! 508: bp2 = bp1; ! 509: ! 510: /* Copy the line of the entry from buf into bp. */ ! 511: tem = buf.ptr; ! 512: while ((*bp1++ = c = *tem++) && c != '\n') ! 513: /* Drop out any \ newline sequence. */ ! 514: if (c == '\\' && *tem == '\n') ! 515: { ! 516: bp1--; ! 517: tem++; ! 518: } ! 519: *bp1 = 0; ! 520: ! 521: /* Does this entry refer to another terminal type's entry? */ ! 522: /* If something is found, copy it into heap and null-terminate it */ ! 523: term = tgetst1 (find_capability (bp2, "tc"), 0); ! 524: } ! 525: ! 526: close (fd); ! 527: free (buf.beg); ! 528: ! 529: if (malloc_size) ! 530: { ! 531: bp = (char *) xrealloc (bp, bp1 - bp + 1); ! 532: } ! 533: ! 534: ret: ! 535: term_entry = bp; ! 536: if (malloc_size) ! 537: return (int) bp; ! 538: return 1; ! 539: } ! 540: ! 541: /* Given file open on `fd' and buffer `bufp', ! 542: scan the file from the beginning until a line is found ! 543: that starts the entry for terminal type `string'. ! 544: Returns 1 if successful, with that line in `bufp', ! 545: or returns 0 if no entry found in the file. */ ! 546: ! 547: static int ! 548: scan_file (string, fd, bufp) ! 549: char *string; ! 550: int fd; ! 551: register struct buffer *bufp; ! 552: { ! 553: register char *tem; ! 554: register char *end; ! 555: ! 556: bufp->ptr = bufp->beg; ! 557: bufp->full = 0; ! 558: bufp->ateof = 0; ! 559: *bufp->ptr = 0; ! 560: ! 561: lseek (fd, 0L, 0); ! 562: ! 563: while (!bufp->ateof) ! 564: { ! 565: /* Read a line into the buffer */ ! 566: end = 0; ! 567: do ! 568: { ! 569: /* if it is continued, append another line to it, ! 570: until a non-continued line ends */ ! 571: end = gobble_line (fd, bufp, end); ! 572: } ! 573: while (!bufp->ateof && end[-2] == '\\'); ! 574: ! 575: if (*bufp->ptr != '#' ! 576: && name_match (bufp->ptr, string)) ! 577: return 1; ! 578: ! 579: /* Discard the line just processed */ ! 580: bufp->ptr = end; ! 581: } ! 582: return 0; ! 583: } ! 584: ! 585: /* Return nonzero if NAME is one of the names specified ! 586: by termcap entry LINE. */ ! 587: ! 588: static int ! 589: name_match (line, name) ! 590: char *line, *name; ! 591: { ! 592: register char *tem; ! 593: ! 594: if (!compare_contin (line, name)) ! 595: return 1; ! 596: /* This line starts an entry. Is it the right one? */ ! 597: for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++) ! 598: if (*tem == '|' && !compare_contin (tem + 1, name)) ! 599: return 1; ! 600: ! 601: return 0; ! 602: } ! 603: ! 604: static int ! 605: compare_contin (str1, str2) ! 606: register char *str1, *str2; ! 607: { ! 608: register int c1, c2; ! 609: while (1) ! 610: { ! 611: c1 = *str1++; ! 612: c2 = *str2++; ! 613: while (c1 == '\\' && *str1 == '\n') ! 614: { ! 615: str1++; ! 616: while ((c1 = *str1++) == ' ' || c1 == '\t'); ! 617: } ! 618: if (c2 == '\0') /* end of type being looked up */ ! 619: { ! 620: if (c1 == '|' || c1 == ':') /* If end of name in data base, */ ! 621: return 0; /* we win. */ ! 622: else ! 623: return 1; ! 624: } ! 625: else if (c1 != c2) ! 626: return 1; ! 627: } ! 628: } ! 629: ! 630: /* Make sure that the buffer <- `bufp' contains a full line ! 631: of the file open on `fd', starting at the place `bufp->ptr' ! 632: points to. Can read more of the file, discard stuff before ! 633: `bufp->ptr', or make the buffer bigger. ! 634: ! 635: Returns the pointer to after the newline ending the line, ! 636: or to the end of the file, if there is no newline to end it. ! 637: ! 638: Can also merge on continuation lines. If `append_end' is ! 639: nonzero, it points past the newline of a line that is ! 640: continued; we add another line onto it and regard the whole ! 641: thing as one line. The caller decides when a line is continued. */ ! 642: ! 643: static char * ! 644: gobble_line (fd, bufp, append_end) ! 645: int fd; ! 646: register struct buffer *bufp; ! 647: char *append_end; ! 648: { ! 649: register char *end; ! 650: register int nread; ! 651: register char *buf = bufp->beg; ! 652: register char *tem; ! 653: ! 654: if (append_end == 0) ! 655: append_end = bufp->ptr; ! 656: ! 657: while (1) ! 658: { ! 659: end = append_end; ! 660: while (*end && *end != '\n') end++; ! 661: if (*end) ! 662: break; ! 663: if (bufp->ateof) ! 664: return buf + bufp->full; ! 665: if (bufp->ptr == buf) ! 666: { ! 667: if (bufp->full == bufp->size) ! 668: { ! 669: bufp->size *= 2; ! 670: tem = (char *) xrealloc (buf, bufp->size); ! 671: bufp->ptr += tem - buf; ! 672: append_end += tem - buf; ! 673: bufp->beg = buf = tem; ! 674: } ! 675: } ! 676: else ! 677: { ! 678: append_end -= bufp->ptr - buf; ! 679: bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf); ! 680: bufp->ptr = buf; ! 681: } ! 682: if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full))) ! 683: bufp->ateof = 1; ! 684: bufp->full += nread; ! 685: if (bufp->full != bufp->size) ! 686: buf[bufp->full] = 0; ! 687: } ! 688: return end + 1; ! 689: } ! 690: ! 691: #ifdef TEST ! 692: ! 693: #include <stdio.h> ! 694: ! 695: main (argc, argv) ! 696: int argc; ! 697: char **argv; ! 698: { ! 699: char *term; ! 700: char *buf; ! 701: ! 702: term = argv[1]; ! 703: printf ("TERM: %s\n", term); ! 704: ! 705: buf = (char *) tgetent (0, term); ! 706: if ((int) buf <= 0) ! 707: { ! 708: printf ("No entry.\n"); ! 709: return 0; ! 710: } ! 711: ! 712: printf ("Entry: %s\n", buf); ! 713: ! 714: tprint ("cm"); ! 715: tprint ("AL"); ! 716: ! 717: printf ("co: %d\n", tgetnum ("co")); ! 718: printf ("am: %d\n", tgetflag ("am")); ! 719: } ! 720: ! 721: tprint (cap) ! 722: char *cap; ! 723: { ! 724: char *x = tgetstr (cap, 0); ! 725: register char *y; ! 726: ! 727: printf ("%s: ", cap); ! 728: if (x) ! 729: { ! 730: for (y = x; *y; y++) ! 731: if (*y <= ' ' || *y == 0177) ! 732: printf ("\\%0o", *y); ! 733: else ! 734: putchar (*y); ! 735: free (x); ! 736: } ! 737: else ! 738: printf ("none"); ! 739: putchar ('\n'); ! 740: } ! 741: ! 742: #endif /* TEST */ ! 743:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.