home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / curses / tgetent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-23  |  9.6 KB  |  396 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1982, Fred Fish            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  *    This software and/or documentation is released for public    *
  7.  *    distribution for personal, non-commercial use only.        *
  8.  *    Limited rights to use, modify, and redistribute are hereby    *
  9.  *    granted for non-commercial purposes, provided that all        *
  10.  *    copyright notices remain intact and all changes are clearly    *
  11.  *    documented.  The author makes no warranty of any kind with    *
  12.  *    respect to this product and explicitly disclaims any implied    *
  13.  *    warranties of merchantability or fitness for any particular    *
  14.  *    purpose.                            *
  15.  *                                    *
  16.  ************************************************************************
  17.  */
  18.  
  19.  
  20. /*
  21.  *  LIBRARY FUNCTION
  22.  *
  23.  *    tgetent   load buffer with entry for specified terminal
  24.  *
  25.  *  KEY WORDS
  26.  *
  27.  *    termcap functions
  28.  *    utility routines
  29.  *
  30.  *  SYNOPSIS
  31.  *
  32.  *    int tgetent(bp,name)
  33.  *    char *bp;
  34.  *    char *name;
  35.  *
  36.  *  DESCRIPTION
  37.  *
  38.  *    Extracts the entry for terminal <name> from the termcap file
  39.  *    and places it in the character buffer <bp>.   It is currently
  40.  *    assumed that bp is at least 1024 characters.  If the entry in
  41.  *    the termcap file is larger than 1023 characters the excess
  42.  *    characters will be discarded and appropriate status will
  43.  *    be returned.
  44.  *
  45.  *    Also note that since bp is used by other termcap
  46.  *    routines, the storage associated with the termcap entry
  47.  *    cannot be freed until all termcap calls are completed.
  48.  *
  49.  *    Tgetent can be directed to look in a file other than
  50.  *    the default (/etc/termcap) by defining an environment
  51.  *    variable called TERMCAP to be the pathname of the desired
  52.  *    termcap file.  This is useful for debugging new entries.
  53.  *    NOTE: the pathname MUST begin with a '/' character.
  54.  *      (Atari ST specific change: the pathname may begin with '\',
  55.  *       or with a drive letter followed by ':').
  56.  *
  57.  *    Also, if the string assigned to TERMCAP does not begin with
  58.  *    a '/' and if the environment variable TERM matches <name> then
  59.  *    the string assigned to TERMCAP is copied to buffer <bp> 
  60.  *    instead of reading a termcap file.
  61.  *      (Atari ST specific change: TERM is no longer checked (the
  62.  *       check was buggy).
  63.  *
  64.  *    Modification by ERS: if no termcap file can be found, then
  65.  *    a default termcap is used (this is for GEMDOS).
  66.  *    
  67.  *  RETURNS
  68.  *
  69.  *    -1  if the termcap file cannot be opened
  70.  *     0  if no entry in termcap file matches <name>
  71.  *     1  if extraction is successful with no errors
  72.  *     2  if extraction is successful but entry truncated
  73.  *
  74.  *  SEE ALSO
  75.  *
  76.  *    tgetnum   extract numeric type capability
  77.  *    tgetflag  test boolean type capability
  78.  *    tgetstr   get string value of capability
  79.  *
  80.  *  AUTHOR
  81.  *
  82.  *    Fred Fish
  83.  *
  84.  */
  85.  
  86. #include <stdio.h>
  87. #include <string.h>
  88. #include <termcap.h>
  89.  
  90. #ifndef _COMPILER_H
  91. #  include <compiler.h>
  92. #endif
  93.  
  94. #define TRUE 1
  95. #define FALSE 0
  96. #define BUFSIZE 1024            /* Assumed size of external buffer */
  97.  
  98. #define NO_FILE     -1            /* Returned if can't open file */
  99. #define NO_ENTRY  0            /* Returned if can't find entry */
  100. #define SUCCESS   1            /* Returned if entry found ok */
  101. #define TRUNCATED 2            /* Returned if entry found but trunc */
  102.  
  103. # ifdef DGK
  104. # define DEFAULT_ROOT "termcap"        /* name without path component */
  105.   static FILE *fopenp __PROTO((char *name, char *mode, char *pathname));
  106. # define DEFAULT_FILE "\\etc\\termcap"
  107. # else
  108. # define DEFAULT_FILE "/etc/termcap"    /* default termcap filename */
  109. # endif
  110. __EXTERN char *fgetlr __PROTO((char *bp, int bpsize, FILE *fp));
  111. static FILE *find_file __PROTO((char *));
  112. static int gotcha __PROTO((char *bp, char *name));
  113.  
  114. char *_tcpbuf;                /* Place to remember buffer pointer */
  115.  
  116. /*
  117.  *  PSEUDO CODE
  118.  *
  119.  *    Begin tgetent
  120.  *        Erase any previous buffer contents.
  121.  *        Remember the buffer pointer.
  122.  *        If termcap file is not found then
  123.  *        If buffer was filled anyway then
  124.  *            Return SUCCESS.
  125.  *        Else
  126.  *            Return NO_FILE.
  127.  *        End if
  128.  *        Else
  129.  *        While records left to process
  130.  *            If this is entry is what we want then
  131.  *            Close the termcap file.
  132.  *            If entry was truncated then
  133.  *                Return TRUNCATED status
  134.  *            Else
  135.  *                Return SUCCESS status.
  136.  *            End if
  137.  *            End if
  138.  *        End while
  139.  *        Return NO_ENTRY status.
  140.  *        End if
  141.  *    End tgetent
  142.  *            
  143.  */
  144.  
  145. int tgetent(bp,name)
  146. char *bp;                /* Pointer to buffer (1024 char min) */
  147. char *name;                /* Pointer to terminal entry to find */
  148. {
  149.     FILE *fp;
  150.  
  151.     *bp = '\0';
  152.     _tcpbuf = bp;
  153.     if ((fp = find_file(bp)) == NULL) {
  154.     if (*bp != '\0') {
  155.         return(SUCCESS);
  156.     } else {
  157.         return(NO_FILE);
  158.     }
  159.     } else {
  160.     while (fgetlr(bp,BUFSIZE,fp)) {
  161.         if (gotcha(bp,name)) {
  162.         fclose(fp);
  163.         if (bp[(int)strlen(bp)-1] != '\n') {
  164.             return(TRUNCATED);
  165.         } else {
  166.             return(SUCCESS);
  167.         }
  168.         }
  169.     }
  170.     return(NO_ENTRY);
  171.     }
  172. }
  173.  
  174. /*
  175.  *  INTERNAL FUNCTION
  176.  *
  177.  *    find_file    find the termcap file and open it if possible
  178.  *
  179.  *  KEY WORDS
  180.  *
  181.  *    internal functions
  182.  *    find_file
  183.  *
  184.  *  SYNOPSIS
  185.  *
  186.  *    static FILE *find_file(bp)
  187.  *    char *bp;
  188.  *
  189.  *  DESCRIPTION
  190.  *
  191.  *    Attempts to locate and open the termcap file.  Also handles
  192.  *    using the environment TERMCAP string as the actual buffer
  193.  *    (that's why bp has to be an input parameter).
  194.  *
  195.  *    If TERMCAP is defined an begins with a '/' character then
  196.  *    it is taken to be the pathname of the termcap file and
  197.  *    an attempt is made to open it.  If this fails then
  198.  *    the default termcap file is used instead.
  199.  *
  200.  *    If TERMCAP is defined but does not begin with a '/' then
  201.  *    it is assumed to be the actual buffer contents provided
  202.  *    that <name> matches the environment variable TERM.
  203.  *
  204.  *  BUGS
  205.  *
  206.  *    There is currently no way to be sure which termcap
  207.  *    file was opened since the default will always be
  208.  *    tried.
  209.  *
  210.  */
  211.  
  212. /*
  213.  *  PSEUDO CODE
  214.  *
  215.  *    Begin find_file
  216.  *        If there is a TERMCAP environment string then
  217.  *        If the string is not null then
  218.  *            If the string is a pathname then
  219.  *            If that file is opened successfully then
  220.  *                Return its pointer.
  221.  *            End if
  222.  *            Else
  223.  *            If there is a TERM environment string then
  224.  *                If TERM matches <name> then
  225.  *                Copy TERMCAP string to buffer.
  226.  *                Return NULL for no file.
  227.  *                End if
  228.  *            End if
  229.  *            End if
  230.  *        End if
  231.  *        End if
  232.  *        Open default termcap file and return results.
  233.  *    End find_file
  234.  *
  235.  */
  236.  
  237. static char term_default[] = "df|default|Atari default\
  238. :al=\\EL:am:bs:cd=\\EJ:ce=\\EK:cl=\\EE:cm=\\EY%+ %+ :co#80:dl=\\EM\
  239. :do=\\EB:eo:ho=\\EH:is=\\Eq\\EE\\Ee\\Ev:it#8:le=^H:li#25:ll=\\EY9!\
  240. :me=\\Eq:mr=\\Ep:nd=\\EC:rc=\\Ek:sc=\\Ej:se=\\Eq:so=\\Ep:ta=^I\
  241. :up=\\EA:ve=\\Ee:vi=\\Ef:";
  242.  
  243. static FILE *find_file(bp)
  244. char *bp;
  245. {
  246.     FILE *fp;
  247.     char *cp, *ncp;
  248.     __EXTERN char *getenv __PROTO((const char *));
  249.  
  250.     if ((cp = getenv("TERMCAP")) != NULL) {
  251.     if (*cp != '\0') {
  252.         if (*cp == '/' || *cp == '\\' || (cp[1] == ':')) {
  253.         if ((fp = fopen(cp,"r")) != NULL) {
  254.             return(fp);
  255.         }
  256.         } else {
  257.         if ((ncp = getenv("TERM")) != NULL) {
  258.             strcpy(bp,cp);
  259.             return((FILE *)NULL);
  260.         }
  261.         }
  262.     }
  263.     }
  264. # ifdef DGK
  265.     /* Try current directory, then /etc/termcap, then along the path
  266.      */
  267.     if (fp = fopen(DEFAULT_ROOT, "r"))
  268.         return fp;
  269.     else if (fp = fopen(DEFAULT_FILE, "r"))
  270.         return fp;
  271.     else if (fp = fopenp(DEFAULT_ROOT, "r", NULL))
  272.         return fp;
  273.     else {
  274. #  ifdef GEMDOS
  275.         strcpy (bp, term_default);
  276. #  endif
  277.         return (FILE *) NULL;
  278.     }
  279. # else
  280.     return(fopen(DEFAULT_FILE,"r"));
  281. # endif
  282. }
  283.  
  284. /*
  285.  *  INTERNAL FUNCTION
  286.  *
  287.  *    gotcha   test to see if entry is for specified terminal
  288.  *
  289.  *  SYNOPSIS
  290.  *
  291.  *    gotcha(bp,name)
  292.  *    char *bp;
  293.  *    char *name;
  294.  *
  295.  *  DESCRIPTION
  296.  *
  297.  *    Tests to see if the entry in buffer bp matches the terminal
  298.  *    specified by name.  Returns TRUE if match is detected, FALSE
  299.  *    otherwise.
  300.  *
  301.  */
  302.  
  303. /*
  304.  *  PSEUDO CODE
  305.  *
  306.  *    Begin gotcha
  307.  *        If buffer character is comment character then
  308.  *        Return FALSE since remainder is comment
  309.  *        Else
  310.  *        Initialize name scan pointer.
  311.  *        Compare name and buffer until end or mismatch.
  312.  *        If valid terminators for both name and buffer strings
  313.  *            Return TRUE since a match was found.
  314.  *        Else
  315.  *            Find next non-name character in buffer.
  316.  *            If not an alternate name separater character
  317.  *            Return FALSE since no more names to check.
  318.  *            Else
  319.  *            Test next name and return results.
  320.  *            End if
  321.  *        End if
  322.  *        End if
  323.  *    End gotcha
  324.  *
  325.  */
  326.  
  327. static int gotcha(bp,name)
  328. char *bp;
  329. char *name;
  330. {
  331.     char *np;
  332.  
  333.     if (*bp == '#') {
  334.     return(FALSE);
  335.     } else {
  336.     np = name;
  337.     while (*np == *bp && *np != '\0') {np++; bp++;}
  338.     if (*np == '\0' && (*bp == '\0' || *bp == '|' || *bp == ':')) {
  339.         return(TRUE);
  340.     } else {
  341.         while (*bp != '\0' && *bp != ':' && *bp != '|') {bp++;}
  342.         if (*bp != '|') {
  343.         return(FALSE);
  344.         } else {
  345.         return(gotcha(++bp,name));
  346.         }
  347.     }
  348.     }
  349. }
  350.  
  351. #ifdef DGK
  352. # ifdef MSDOS
  353. # define PATHSEP ';'
  354. # endif
  355. # ifdef GEMDOS
  356. # define PATHSEP ','
  357. # endif
  358.  
  359. /* Follow the PATH, trying to fopen the file.  Takes one additional
  360.  * argument which can be NULL.  Otherwise this argument gets filled
  361.  * in the full path to the file.  Returns as does fopen().
  362.  */
  363. static FILE *
  364. fopenp(name, mode, pathname)
  365. char *name, *mode, *pathname;
  366. {
  367.     char buffer[BUFSIZ], *buf, *bufp, *pathp, lastch;
  368.     FILE *fp;
  369.     __EXTERN char *getenv __PROTO((const char *));
  370.  
  371.     /* If pathname is given, use it instead of buf so the calling
  372.      * process knows the path we found name under
  373.      */
  374.     if (pathname)
  375.         buf = pathname;
  376.     else
  377.         buf = buffer;
  378.  
  379.     strcpy(buf, name);
  380.     pathp = getenv("PATH");
  381.     while (pathp && *pathp) {
  382.         bufp = buf;
  383.         while (*pathp && *pathp != PATHSEP)
  384.             lastch = *bufp++ = *pathp++;
  385.         if (lastch != '\\')
  386.             *bufp++ = '\\';
  387.         strcpy(bufp, name);
  388.         if (fp = fopen(buf, mode))
  389.             return fp;
  390.         if (*pathp)
  391.             pathp++;
  392.     }
  393.     return NULL;
  394. }
  395. #endif
  396.