home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / unixlib36d / src / c / termcap < prev   
Encoding:
Text File  |  1994-03-08  |  15.7 KB  |  979 lines

  1. #ifdef __STDC__
  2. static char sccs_id[] = "@(#) termcap.c 5.6 " __DATE__ " HJR";
  3. #else
  4. static char sccs_id[] = "@(#) termcap.c 5.6 25/2/92 HJR";
  5. #endif
  6.  
  7. /* termcap.c (c) Copyright 1989/1990/1991/1992 H.Rogers */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12.  
  13. #ifdef __STDC__            /* implies ANSI C compilation */
  14. #include <stdlib.h>
  15. #else
  16. char *getenv ();
  17. char *malloc ();
  18. extern long strtol ();
  19. #define const
  20. #endif
  21.  
  22. #include "termcap.h"
  23.  
  24. #ifdef ARCH
  25. #define T_BUILTIN        /* builtin termcap */
  26.  
  27. static char *t_bname = "acorn0";
  28. static unsigned char *t_btenv = (unsigned char *)
  29. "av|acorn0|Acorn VDU Driver Mode 0:"
  30. ":li#32:co#80:am:cl=^L:bs:cm=^_%r%.%.:up=^K:ho=^^:bl=^G:bw:"
  31. ":ce=^W^H^E^F\\200\\200\\200\\200\\200\\200:"
  32. ":so=^W^Q^E\\200\\200\\200\\200\\200\\200\\200:"
  33. ":se=^W^Q^E\\200\\200\\200\\200\\200\\200\\200:"
  34. ":sb=^W^G^A^B\\200\\200\\200\\200\\200\\200:"
  35. ":sf=^W^G^A^C\\200\\200\\200\\200\\200\\200:"
  36. ":is=^C^F^D^O^V\\200:";
  37. #endif
  38.  
  39. #define T_IOCTL            /* use TIOCGWINSIZ to get LI,CO */
  40.  
  41. #ifdef T_IOCTL
  42. #include "termio.h"
  43.  
  44. #ifdef __STDC__
  45. extern int ioctl (int, int, void *);
  46. #else
  47. extern int ioctl ();
  48. #endif
  49. #endif
  50.  
  51. /* #define T_TEST */
  52. /* test main() */
  53.  
  54. /* #define T_DEBUG */
  55. /* debugging output to t_debug */
  56.  
  57. #define T_FILE "/etc/termcap"    /* the database file */
  58.  
  59. #ifdef __STDC__
  60. static int t_tgetnam (unsigned char **, unsigned char **);
  61. static int t_tgetln (FILE *, unsigned char *);
  62. static int t_tentcp (unsigned char *);
  63. static unsigned char *t_tgetid (char *);
  64. static unsigned char t_tcoord (int, unsigned int *);
  65. #else
  66. static int t_tgetnam ();    /* extracts the next name from entry */
  67. static int t_tgetln ();        /* reads line from termcap file */
  68. static int t_tentcp ();        /* copies the termcap entry into bp */
  69. static unsigned char *t_tgetid ();    /* returns a pointer to a capability */
  70. static unsigned char t_tcoord ();    /* converts a coord to an output val */
  71. #endif /* __STDC__ */
  72.  
  73. #define MAXTC 64        /* max. tc indirections */
  74.  
  75. static char __PC, *__BC, *__UP;
  76.  
  77. static char *t_tbp;
  78. static unsigned char *t_tbpstart;
  79. static int t_recurs, t_tbpspace;
  80. static unsigned char *t_tenv;
  81.  
  82. #ifdef T_DEBUG
  83. static FILE *t_debug;
  84. #endif
  85.  
  86. /* tgetent() */
  87.  
  88. int
  89. tgetent (bp, name)
  90.      char *bp, *name;
  91. {
  92.   unsigned char *tenv, *tent, *tentbuf, tc;
  93.   unsigned char *tp1, *tp2;
  94.   char *fnam;
  95.   FILE *tfile = 0;
  96.   int nbyt, rval;
  97.  
  98. #ifdef T_DEBUG
  99.   if (!t_recurs)
  100.     {
  101.       if (!(t_debug = fopen ("t_debug", "w")))
  102.     return (-1);
  103.       setvbuf (t_debug, (char *) 0, _IONBF, BUFSIZ);
  104.     }
  105. #endif
  106.  
  107.   if (!(t_tbp = bp))
  108.     return (-1);
  109.  
  110.   if (!name)
  111. #ifdef T_BUILTIN
  112. #ifdef T_DEBUG
  113.     fputs ("tgetent(\"(null)\")\n", t_debug);
  114. #endif
  115.   name = t_bname;
  116. #else
  117.     return (-1);
  118. #endif
  119.  
  120.   fnam = T_FILE;
  121.  
  122.   if (!t_recurs)
  123.     t_tbpspace = 1024;
  124.  
  125.   if (!t_recurs)
  126.     {
  127.       char *t = getenv ("TERM");
  128.  
  129.       if (!t)
  130.     t = "";
  131.       if (!strcmp (name, t))
  132.     t_tenv = (unsigned char *) getenv ("TERMCAP");
  133.       else
  134.     t_tenv = 0;
  135.     }
  136.  
  137.   if (tenv = t_tenv)
  138.     {
  139.       if (!t_recurs && *tenv != '/')
  140.     {
  141. #ifdef T_BUILTIN
  142.     builtin:
  143. #endif
  144.  
  145.       while (isspace (*tenv))
  146.         tenv++;
  147.       tp1 = tp2 = tenv;
  148.  
  149. #ifdef T_DEBUG
  150.       fprintf (t_debug, "tgetent(\"%s\") < $TERMCAP\n", name);
  151. #endif
  152.  
  153.       while (t_tgetnam (&tp1, &tp2))
  154.         {
  155.           tc = *tp2;
  156.           *tp2 = 0;
  157.  
  158. #ifdef T_DEBUG
  159.           fprintf (t_debug, "t_tgetnam(): %s\n", (char *) tp1);
  160. #endif
  161.  
  162.           if (!strcmp ((char *) tp1, name))
  163.         {
  164.           *tp2 = tc;
  165.  
  166. #ifdef T_DEBUG
  167.           fputs ("t_tgetnam() - MATCH -\n", t_debug);
  168. #endif
  169.  
  170.           if (strlen ((char *) tenv) > t_tbpspace)
  171.             return (-1);
  172.           return (t_tentcp (tenv) ? -1 : 1);
  173.         }
  174.           else
  175.         *tp2 = tc;
  176.         }
  177.     }
  178.       else if (*tenv == '/')
  179.     {
  180.  
  181. #ifdef T_DEBUG
  182.       fprintf (t_debug, "tgetent(\"%s\") < %s\n", name, (char *) tenv);
  183. #endif
  184.  
  185.       fnam = (char *) tenv;
  186.     }
  187.     }
  188.  
  189. #ifdef T_DEBUG
  190.   if (fnam != (char *) t_tenv)
  191.     fprintf (t_debug, "tgetent(\"%s\") < /etc/termcap\n", name);
  192. #endif
  193.  
  194.   if (!(tfile = fopen (fnam, "r")))
  195. #ifdef T_BUILTIN
  196.     {
  197.       if (fnam != (char *) t_tenv && !strcmp (name, t_bname))
  198.     {
  199.       tenv = t_btenv;
  200.       goto builtin;
  201.     }
  202.       else
  203.     return (-1);
  204.     }
  205. #else
  206.     return (-1);
  207. #endif
  208.  
  209.   tent = tentbuf = (unsigned char *) malloc (1024);
  210.  
  211.   while (nbyt = t_tgetln (tfile, tent))
  212.     {
  213.       if (*tent != '#')
  214.     {
  215.       while (isspace (*tent))
  216.         tent++;
  217.       tp1 = tp2 = tent;
  218.       while (t_tgetnam (&tp1, &tp2))
  219.         {
  220.           tc = *tp2;
  221.           *tp2 = 0;
  222.  
  223. #ifdef T_DEBUG
  224.           fprintf (t_debug, "t_tgetnam(): %s\n", (char *) tp1);
  225. #endif
  226.  
  227.           if (!strcmp ((char *) tp1, name))
  228.         {
  229.           *tp2 = tc;
  230.  
  231. #ifdef T_DEBUG
  232.           fprintf (t_debug, "t_tgetnam() - MATCH -\n");
  233.           fprintf (t_debug, "t_tgetnam(): [%d (%d)] %s\n", nbyt, t_tbpspace, tent);
  234. #endif
  235.  
  236.           if (nbyt > t_tbpspace || nbyt < 0)
  237.             {
  238.               free ((char *) tentbuf);
  239.               return (-1);
  240.             }
  241.           if (tfile)
  242.             {
  243.               fclose (tfile);
  244.               tfile = 0;
  245.             }
  246.           rval = t_tentcp (tent);
  247.           free ((char *) tentbuf);
  248.           return (rval ? -1 : 1);
  249.         }
  250.           else
  251.         *tp2 = tc;
  252.         }
  253.     }
  254.     }
  255.  
  256.   if (tfile)
  257.     {
  258.       fclose (tfile);
  259.       tfile = 0;
  260.     }
  261.  
  262.   free ((char *) tentbuf);
  263.  
  264.   return (0);
  265. }
  266.  
  267. /* t_tgetnam() */
  268.  
  269. static int
  270. t_tgetnam (t1, t2)
  271.      unsigned char **t1, **t2;
  272. {
  273.   register unsigned char *tp1 = *t1, *tp2 = *t2;
  274.  
  275.   while ((*tp2 == '|') || isspace (*tp2))
  276.     tp2++;
  277.   if (*tp2 == ':')
  278.     return (0);
  279.   tp1 = tp2;
  280.   while ((*tp2 != '|') && (*tp2 != ':'))
  281.     tp2++;
  282.  
  283.   *t1 = tp1;
  284.   *t2 = tp2;
  285.   return (-1);
  286. }
  287.  
  288. /* t_tentcp() */
  289.  
  290. static int
  291. t_tentcp (s)
  292.      unsigned char *s;
  293. {
  294.   register unsigned char *s1, *s2, *sp;
  295.   char *t_tbp_;
  296.   char *tcnam, *tcn;
  297.  
  298. #ifdef T_DEBUG
  299.   fputs ("t_tentcp()\n", t_debug);
  300. #endif
  301.  
  302.   tcnam = (char *) malloc (256);
  303.  
  304.   s1 = (unsigned char *) t_tbp;
  305.   s2 = s;
  306.  
  307.   while (*s2)
  308.     {
  309.       if (*s2 == ':')        /* strips out empty capabilities :: */
  310.     {
  311.       sp = s2 + 1;
  312.       while (isspace (*sp))
  313.         sp++;
  314.       if (*sp == ':')
  315.         s2 = sp;
  316.     }
  317.       *s1++ = *s2++;
  318.     }
  319.  
  320.   *s1 = 0;
  321.  
  322.   if (!t_recurs)
  323.     {
  324.       sp = (unsigned char *) t_tbp;
  325.       while (*sp++ != ':');
  326.       t_tbpstart = sp;
  327.     }
  328.  
  329.   if (sp = t_tgetid ("tc"))
  330.     {
  331.  
  332. #ifdef T_DEBUG
  333.       fprintf (t_debug, "tgetent()# %d\n", t_recurs);
  334. #endif
  335.  
  336.       if (++t_recurs > (MAXTC - 1))
  337.     {
  338.       free (tcnam);
  339.       return (-1);
  340.     }
  341.       t_tbp_ = t_tbp;
  342.  
  343.       tcn = tcnam;
  344.       s1 = sp = sp - 2;
  345.       t_tbpspace -= (int) (s1 - (unsigned char *) t_tbp);
  346.       if (tgetent ((char *) s1, tgetstr ("tc", &tcn)) < 1)
  347.     {
  348.       free (tcnam);
  349.       return (-1);
  350.     }
  351.  
  352.       while (*sp++ != ':');
  353.       while (*s1++ = *sp++);
  354.  
  355.       t_tbp = t_tbp_;
  356.       t_recurs--;
  357.     }
  358.  
  359. #ifdef T_DEBUG
  360.   fprintf (t_debug, "tgetent(): %s\n", t_tbp);
  361. #endif
  362.  
  363.   if (!t_recurs)
  364.     {
  365.       __PC = 0;
  366.       __BC = "\b";
  367.       __UP = "\v";
  368.     }
  369.  
  370.   free (tcnam);
  371.  
  372.   return (0);
  373. }
  374.  
  375. /* t_tgetln() */
  376.  
  377. static int
  378. t_tgetln (tfile, buf)
  379.      FILE *tfile;
  380.      register unsigned char *buf;
  381. {
  382.   register unsigned char *bufp;
  383.   register int nbyt;
  384.  
  385.   bufp = buf;
  386.   nbyt = 0;
  387.  
  388.   while (-1)
  389.     {
  390.       if (!fgets ((char *) bufp, t_tbpspace - nbyt, tfile))
  391.     return (nbyt);
  392.       while (*bufp++);
  393.       bufp--;
  394.       if (*--bufp != '\n')
  395.     ++bufp;
  396.       nbyt += (bufp - buf);
  397.       if (!nbyt)
  398.     continue;
  399.       if (*--bufp != '\\')
  400.     {
  401.       *++bufp = 0;
  402.       return (nbyt);
  403.     }
  404.       buf = bufp;
  405.       nbyt--;
  406.     }
  407. }
  408.  
  409. /* t_tgetid() */
  410.  
  411. static unsigned char *
  412. t_tgetid (id)
  413.      register char *id;
  414. {
  415.   register unsigned char *bptr;
  416.   int found;
  417.  
  418.   if ((!id) || (!t_tbpstart))
  419.     return (0);
  420.  
  421.   bptr = t_tbpstart;
  422.   while (*bptr)
  423.     {
  424.       found = (((unsigned char) *id++ == *bptr++) ? \
  425.            ((unsigned char) *id == *bptr) : 0);
  426.       bptr++;
  427.       id--;
  428.       if (found)
  429.     {
  430.       if (*bptr == '@')
  431.         return (0);
  432.       else
  433.         return (bptr);
  434.     }
  435.       while ((*bptr != ':') && (*bptr != 0))
  436.     bptr++;
  437.       if (*bptr == ':')
  438.     bptr++;
  439.     }
  440.   return (0);
  441. }
  442.  
  443. /* tgetnum() */
  444.  
  445. int
  446. tgetnum (id)
  447.      char *id;
  448. {
  449.   register unsigned char *eptr;
  450.   int rval;
  451.  
  452. #ifdef TIOCGWINSZ
  453.   if (rval = (!strncmp (id, "li", 2) ? 1 : (!strncmp (id, "co", 2) ? -1 : 0)))
  454.     {
  455.       struct winsize w[1];
  456.  
  457.       ioctl (2, TIOCGWINSZ, w);
  458.       return ((rval > 0) ? w->ws_row : w->ws_col);
  459.     }
  460. #endif
  461.  
  462.   if (!(eptr = t_tgetid (id)))
  463.     return (-1);
  464.  
  465.   if (*eptr++ != '#')
  466.     return (0);
  467.   rval = atoi ((const char *) eptr);
  468.  
  469. #ifdef T_DEBUG
  470.   fprintf (t_debug, "tgetnum(\"%s\"): %d\n", id, rval);
  471. #endif
  472.  
  473.   return (rval);
  474. }
  475.  
  476. /* tgetflag() */
  477.  
  478. int
  479. tgetflag (id)
  480.      char *id;
  481. {
  482.   register unsigned char *idp;
  483.  
  484. #ifdef T_DEBUG
  485.   int rval;
  486.  
  487.   idp = t_tgetid (id);
  488.   rval = (idp ? ((*idp != '@') ? 1 : 0) : 0);
  489.   fprintf (t_debug, "tgetflag(\"%s\"): %d\n", id, rval);
  490.   return (rval);
  491. #else
  492.   idp = t_tgetid (id);
  493.   return (idp ? ((*idp != '@') ? 1 : 0) : 0);
  494. #endif
  495. }
  496.  
  497. /* tgetstr() */
  498.  
  499. char *
  500. tgetstr (id, area)
  501.      char *id, **area;
  502. {
  503.   register unsigned char *eptr, *aptr;
  504.   unsigned char obuf[4];
  505.   char *rval;
  506.  
  507. #ifdef T_DEBUG
  508.   fprintf (t_debug, "tgetstr(\"%s\")\n", id);
  509. #endif
  510.  
  511.   if (!(area ? *area : 0))
  512.     {
  513.       rval = 0;
  514.       goto tgetstr_ret;
  515.     }
  516.  
  517.   aptr = (unsigned char *) *area;
  518.   if (!(eptr = t_tgetid (id)))
  519.     return (0);
  520.   if (*eptr++ != '=')
  521.     {
  522.       *aptr = 0;
  523.       return (0);
  524.     }
  525.  
  526.   if ((*eptr >= '0') && (*eptr <= '9'))
  527.     {
  528.       while ((*eptr >= '0') && (*eptr <= '9'))
  529.     *aptr++ = *eptr++;
  530.       if (*eptr == '*')
  531.     *aptr++ = *eptr++;
  532.     }
  533.  
  534.   obuf[3] = 0;
  535.   while ((*eptr != ':') && (*eptr != 0))
  536.     {
  537.       switch (*eptr)
  538.     {
  539.     case '\\':
  540.       switch (*++eptr)
  541.         {
  542.         case 'E':
  543.           *aptr = 0x1b;
  544.           break;
  545.         case 'n':
  546.           *aptr = 0x0a;
  547.           break;
  548.         case 'r':
  549.           *aptr = 0x0d;
  550.           break;
  551.         case 't':
  552.           *aptr = 0x09;
  553.           break;
  554.         case 'b':
  555.           *aptr = 0x08;
  556.           break;
  557.         case 'f':
  558.           *aptr = 0x0c;
  559.           break;
  560.         case '0':
  561.         case '1':
  562.         case '2':
  563.         case '3':
  564.           obuf[0] = *eptr++;
  565.           obuf[1] = *eptr++;
  566.           obuf[2] = *eptr;
  567.           *aptr = (char) (strtol ((const char *) obuf, 0, 8) & 0xff);
  568.           break;
  569.         default:
  570.           *aptr = *eptr;
  571.         }
  572.       break;
  573.     case '^':
  574.       *aptr = ((*++eptr) & 0x1f);
  575.       break;
  576.     default:
  577.       *aptr = *eptr;
  578.       break;
  579.     }
  580.       eptr++;
  581.       aptr++;
  582.     }
  583.  
  584.   *aptr++ = 0;
  585.   rval = *area;
  586.   *area = (char *) aptr;
  587.  
  588. tgetstr_ret:
  589.  
  590. #ifdef T_DEBUG
  591.   fprintf (t_debug, "tgetstr(\"%s\"): %s\n", id, rval);
  592. #endif
  593.  
  594.   if (rval)
  595.     {
  596.       if (id[1] == 'c')
  597.     {
  598.       if (id[0] == 'b')
  599.         __BC = rval;
  600.       else if (id[0] == 'p')
  601.         __PC = *rval & 0x7f;
  602.     }
  603.       else if (id[0] == 'u' && id[1] == 'p')
  604.     __UP = rval;
  605.       else if (id[0] == 'l' && id[1] == 'e')    /* terminfo compatibility */
  606.     __BC = rval;
  607.     }
  608.  
  609.   return (rval);
  610. }
  611.  
  612. static int tg_aoff, tg_coff, tg_clev;
  613.  
  614. #define TG_revxy    0001
  615. #define TG_incxy    0002
  616. #define TG_eorxy    0004
  617. #define TG_bcdxy    0010
  618. #define TG_revcod    0020
  619. #define TG_bc        0040
  620. #define TG_up        0100
  621. #define TG_chkout    0200
  622.  
  623. /* tgoto() */
  624.  
  625. char *
  626. tgoto (cm, destcol, destline)
  627.      char *cm;
  628.      int destcol, destline;
  629. {
  630.   static char rstr[256];
  631.   register char *cmp, *rstrp, *cp;
  632.   unsigned int f;
  633.  
  634. #define TC(f) (((f) & TG_revxy) ? destcol : destline)
  635.  
  636. #ifdef T_DEBUG
  637.   fprintf (t_debug, "tgoto(\"%s\",%d,%d): ", cm, destcol, destline);
  638.  
  639.   if (!cm)
  640.     {
  641.       putc ('\n', t_debug);
  642.       return (0);
  643.     }
  644. #else
  645.   if (!cm)
  646.     return (0);
  647. #endif
  648.  
  649.   tg_aoff = tg_coff = tg_clev = 0;
  650.   f = 0;
  651.  
  652.   cmp = cm;
  653.   rstrp = rstr;
  654.   while (*cmp)
  655.     {
  656.       if (*cmp == '%')
  657.     {
  658.       register int d;
  659.       register char *e;
  660.  
  661.       cmp++;
  662.       switch (*cmp++)
  663.         {
  664.         case 'r':
  665.           f |= TG_revxy;
  666.           break;
  667.         case 'i':
  668.           f |= TG_incxy;
  669.           break;
  670.         case 'n':
  671.           f |= TG_eorxy;
  672.           break;
  673.         case 'B':
  674.           f |= TG_bcdxy;
  675.           break;
  676.         case 'D':
  677.           f |= TG_revcod;
  678.           break;
  679.         case '>':
  680.           tg_clev = *cmp++;
  681.           tg_coff = *cmp++;
  682.           break;
  683.         case '+':
  684.           tg_aoff = *cmp++;    /* fallthru */
  685.         case '.':
  686.           f |= TG_chkout;
  687.           *rstrp++ = t_tcoord (TC (f), &f);
  688.           break;
  689.         case 'd':
  690.           d = (int) t_tcoord (TC (f), &f);
  691.           e = rstrp + 1;
  692.           if (d > 9)
  693.         e++;
  694.           if (d > 99)
  695.         e++;
  696.           rstrp = e;
  697.           *e = 0;
  698.           do
  699.         {
  700.           *--e = (d % 10) + '0';
  701.           d /= 10;
  702.         }
  703.           while (d);
  704.           break;
  705.         case '2':
  706.           d = (int) t_tcoord (TC (f), &f);
  707.           *rstrp = ' ';
  708.           if (d > 99)
  709.         *++rstrp = ' ';
  710.           e = rstrp = rstrp + 2;
  711.           *e = 0;
  712.           do
  713.         {
  714.           *--e = (d % 10) + '0';
  715.           d /= 10;
  716.         }
  717.           while (d);
  718.           break;
  719.         case '3':
  720.           d = (int) t_tcoord (TC (f), &f);
  721.           *rstrp = ' ';
  722.           *++rstrp = ' ';
  723.           e = rstrp = rstrp + 2;
  724.           *e = 0;
  725.           do
  726.         {
  727.           *--e = (d % 10) + '0';
  728.           d /= 10;
  729.         }
  730.           while (d);
  731.           break;
  732.         case '%':
  733.           *rstrp++ = '%';
  734.           break;
  735.         default:
  736.           rstrp = "OOPS";
  737.           goto tgoto_ret;
  738.           break;
  739.         }
  740.     }
  741.       else
  742.     *rstrp++ = *cmp++;
  743.     }
  744.  
  745.   if (f & TG_bc)
  746.     {
  747.       cp = __BC;
  748.       while (*rstrp = *cp)
  749.     rstrp++, cp++;
  750.     }
  751.   if (f & TG_up)
  752.     {
  753.       cp = __UP;
  754.       while (*rstrp = *cp)
  755.     rstrp++, cp++;
  756.     }
  757.  
  758.   *rstrp = 0;
  759.  
  760.   rstrp = rstr;
  761.  
  762. tgoto_ret:
  763.  
  764. #ifdef T_DEBUG
  765.   fprintf (t_debug, "%s\n", rstrp);
  766. #endif
  767.  
  768.   return (rstrp);
  769. }
  770.  
  771. /* t_tcoord() */
  772.  
  773. static unsigned char
  774. t_tcoord (x, _f)
  775.      register int x;
  776.      unsigned int *_f;
  777. {
  778.   register unsigned int f;
  779.  
  780. t_tccalc:
  781.  
  782.   f = (*_f);
  783.  
  784.   if (x > tg_clev)
  785.     x += tg_coff;
  786.   x += tg_aoff;
  787.   if (f & TG_incxy)
  788.     x++;
  789.   if (f & TG_eorxy)
  790.     x ^= 0140;
  791.   if (f & TG_bcdxy)
  792.     x = ((x / 10) << 4) | (x % 10);
  793.   if (f & TG_revcod)
  794.     x = (x - ((x & 15) << 1));
  795.  
  796.   if (f & TG_chkout)
  797.     {
  798.       (*_f) &= (~TG_chkout);
  799.       if (!x || x == '\004' || x == '\n' || x == '\r')
  800.     {
  801.       if (f & TG_revxy)
  802.         (*_f) |= TG_bc;
  803.       else
  804.         (*_f) |= TG_up;
  805.       x++;
  806.       goto t_tccalc;
  807.     }
  808.     }
  809.  
  810.   (*_f) ^= TG_revxy;
  811.   tg_aoff = 0;
  812.   return (x);
  813. }
  814.  
  815. /* tputs() */
  816.  
  817. int
  818. tputs (cp, affcnt, outc)
  819.      register char *cp;
  820.      int affcnt;
  821. #ifdef __STDC__
  822.      int (*outc) (char);
  823. #else
  824.      int (*outc) ();
  825. #endif
  826. {
  827.   register int i;
  828.   char *cpp;
  829.   int delay;
  830.  
  831. #ifdef T_DEBUG
  832.   fprintf (t_debug, "tputs(\"%s\",%d)\n", cp, affcnt);
  833. #endif
  834.  
  835.   if ((!cp) || (!outc))
  836.     return (0);
  837.  
  838.   if (isdigit (*cp))
  839.     {
  840.       delay = (int) strtol (cp, &cpp, 0);
  841.       cp = cpp;
  842.     }
  843.   else
  844. #ifdef T_DEBUG
  845.     {
  846.       cpp = cp;
  847.       delay = 0;
  848.     }
  849. #else
  850.     delay = 0;
  851. #endif
  852.  
  853.   i = *cp;
  854.  
  855.   if (i == '.')
  856.     while (isdigit (*++cp));
  857.   if (i == '*')
  858.     {
  859.       delay *= affcnt;
  860.       cp++;
  861.     }
  862.  
  863.   if (ospeed > 13)
  864.     delay <<= (ospeed - 13);
  865.   else
  866.     delay >>= (13 - ospeed);
  867.  
  868. #ifdef T_DEBUG
  869.   fprintf (t_debug, "tputs() (pad %d): %s\n", delay, cpp);
  870. #endif
  871.  
  872.   while (i = *cp++)
  873.     (*outc) (i & 0x7f);
  874.  
  875.   if (ospeed)
  876.     while (delay-- > 0)
  877.       (*outc) (__PC);
  878.  
  879.   return (0);
  880. }
  881.  
  882. #ifdef T_TEST
  883.  
  884. char PC, *BC, *UP;
  885.  
  886. #ifdef __STDC__
  887. static int out (char);
  888. static void dump (char *);
  889. #else
  890. static int out ();
  891. static void dump ();
  892. #endif
  893.  
  894. /* main() */
  895.  
  896. #ifdef __STDC__
  897. int
  898. main (void)
  899. #else
  900. int
  901. main ()
  902. #endif
  903. {
  904.   static char bp[1024], tbuf[512];
  905.   char *tbufp, *cm;
  906.   int rval, i;
  907.  
  908.   if ((rval = tgetent (bp, getenv ("TERM"))) < 1)
  909.     {
  910.       fprintf (stderr, "termcap: tgetent() returned %d\n", rval);
  911.       exit (1);
  912.     }
  913.  
  914.   tbufp = tbuf;
  915.  
  916.   if (tgetstr ("pc", &tbufp))
  917.     PC = *tbuf;
  918.  
  919.   if (!(BC = tgetstr ("bc", &tbufp)))
  920.     BC = "\b";
  921.  
  922.   UP = tgetstr ("up", &tbufp);
  923.  
  924.   tputs (tgetstr ("cl", &tbufp), 1, out);
  925.  
  926.   printf ("tgetent(): %s\n", bp);
  927.  
  928.   printf ("tgetflag(\"cm\"): %d\n", tgetflag ("cm"));
  929.  
  930.   printf ("tgetnum(\"li\"): %d\n", tgetnum ("li"));
  931.  
  932.   tbufp = tbuf;
  933.  
  934.   printf ("tgetstr(\"cm\"): ");
  935.   dump (cm = tgetstr ("cm", &tbufp));
  936.  
  937.   for (i = 0; i < 10; i++)
  938.     {
  939.       tputs (tgoto (cm, i << 1, i + 20), 1, out);
  940.       printf ("%d", i);
  941.     }
  942.  
  943.   printf ("\n");
  944. }
  945.  
  946. #ifdef __STDC__
  947. static int
  948. out (char c)
  949. #else
  950. static int
  951. out (c)
  952.      char c;
  953. #endif
  954. {
  955.   return (putc (c, stdout));
  956. }
  957.  
  958. static void
  959. dump (s)
  960.      char *s;
  961. {
  962.   if (!s)
  963.     {
  964.       printf ("(null)\n");
  965.       return;
  966.     }
  967.   while (*s)
  968.     {
  969.       if ((*s < ' ') || (*s > '\176'))
  970.     printf ("\\%03o", (int) *s);
  971.       else
  972.     putc (*s, stdout);
  973.       s++;
  974.     }
  975.   putc ('\n', stdout);
  976. }
  977.  
  978. #endif /* T_TEST */
  979.