home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / crssrc16 / tgetstr.c < prev    next >
C/C++ Source or Header  |  1993-07-29  |  6KB  |  289 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.  *    tgetstr   extract string capability from termcap entry
  24.  *
  25.  *  KEY WORDS
  26.  *
  27.  *    termcap
  28.  *
  29.  *  SYNOPSIS
  30.  *
  31.  *    char *tgetstr(id,area)
  32.  *    char *id;
  33.  *    char **area;
  34.  *
  35.  *  DESCRIPTION
  36.  *
  37.  *    Gets the string capability for <id>, placing it in
  38.  *    the buffer at *area, and advancing *area to point
  39.  *    to next available storage.
  40.  *
  41.  *    For example, if the following capabilities are
  42.  *    in the termcap file:
  43.  *
  44.  *        ZZ=zzzz
  45.  *        YY=yyyyyy
  46.  *        WW=www
  47.  *
  48.  *    then successive calls using YY, ZZ, and WW will
  49.  *    build the following buffer:
  50.  *
  51.  *        yyyyyy0zzzz0www0
  52.  *
  53.  *    The first call will return a pointer to yyyyyy, the
  54.  *    second will return a pointer to zzzz and the third
  55.  *    will return a pointer to www.  Note that each
  56.  *    string is null terminated, as are all C strings.
  57.  *
  58.  *    Characters preceded by the carot character (\136)
  59.  *    are mapped into the corresponding control character.
  60.  *    For example, the two character sequence ^A becomes
  61.  *    a single control-A (\001) character.
  62.  *
  63.  *    The escape character is the normal C backslash and
  64.  *    the normal C escape sequences are recognized, along
  65.  *    with a special sequence for the ASCII escape character
  66.  *    (\033).  The recognized sequences are:
  67.  *
  68.  *        \E   =>  '\033'  (ASCII escape character)
  69.  *        \b   =>  '\010'  (ASCII backspace character)
  70.  *        \f   =>  '\014'  (ASCII form feed character)
  71.  *        \n   =>  '\012'  (ASCII newline/linefeed char)
  72.  *        \r   =>  '\015'  (ASCII carriage return char)
  73.  *        \t   =>  '\011'  (ASCII tab character)
  74.  *        \ddd =>  '\ddd'  (arbitrary ASCII digit)
  75.  *        \x   =>  'x'     (ordinary ASCII character)
  76.  *
  77.  */
  78.  
  79. #include <stdio.h>
  80. #include <ctype.h>
  81. #include <string.h>
  82. #include <termcap.h>
  83.  
  84. #ifndef _COMPILER_H
  85. #  include <compiler.h>
  86. #endif
  87.  
  88. # ifdef MSDOS
  89. # define index strchr
  90. # endif
  91.  
  92. extern char *_tcpbuf;        /* Termcap entry buffer pointer */
  93. static char *decode __PROTO((char *bp, char **area));
  94. static char *do_esc __PROTO((char *out, char *in));
  95.  
  96.  
  97. /*
  98.  *  PSEUDO CODE
  99.  *
  100.  *    Begin tgetstr
  101.  *        Initialize pointer to the termcap entry buffer.
  102.  *        While there is a field to process
  103.  *        Skip over the field separator character.
  104.  *        If this is the entry we want then
  105.  *            If the entry is not a string then
  106.  *            Return NULL.
  107.  *            Else
  108.  *            Transfer string and rtn pointer.
  109.  *            End if
  110.  *        End if
  111.  *        End while
  112.  *        Return NULL
  113.  *    End tgetstr
  114.  *
  115.  */
  116.  
  117. char *tgetstr(id,area)
  118. char *id;
  119. char **area;
  120. {
  121.     char *bp;
  122.  
  123.     bp = _tcpbuf;
  124.     while ((bp = index(bp,':')) != NULL) {
  125.     bp++;
  126.     if (*bp++ == id[0] && *bp != '\0' && *bp++ == id[1]) {
  127.         if (*bp != '\0' && *bp++ != '=') {
  128.         return(NULL);
  129.         } else {
  130.         return(decode(bp,area));
  131.         }
  132.     }
  133.     }
  134.     return(NULL);
  135. }
  136.  
  137. /*
  138.  *  INTERNAL FUNCTION
  139.  *
  140.  *    decode   transfer string capability, decoding escapes
  141.  *
  142.  *  SYNOPSIS
  143.  *
  144.  *    static char *decode(bp,area)
  145.  *    char *bp;
  146.  *    char **area;
  147.  *
  148.  *  DESCRIPTION
  149.  *
  150.  *    Transfers the string capability, up to the next ':'
  151.  *    character, or null, to the buffer pointed to by
  152.  *    the pointer in *area.  Note that the initial
  153.  *    value of *area and *area is updated to point
  154.  *    to the next available location after the null
  155.  *    terminating the transfered string.
  156.  *
  157.  *  BUGS
  158.  *
  159.  *    There is no overflow checking done on the destination
  160.  *    buffer, so it better be large enough to hold
  161.  *    all expected strings.
  162.  *
  163.  */
  164.  
  165. /*
  166.  *  PSEUDO CODE
  167.  *
  168.  *    Begin decode
  169.  *        Initialize the transfer pointer.
  170.  *        While there is an input character left to process
  171.  *        Switch on input character
  172.  *        Case ESCAPE:
  173.  *            Decode and xfer the escaped sequence.
  174.  *            Break
  175.  *        Case CONTROLIFY:
  176.  *            Controlify and xfer the next character.
  177.  *            Advance the buffer pointer.
  178.  *            Break
  179.  *        Default:
  180.  *            Xfer a normal character.
  181.  *        End switch
  182.  *        End while
  183.  *        Null terminate the output string.
  184.  *        Remember where the output string starts.
  185.  *        Update the output buffer pointer.
  186.  *        Return pointer to the output string.
  187.  *    End decode
  188.  *
  189.  */
  190.  
  191. static char *decode(bp,area)
  192. char *bp;
  193. char **area;
  194. {
  195.     char *cp, *bgn;
  196.  
  197.     cp = *area;
  198.     while (*bp != '\0' && *bp != ':') {
  199.     switch(*bp) {
  200.     case '\\':
  201.         bp = do_esc(cp++,++bp);
  202.         break;
  203.     case '^':
  204.         *cp++ = *++bp & 037;
  205.         bp++;
  206.         break;
  207.     default:
  208.         *cp++ = *bp++;
  209.         break;
  210.     }
  211.     }
  212.     *cp++ = '\0';
  213.     bgn = *area;
  214.     *area = cp;
  215.     return(bgn);
  216. }
  217.  
  218. /*
  219.  *  INTERNAL FUNCTION
  220.  *
  221.  *    do_esc    process an escaped sequence
  222.  *
  223.  *  SYNOPSIS
  224.  *
  225.  *    char *do_esc(out,in);
  226.  *    char *out;
  227.  *    char *in;
  228.  *
  229.  *  DESCRIPTION
  230.  *
  231.  *    Processes an escape sequence pointed to by
  232.  *    in, transfering it to location pointed to
  233.  *    by out, and updating the pointer to in.
  234.  *
  235.  */
  236.  
  237. /*
  238.  *  PSEUDO CODE
  239.  *
  240.  *    Begin do_esc
  241.  *        If the first character is not a NULL then
  242.  *        If is a digit then
  243.  *            Set value to zero.
  244.  *            For up to 3 digits
  245.  *                Accumulate the sum.
  246.  *            End for
  247.  *            Transfer the sum.
  248.  *            Else if character is in remap list then
  249.  *            Transfer the remapped character.
  250.  *            Advance the input pointer once.
  251.  *            Else
  252.  *            Simply transfer the character.
  253.  *            End if
  254.  *        End if
  255.  *        Return updated input pointer.
  256.  *    End do_esc
  257.  *
  258.  */
  259.  
  260. static char *maplist = {
  261.     "E\033b\bf\fn\nr\rt\t"
  262. };
  263.  
  264. static char *do_esc(out,in)
  265. char *out;
  266. char *in;
  267. {
  268.     int count;
  269.     char ch;
  270.     char *cp;
  271.  
  272.     if (*in != '\0') {
  273.     if (isdigit(*in)) {
  274.         ch = 0;
  275.         for (count = 0; count < 3 && isdigit(*in); in++) {
  276.          ch <<= 3;
  277.          ch |= (*in - '0');
  278.         }
  279.         *out++ = ch;
  280.     } else if ((cp = index(maplist,*in)) != NULL) {
  281.         *out++ = *++cp;
  282.         in++;
  283.     } else {
  284.         *out++ = *in++;
  285.     }
  286.     }
  287.     return(in);
  288. }
  289.