home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / tput2 / tput.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-12-02  |  5.5 KB  |  241 lines

  1. #ifndef LINT
  2. static char rcsid[] = "$Header: tput.c,v 1.6 86/09/19 17:01:00 badri Exp $" ;
  3. #endif LINT
  4. /*
  5.  * Copyright (C) $Date: 86/09/19 17:01:00 $
  6.  * by $Author: badri $
  7.  * University of Rochester,
  8.  * Department of Electrical Engineering.
  9.  *
  10.  * CoNtEnTs   This file contains a program to emulate the system V
  11.  * CoNtEnTs   version of tput.
  12.  *
  13.  * $Locker:  $
  14.  * $Source: /u/users/badri/usr/src/local/tput/RCS/tput.c,v $
  15.  * $Revision: 1.6 $
  16.  *
  17.  * History of this release:
  18.  * $Log:    tput.c,v $
  19.  * Revision 1.6  86/09/19  17:01:00  badri
  20.  * Updated to incorporate -e flag etc.
  21.  * 
  22.  * Revision 1.5  86/09/18  20:58:09  badri
  23.  * Rewrote match, which had a bug in it!
  24.  * 
  25.  * Revision 1.4  86/09/18  15:43:34  badri
  26.  * Updated to incorporate all flags of the old SV tput plus cursor movement
  27.  * plus -n flag to affect number of lines (if permitted.)
  28.  * 
  29.  * Revision 1.3  86/09/18  15:34:51  badri
  30.  * This is an interim version to make tput more compatible with SV.
  31.  * Mods suggested by mark@cbosgd (Mark Horton)
  32.  * 
  33.  * Revision 1.2  86/08/22  13:39:27  badri
  34.  * 1. Corrected a bug that would cause %d to fail after %%.
  35.  * 2. Included XTABS handling.
  36.  * 3. General cleanup of code.
  37.  * 1. Corrected a bug that would cause %d to fail after %%.
  38.  * 2. Included XTABS handling.
  39.  * 3. General cleanup of code.
  40.  * 
  41.  * Revision 1.1  86/08/21  19:23:33  badri
  42.  * Initial revision
  43.  * 
  44.  */
  45. #include "tput.h"
  46.  
  47. main(argc,argv)
  48. int argc;
  49. char *argv[];
  50. {
  51.     char bp[LARGEBUF], *getenv(), *tgetstr(), *tgoto(),
  52.          buf[SMALLBUF], *id, *area, *ptr;
  53.     int outc();
  54.     struct sgttyb ttyprm;
  55.     unsigned short ttyflg, arg, start, pos, end;
  56.     long affcnt, val;
  57.  
  58.     if (argc < 2) quit(BADUSE,"fubar");
  59.  
  60.     arg = 1;
  61.     affcnt = 1;
  62.     val = -1;    /* This is used for examining if type of
  63.              * terminal is explicitly specified.
  64.              */
  65.  
  66.     while (argv[arg][0] == '-')
  67.     {
  68.         switch (argv[arg][1])
  69.         {
  70.             case 'T':    /* Terminal type */
  71.             if (argv[arg][2] == '\0' || argc < 3)
  72.                 quit(BADUSE,"fubar");
  73.  
  74.             if (tgetent(bp,&argv[arg][2]) < 1)
  75.                 quit(BADTERM,&argv[arg][2]);
  76.             val = 0;
  77.             break;
  78.  
  79.             case 'e':    /* Suppress printing of error message */
  80.             errsup = 1;
  81.             break;
  82.  
  83.             case 'n':    /* No. of affected lines */
  84.             affcnt = atoi(&argv[arg][2]); 
  85.             break;
  86.  
  87.             default:
  88.                 quit(BADUSE,"fubar");
  89.         }
  90.         arg++;
  91.     }
  92.     if (val < 0)
  93.         if (tgetent(bp,getenv("TERM")) < 1)
  94.             quit(BADTERM,"in environment variable TERM");
  95.  
  96.     /* Begin a binary search for capability in table */ 
  97.     for (start = 0, end = TABLESIZE - 1, pos = (end - start) >> 1;
  98.          end - start > 1; pos = start + ((end - start) >> 1))
  99.     {
  100.         switch (match(argv[arg],table[pos].key))
  101.         {
  102.             case -1:    /* Lexicographically less than pos */
  103.             end = pos;
  104.             continue;
  105.  
  106.             case  0:    /* A hit! */
  107.             id = table[pos].value;
  108.             goto WORK;
  109.  
  110.             case  1:    /* Lexicographically greater than pos. */
  111.             start = pos;
  112.             continue;
  113.         }            
  114.     }
  115.  
  116.     /* Examine the current start and end positions of table for match */
  117.     if (!match(argv[arg],table[start].key)) id = table[start].value;
  118.     else if (!match(argv[arg],table[end].key)) id = table[end].value;
  119.     else quit(BADCAP,argv[arg]);  /* Could not find capability in table */
  120.  
  121.     WORK:
  122.     /* At this point we know that the capability exists in our
  123.      * table, but we do not know if it is of type boolean, string
  124.      * or has a numeric value (or does not exist.)
  125.      */
  126.     if ((val = tgetnum(id)) != -1)
  127.     {
  128.         /* It has a numeric value. Print it and quit. */
  129.         fprintf(stdout, "%d\n",val);
  130.         quit(SUCCESS,"tput");
  131.     }
  132.  
  133.     /* It is of type string (or boolean) */
  134.     area = buf;
  135.     if (!tgetstr(id,&area))
  136.     {
  137.         /* Boolean */
  138.          if (tgetflag(id)) quit(SUCCESS,"tput");
  139.         else quit(FAILURE,"tput");
  140.     }
  141.     /*
  142.      * It is of type string.
  143.      * Examine if cursor movement specified. This is done
  144.      * by looking for % followed by any but %. Since %%
  145.      * is a single %, we have to make sure that %% followed
  146.      * by any but % is not interpreted as a format.
  147.      * If cursor movement is specified then tgoto needs
  148.      * to be invoked. Else put as is.
  149.      */
  150.     ptr = buf;
  151.     while (*ptr != '\0')
  152.     {
  153.         if (*(ptr++) != '%') continue;
  154.         if (*ptr != '\0' && *(ptr++) != '%')
  155.         {
  156.             /* This string is a cm string. Increment arg to
  157.              * position it over the numeric argument (if specified!)
  158.              */
  159.             if (argc - ++arg < 2) quit(BADUSE,"fubar");
  160.  
  161.             if (*(ptr=tgoto(buf,atoi(argv[arg+1]),atoi(argv[arg])))
  162.                 == 'O' && *(ptr+1) == 'O' &&
  163.                 *(ptr+2) == 'P' && *(ptr+3) == 'S')
  164.                 quit(BADUSE,"fubar");
  165.  
  166.             /* Turn off XTABS, but save old flags first. */
  167.             if (gtty(fileno(stdout),&ttyprm) < 0)
  168.                 quit(SYSTEM,"fubar");
  169.             ttyflg = ttyprm.sg_flags;
  170.  
  171.             ttyprm.sg_flags &= ~XTABS;
  172.             if (stty(fileno(stdout),&ttyprm) < 0)
  173.                 quit(SYSTEM,"fubar");
  174.  
  175.             tputs(ptr,affcnt,outc);
  176.  
  177.             /* Restore old flags. */
  178.             ttyprm.sg_flags = ttyflg;
  179.             if (stty(fileno(stdout),&ttyprm) < 0)
  180.                 quit(SYSTEM,"fubar");
  181.             quit(SUCCESS,"tput");
  182.         }
  183.     quit(BADUSE,"fubar");
  184.     }
  185.     tputs(buf,affcnt,outc);
  186.     quit(SUCCESS,"tput");
  187. }
  188.  
  189. outc(c)
  190. char c;
  191. {
  192.     if (write(fileno(stdout),&c,sizeof(char)) < 0)
  193.         quit(SYSTEM,"fubar");
  194.     return(SUCCESS);
  195. }
  196.  
  197. match(s1,s2)
  198. char *s1, *s2;
  199. {
  200.     while (*s1 == *s2)
  201.     {
  202.         if (*s1 == '\0') return(0);
  203.         s1++, s2++;
  204.     }
  205.     return(*s1 > *s2 ? 1:-1);
  206. }
  207.  
  208. quit(i,s)
  209. int i;
  210. char *s;
  211. {
  212.     if (errsup)
  213.     {
  214.         if (i < SYSTEM) exit(i);
  215.         else exit(errno);
  216.     }
  217.     switch(i)
  218.     {
  219.         case SUCCESS:
  220.         case FAILURE:
  221.         exit(i);
  222.  
  223.         case BADUSE:
  224.         fprintf(stderr,
  225.         "Usage: tput [ -Ttype ] [ -e ] [ -nlines ] capname [ x y ]\n");
  226.         exit(i);
  227.     
  228.         case BADTERM:
  229.         fprintf(stderr, "Bad terminal type: %s\n",s);
  230.         exit(i);
  231.  
  232.         case BADCAP:
  233.         fprintf(stderr, "Bad capability: %s\n",s);
  234.         exit(i);
  235.  
  236.         case SYSTEM:
  237.         fprintf(stderr, "Terminal I/O error - examine exit status\n");
  238.         exit(errno);
  239.     }
  240. }
  241.