home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Shells / tcsh / Source / vms.termcap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  7.0 KB  |  337 lines

  1. /* $Header: /u/christos/src/tcsh-6.03/RCS/vms.termcap.c,v 1.1 1992/10/05 02:39:59 christos Exp $ */
  2. /*
  3.  *    termcap.c    1.1    20/7/87        agc    Joypace Ltd
  4.  *
  5.  *    Copyright Joypace Ltd, London, UK, 1987. All rights reserved.
  6.  *    This file may be freely distributed provided that this notice
  7.  *    remains attached.
  8.  *
  9.  *    A public domain implementation of the termcap(3) routines.
  10.  */
  11. #include "sh.h"
  12. RCSID("$Id: vms.termcap.c,v 1.1 1992/10/05 02:39:59 christos Exp $")
  13. #ifdef _VMS_POSIX
  14. /*    efth      1988-Apr-29
  15.  
  16.     - Correct when TERM != name and TERMCAP is defined   [tgetent]
  17.     - Correct the comparison for the terminal name       [tgetent]
  18.     - Correct the value of ^x escapes                    [tgetstr]
  19.     - Added %r to reverse row/column             [tgoto]
  20.  
  21.      Paul Gillingwater <paul@actrix.gen.nz> July 1992
  22.     - Modified to allow terminal aliases in termcap file
  23.     - Uses TERMCAP environment variable for file only
  24. */
  25.  
  26. #include    <stdio.h>
  27. #include    <string.h>
  28.  
  29. #define CAPABLEN    2
  30.  
  31. #define ISSPACE(c)  ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n')
  32. #define ISDIGIT(x)  ((x) >= '0' && (x) <= '9')
  33.  
  34. char        *capab;        /* the capability itself */
  35.  
  36. extern char    *getenv();    /* new, improved getenv */
  37. extern FILE    *fopen();    /* old fopen */
  38.  
  39. /*
  40.  *    tgetent - get the termcap entry for terminal name, and put it
  41.  *    in bp (which must be an array of 1024 chars). Returns 1 if
  42.  *    termcap entry found, 0 if not found, and -1 if file not found.
  43.  */
  44.  
  45. int
  46. tgetent(bp, name)
  47. char    *bp;
  48. char    *name;
  49. {
  50.     FILE    *fp;
  51.     char    *termfile;
  52.     char    *cp,
  53.         *ptr,        /* temporary pointer */
  54.         tmp[1024];    /* buffer for terminal name */
  55.     short    len = strlen(name);
  56.  
  57.     capab = bp;
  58.  
  59.     /* Use TERMCAP to override default. */
  60.  
  61.     termfile = getenv("TERMCAP");
  62.     if (termfile == NULL ) termfile = "/etc/termcap";
  63.  
  64.     if ((fp = fopen(termfile, "r")) == (FILE *) NULL) {
  65.         fprintf(stderr,"Can't open TERMCAP: [%s]\n", termfile);
  66.         fprintf(stderr,"Can't open %s.\n",termfile);
  67.         sleep(1);
  68.         return(-1);
  69.     }
  70.  
  71.     while (fgets(bp, 1024, fp) != NULL) {
  72.         /* Any line starting with # or NL is skipped as a comment */
  73.         if ((*bp == '#') || (*bp == '\n')) continue;
  74.  
  75.         /* Look for lines which end with two backslashes,
  76.         and then append the next line. */
  77.         while (*(cp = &bp[strlen(bp) - 2]) == '\\')
  78.             fgets(cp, 1024, fp);
  79.         
  80.         /* Skip over any spaces or tabs */
  81.         for (++cp ; ISSPACE(*cp) ; cp++);
  82.  
  83.         /*  Make sure "name" matches exactly  (efth)  */
  84.  
  85. /* Here we might want to look at any aliases as well.  We'll use
  86. sscanf to look at aliases.  These are delimited by '|'. */
  87.  
  88.         sscanf(bp,"%[^|]",tmp);
  89.         if (strncmp(name, tmp, len) == 0) {
  90.             fclose(fp);
  91. #ifdef DEBUG
  92.     fprintf(stderr,"Found %s in %s.\n", name, termfile);
  93.     sleep(1);
  94. #endif /* DEBUG */
  95.             return(1);
  96.         }
  97.         ptr = bp;
  98.         while ((ptr = strchr(ptr,'|')) != NULL) {
  99.             ptr++;
  100.             if (strchr(ptr,'|') == NULL) break;
  101.             sscanf(ptr,"%[^|]",tmp);
  102.             if (strncmp(name, tmp, len) == 0) {
  103.                 fclose(fp);
  104. #ifdef DEBUG
  105.     fprintf(stderr,"Found %s in %s.\n", name, termfile);
  106.     sleep(1);
  107. #endif /* DEBUG */
  108.                 return(1);
  109.             }
  110.         }
  111.     }
  112.     /* If we get here, then we haven't found a match. */
  113.     fclose(fp);
  114. #ifdef DEBUG
  115.     fprintf(stderr,"No match found for %s in file %s\n",
  116.         name, termfile);
  117.     sleep(1);
  118. #endif /* DEBUG */
  119.     return(0);
  120.     
  121. }
  122.  
  123. /*
  124.  *    tgetnum - get the numeric terminal capability corresponding
  125.  *    to id. Returns the value, -1 if invalid.
  126.  */
  127. int
  128. tgetnum(id)
  129. char    *id;
  130. {
  131.     char    *cp;
  132.     int    ret;
  133.  
  134.     if ((cp = capab) == NULL || id == NULL)
  135.         return(-1);
  136.     while (*++cp != ':')
  137.         ;
  138.     for (++cp ; *cp ; cp++) {
  139.         while (ISSPACE(*cp))
  140.             cp++;
  141.         if (strncmp(cp, id, CAPABLEN) == 0) {
  142.             while (*cp && *cp != ':' && *cp != '#')
  143.                 cp++;
  144.             if (*cp != '#')
  145.                 return(-1);
  146.             for (ret = 0, cp++ ; *cp && ISDIGIT(*cp) ; cp++)
  147.                 ret = ret * 10 + *cp - '0';
  148.             return(ret);
  149.         }
  150.         while (*cp && *cp != ':')
  151.             cp++;
  152.     }
  153.     return(-1);
  154. }
  155.  
  156. /*
  157.  *    tgetflag - get the boolean flag corresponding to id. Returns -1
  158.  *    if invalid, 0 if the flag is not in termcap entry, or 1 if it is
  159.  *    present.
  160.  */
  161. int
  162. tgetflag(id)
  163. char    *id;
  164. {
  165.     char    *cp;
  166.  
  167.     if ((cp = capab) == NULL || id == NULL)
  168.         return(-1);
  169.     while (*++cp != ':')
  170.         ;
  171.     for (++cp ; *cp ; cp++) {
  172.         while (ISSPACE(*cp))
  173.             cp++;
  174.         if (strncmp(cp, id, CAPABLEN) == 0)
  175.             return(1);
  176.         while (*cp && *cp != ':')
  177.             cp++;
  178.     }
  179.     return(0);
  180. }
  181.  
  182. /*
  183.  *    tgetstr - get the string capability corresponding to id and place
  184.  *    it in area (advancing area at same time). Expand escape sequences
  185.  *    etc. Returns the string, or NULL if it can't do it.
  186.  */
  187. char *
  188. tgetstr(id, area)
  189. char    *id;
  190. char    **area;
  191. {
  192.     char    *cp;
  193.     char    *ret;
  194.     int    i;
  195.  
  196.     if ((cp = capab) == NULL || id == NULL)
  197.         return(NULL);
  198.     while (*++cp != ':')
  199.         ;
  200.     for (++cp ; *cp ; cp++) {
  201.         while (ISSPACE(*cp))
  202.             cp++;
  203.         if (strncmp(cp, id, CAPABLEN) == 0) {
  204.             while (*cp && *cp != ':' && *cp != '=')
  205.                 cp++;
  206.             if (*cp != '=')
  207.                 return(NULL);
  208.             for (ret = *area, cp++; *cp && *cp != ':' ; 
  209.                 (*area)++, cp++)
  210.                 switch(*cp) {
  211.                 case '^' :
  212.                     **area = *++cp - '@'; /* fix (efth)*/
  213.                     break;
  214.                 case '\\' :
  215.                     switch(*++cp) {
  216.                     case 'E' :
  217.                         **area = '\033';
  218.                         break;
  219.                     case 'n' :
  220.                         **area = '\n';
  221.                         break;
  222.                     case 'r' :
  223.                         **area = '\r';
  224.                         break;
  225.                     case 't' :
  226.                         **area = '\t';
  227.                         break;
  228.                     case 'b' :
  229.                         **area = '\b';
  230.                         break;
  231.                     case 'f' :
  232.                         **area = '\f';
  233.                         break;
  234.                     case '0' :
  235.                     case '1' :
  236.                     case '2' :
  237.                     case '3' :
  238.                         for (i=0 ; *cp && ISDIGIT(*cp) ;
  239.                              cp++)
  240.                             i = i * 8 + *cp - '0';
  241.                         **area = i;
  242.                         cp--;
  243.                         break;
  244.                     case '^' :
  245.                     case '\\' :
  246.                         **area = *cp;
  247.                         break;
  248.                     }
  249.                     break;
  250.                 default :
  251.                     **area = *cp;
  252.                 }
  253.             *(*area)++ = '\0';
  254.             return(ret);
  255.         }
  256.         while (*cp && *cp != ':')
  257.             cp++;
  258.     }
  259.     return(NULL);
  260. }
  261.  
  262. /*
  263.  *    tgoto - given the cursor motion string cm, make up the string
  264.  *    for the cursor to go to (destcol, destline), and return the string.
  265.  *    Returns "OOPS" if something's gone wrong, or the string otherwise.
  266.  */
  267. char *
  268. tgoto(cm, destcol, destline)
  269. char    *cm;
  270. int    destcol;
  271. int    destline;
  272. {
  273.     register char    *rp;
  274.     static char    ret[24];
  275.     int        incr = 0;
  276.     int         argno = 0, numval;
  277.  
  278.     for (rp = ret ; *cm ; cm++) {
  279.         switch(*cm) {
  280.         case '%' :
  281.             switch(*++cm) {
  282.             case '+' :
  283.                 numval = (argno == 0 ? destline : destcol);
  284.                 argno = 1 - argno;
  285.                 *rp++ = numval + incr + *++cm;
  286.                 break;
  287.  
  288.             case '%' :
  289.                 *rp++ = '%';
  290.                 break;
  291.  
  292.             case 'i' :
  293.                 incr = 1;
  294.                 break;
  295.  
  296.             case 'd' :
  297.                 numval = (argno == 0 ? destline : destcol);
  298.                 numval += incr;
  299.                 argno = 1 - argno;
  300.                 *rp++ = '0' + (numval/10);
  301.                 *rp++ = '0' + (numval%10);
  302.                 break;
  303.  
  304.             case 'r' :
  305.                 argno = 1;
  306.                 break;
  307.             }
  308.  
  309.             break;
  310.         default :
  311.             *rp++ = *cm;
  312.         }
  313.     }
  314.     *rp = '\0';
  315.     return(ret);
  316. }
  317.  
  318. /*
  319.  *    tputs - put the string cp out onto the terminal, using the function
  320.  *    outc. This should do padding for the terminal, but I can't find a
  321.  *    terminal that needs padding at the moment...
  322.  */
  323. int
  324. tputs(cp, affcnt, outc)
  325. register char    *cp;
  326. int        affcnt;
  327. int        (*outc)();
  328. {
  329.     if (cp == NULL)
  330.         return(1);
  331.     /* do any padding interpretation - left null for MINIX just now */
  332.     while (*cp)
  333.         (*outc)(*cp++);
  334.     return(1);
  335. }
  336. #endif /* _VMS_POSIX */
  337.