home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 316 / libsrc / read.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  5.3 KB  |  321 lines

  1. /*
  2.  *        Cross Development System for Atari ST 
  3.  *     Copyright (c) 1988, Memorial University of Newfoundland
  4.  *
  5.  * $Header: read.c,v 1.2 88/02/03 22:56:30 m68k Exp $
  6.  *
  7.  * $Log:    read.c,v $
  8.  *
  9.  * 1.3        jrd
  10.  *
  11.  * Revision 1.2  88/02/03  22:56:30  m68k
  12.  * Added unix like tty driver stuff
  13.  * 
  14.  * Revision 1.1  88/01/29  17:31:39  m68k
  15.  * Initial revision
  16.  * 
  17.  */
  18. /* #include    <gembios.h>    ?? */
  19. #include    <osbind.h>
  20. #include    <ioctl.h>
  21. #include    <signal.h>
  22. #include    "tchars.h"
  23.  
  24. #define    iswhite(c)    ((c) == ' ' || (c) == '\t')
  25. #define    isvisable(c)    ((c) >= ' ' && (c) < 0x7f)
  26. #define    echochar(c)    if (__ttymode & ECHO) (void) _echochar(c); else
  27. #define    delchar(n)    if (__ttymode & ECHO) _delchar(n); else
  28.  
  29. # ifndef    NULL
  30. #  define    NULL    0
  31. # endif    /* NULL */
  32.  
  33. extern    void    _do_signal();
  34.  
  35. int        __col_pos = 0;
  36. static int    start_col;
  37. static char    *thebuf;
  38.  
  39. static    int    _echochar();
  40. static    void    _delchar();
  41.  
  42. int
  43. read(fd, buf, nbytes)
  44.     int    fd;
  45.     char    *buf;
  46.     int    nbytes;
  47. {
  48.     extern    int    errno;
  49. #ifdef DEBUG
  50.     char dbgbuf[64];
  51. #endif
  52.  
  53.  
  54.     int        rval;
  55.     int        cnt = 0;
  56.     char        *p = buf;
  57.  
  58.     if (!isatty(fd))
  59.         {
  60.         if ((rval = Fread(fd, nbytes, buf)) < 0) 
  61.             {
  62.             errno = rval;
  63.             rval = -1;
  64.             }
  65. #ifdef DEBUG
  66.     sprintf(dbgbuf, "read(%d, %X, %d)->%d\r\n", fd, buf, nbytes, rval);
  67.     dbgstr(dbgbuf);
  68. #endif
  69.         return rval;
  70.         }
  71.     thebuf = buf;
  72.     start_col = __col_pos;
  73.     while (1) {
  74.         *p = Bconin(2) & 0xff;
  75.         if (__ttymode & RAW) 
  76.             {
  77.             if (__ttymode & ECHO) 
  78.                 {
  79.                 Bconout(2, *p);
  80.                 if (*p == '\r')
  81.                     __col_pos = 0;
  82.                 else if (isvisable(*p))
  83.                     __col_pos++;
  84.                 }
  85.             if (++cnt >= nbytes || !(short)Bconstat(2))
  86.                 return cnt;
  87.             p++;
  88.             continue;
  89.             }
  90.         if ((__ttymode & CRMOD) && *p == '\r')
  91.             *p = '\n';
  92.         if (*p == __tchars[TC_INTRC]) 
  93.             {
  94.             /* Do the bsd thing here, i.e. flush buffers
  95.              * and continue to read after the interupt
  96.              */
  97.             echochar(*p);
  98.             p = buf;
  99.             cnt = 0;
  100.             _do_signal(SIGINT);
  101.             } 
  102.             else 
  103.         if (*p == __tchars[TC_QUITC]) 
  104.             {
  105.             echochar(*p);
  106.             p = buf;
  107.             cnt = 0;
  108.             _do_signal(SIGQUIT);
  109.             }
  110.         if (__ttymode & CBREAK) 
  111.             {
  112.             if (*p == __tchars[TC_LNEXTC])
  113.                 *p = Bconin(2);
  114.             if (__ttymode & ECHO) 
  115.                 {
  116.                 if (*p == '\n' && (__ttymode & CRMOD)) 
  117.                     {
  118.                     Bconout(2, '\n');
  119.                     Bconout(2, '\r');
  120.                     __col_pos = 0;
  121.                     } 
  122.                     else
  123.                     (void) _echochar(*p);
  124.                 }
  125.             ++cnt;
  126.             if (!(short) Bconstat(2))
  127.                 return cnt;
  128.             p++;
  129.             } 
  130.             else
  131.         if (*p == __tchars[TC_LNEXTC]) 
  132.             {
  133.             if (__ttymode & ECHO) 
  134.                 {
  135.                 Bconout(2, '^');
  136.                 Bconout(2, '\b');
  137.                 }
  138.             *p = Bconin(2);
  139.             echochar(*p++);
  140.             cnt++;
  141.             }
  142.             else
  143.         if (*p == __tchars[TC_EOFC]) 
  144.             {
  145.             if (__ttymode & ECHO)
  146.                 {
  147.                 int i = _echochar(*p);
  148.                 __col_pos -= i;
  149.                 while (i-- > 0)
  150.                     Bconout(2, '\b');
  151.                 }
  152.             return cnt;
  153.             }
  154.             else
  155.         if (*p == '\n' || *p == __tchars[TC_BRKC]) 
  156.             {
  157.             if (__ttymode & ECHO)
  158.                 if (*p == '\n')
  159.                     {
  160.                     Bconout(2, '\n');
  161.                     if (__ttymode & CRMOD) 
  162.                         {
  163.                         Bconout(2, '\r');
  164.                         __col_pos = 0;
  165.                         }
  166.                     }
  167.                     else
  168.                     (void) _echochar(*p);
  169.             return ++cnt;
  170.             }
  171.             else
  172.         if ((*p == __tchars[TC_ERASE]) || (*p == __tchars[TC_ERASE]))
  173.             {
  174.             if (cnt) 
  175.                 {
  176.                 p--;
  177.                 delchar(--cnt);
  178.                 }
  179.             }
  180.             else
  181.         if (*p == __tchars[TC_KILL]) 
  182.             {
  183.             while (--cnt >= 0) 
  184.                 {
  185.                 delchar(cnt);
  186.                 p--;
  187.                 }
  188.             cnt = 0;
  189.             } 
  190.             else
  191.         if (*p == __tchars[TC_WERASC]) 
  192.             {
  193.             p--;
  194.             while (cnt && iswhite(*p)) 
  195.                 {
  196.                 delchar(--cnt);
  197.                 p--;
  198.                 }
  199.             while (cnt && !iswhite(*p)) 
  200.                 {
  201.                 delchar(--cnt);
  202.                 p--;
  203.                 }
  204.             p++;
  205.             }
  206.             else
  207.         if (*p == __tchars[TC_RPRNTC]) 
  208.             {
  209.             char    *s;
  210.  
  211.             echochar(__tchars[TC_RPRNTC]);
  212.             Bconout(2, '\r');
  213.             Bconout(2, '\n');
  214.             __col_pos = 0;
  215.             start_col = 0;
  216.             if (__ttymode & ECHO)
  217.                 for (s = buf ; s < p ; s++)
  218.                     echochar(*s);
  219.             }
  220.             else
  221.             {
  222.             echochar(*p++);
  223.             cnt++;
  224.             }
  225.         if (cnt >= nbytes)
  226.             return cnt;
  227.     }
  228.     /*NOTREACHED*/
  229. }
  230.  
  231. static    int
  232. _echochar(c)
  233.     char    c;
  234. {
  235.     int    len = 0;
  236.  
  237.     if (c & 0x80) {
  238.         Bconout(2, 'M');
  239.         Bconout(2, '-');
  240.         c &= 0x7f;
  241.         len += 2;
  242.     }
  243.     if (c < ' ') {
  244.         if (c == '\t') {
  245.             int    i;
  246.  
  247.             len = ((__col_pos | 7) + 1) - __col_pos;
  248.             if (__ttymode & XTABS)
  249.                 for (i = len ; i-- ;)
  250.                     Bconout(2, ' ');
  251.             else
  252.                 Bconout(2, '\t');
  253.         } else {
  254.             Bconout(2, '^');
  255.             Bconout(2, c + 0x40);
  256.             len += 2;
  257.         }
  258.     } else if (c == 0x7f) {
  259.         Bconout(2, '^');
  260.         Bconout(2, '?');
  261.         len += 2;
  262.     } else {
  263.         Bconout(2, c);
  264.         len++;
  265.     }
  266.     __col_pos += len;
  267.     return len;
  268. }
  269.  
  270. static    void
  271. _delchar(n)
  272.     int    n;
  273. {
  274.     int    len;
  275.     char    c = thebuf[n];
  276.  
  277.     if (c & 0x80) {
  278.         len = 2;
  279.         c &= 0x7f;
  280.     } else
  281.         len = 0;
  282.     if (c < ' ' || c == 0x7f) {
  283.         if (c == '\t')
  284.             len = __col_pos - str_length(thebuf, n);
  285.         else
  286.             len += 2;
  287.     } else
  288.         len++;
  289.     __col_pos -= len;
  290.     while (len--) {
  291.         Bconout(2, '\b');
  292.         Bconout(2, ' ');
  293.         Bconout(2, '\b');
  294.     }
  295. }
  296.  
  297. static    int
  298. str_length(p, n)
  299.     char    *p;
  300.     int    n;
  301. {
  302.     int    pos = start_col;
  303.     char    c;
  304.  
  305.     while (n--) {
  306.         c = *p++;
  307.         if (c & 0x80) {
  308.             pos += 2;
  309.             c &= 0x7f;
  310.         }
  311.         if (c < ' ' || c == 0x7f)
  312.             if (c == '\t')
  313.                 pos = (pos | 7) + 1;
  314.             else
  315.                 pos += 2;
  316.         else
  317.             pos++;
  318.     }
  319.     return pos;
  320. }
  321.