home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / ex / ex_get.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  4KB  |  270 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "ex.h"
  3. #include "ex_tty.h"
  4.  
  5. /*
  6.  * Input routines for command mode.
  7.  * Since we translate the end of reads into the implied ^D's
  8.  * we have different flavors of routines which do/don't return such.
  9.  */
  10. static    bool junkbs;
  11. short    lastc = '\n';
  12.  
  13. ignchar()
  14. {
  15.     register int c;
  16.  
  17.     do
  18.         c = getcd();
  19.     while (c == CTRL(d));
  20. }
  21.  
  22. getchar()
  23. {
  24.     register int c;
  25.  
  26.     do
  27.         c = getcd();
  28.     while (c == CTRL(d));
  29.     return (c);
  30. }
  31.  
  32. getcd()
  33. {
  34.     register int c;
  35.  
  36. again:
  37.     c = getach();
  38.     if (c == EOF)
  39.         return (c);
  40.     c &= TRIM;
  41.     if (!inopen)
  42.         if (c == CTRL(d))
  43.             setlastchar('\n');
  44.         else if (junk(c)) {
  45.             checkjunk(c);
  46.             goto again;
  47.         }
  48.     return (c);
  49. }
  50.  
  51. peekchar()
  52. {
  53.  
  54.     if (peekc == 0)
  55.         peekc = getchar();
  56.     return (peekc);
  57. }
  58.  
  59. peekcd()
  60. {
  61.  
  62.     if (peekc == 0)
  63.         peekc = getcd();
  64.     return (peekc);
  65. }
  66.  
  67. getach()
  68. {
  69.     register int c;
  70.     static char inline[128];
  71.  
  72.     c = peekc;
  73.     if (c != 0) {
  74.         peekc = 0;
  75.         return (c);
  76.     }
  77.     if (globp) {
  78.         if (*globp)
  79.             return (*globp++);
  80.         globp = 0;
  81.         return (lastc = EOF);
  82.     }
  83. top:
  84.     if (input) {
  85.         if (c = *input++) {
  86.             if (c &= TRIM)
  87.                 return (lastc = c);
  88.             goto top;
  89.         }
  90.         input = 0;
  91.     }
  92.     flush();
  93.     if (intty) {
  94.         c = read(0, inline, sizeof inline - 4);
  95.         if (c < 0)
  96.             return (lastc = EOF);
  97.         if (c == 0 || inline[c-1] != '\n')
  98.             inline[c++] = CTRL(d);
  99.         if (inline[c-1] == '\n')
  100.             noteinp();
  101.         inline[c] = 0;
  102.         for (c--; c >= 0; c--)
  103.             if (inline[c] == 0)
  104.                 inline[c] = QUOTE;
  105.         input = inline;
  106.         goto top;
  107.     }
  108.     if (read(0, (char *) &lastc, 1) != 1)
  109.         lastc = EOF;
  110.     return (lastc);
  111. }
  112.  
  113. /*
  114.  * Input routine for insert/append/change in command mode.
  115.  * Most work here is in handling autoindent.
  116.  */
  117. static    short    lastin;
  118.  
  119. gettty()
  120. {
  121.     register int c = 0;
  122.     register char *cp = genbuf;
  123.     char hadup = 0;
  124.     int numbline();
  125.     extern int (*Pline)();
  126.     int offset = Pline == numbline ? 8 : 0;
  127.     int ch;
  128.  
  129.     if (intty && !inglobal) {
  130.         if (offset) {
  131.             holdcm = 1;
  132.             printf("  %4d  ", lineDOT() + 1);
  133.             flush();
  134.             holdcm = 0;
  135.         }
  136.         if (value(AUTOINDENT) ^ aiflag) {
  137.             holdcm = 1;
  138. #ifdef LISP
  139.             if (value(LISP))
  140.                 lastin = lindent(dot + 1);
  141. #endif
  142.             tab(lastin + offset);
  143.             while ((c = getcd()) == CTRL(d)) {
  144.                 if (lastin == 0 && isatty(0) == -1) {
  145.                     holdcm = 0;
  146.                     return (EOF);
  147.                 }
  148.                 lastin = backtab(lastin);
  149.                 tab(lastin + offset);
  150.             }
  151.             switch (c) {
  152.  
  153.             case '^':
  154.             case '0':
  155.                 ch = getcd();
  156.                 if (ch == CTRL(d)) {
  157.                     if (c == '0')
  158.                         lastin = 0;
  159.                     if (!OS) {
  160.                         putchar('\b' | QUOTE);
  161.                         putchar(' ' | QUOTE);
  162.                         putchar('\b' | QUOTE);
  163.                     }
  164.                     tab(offset);
  165.                     hadup = 1;
  166.                     c = getchar();
  167.                 } else
  168.                     ungetchar(ch);
  169.                 break;
  170.  
  171.             case '.':
  172.                 if (peekchar() == '\n') {
  173.                     ignchar();
  174.                     noteinp();
  175.                     holdcm = 0;
  176.                     return (EOF);
  177.                 }
  178.                 break;
  179.  
  180.             case '\n':
  181.                 hadup = 1;
  182.                 break;
  183.             }
  184.         }
  185.         flush();
  186.         holdcm = 0;
  187.     }
  188.     if (c == 0)
  189.         c = getchar();
  190.     while (c != EOF && c != '\n') {
  191.         if (cp > &genbuf[LBSIZE - 2])
  192.             error("Input line too long");
  193.         *cp++ = c;
  194.         c = getchar();
  195.     }
  196.     if (c == EOF) {
  197.         if (inglobal)
  198.             ungetchar(EOF);
  199.         return (EOF);
  200.     }
  201.     *cp = 0;
  202.     cp = linebuf;
  203.     if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) {
  204.         lastin = c = smunch(lastin, genbuf);
  205.         for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP))
  206.             *cp++ = '\t';
  207.         for (; c > 0; c--)
  208.             *cp++ = ' ';
  209.     }
  210.     CP(cp, genbuf);
  211.     if (linebuf[0] == '.' && linebuf[1] == 0)
  212.         return (EOF);
  213.     return (0);
  214. }
  215.  
  216. /*
  217.  * Crunch the indent.
  218.  * Hard thing here is that in command mode some of the indent
  219.  * is only implicit, so we must seed the column counter.
  220.  * This should really be done differently so as to use the whitecnt routine
  221.  * and also to hack indenting for LISP.
  222.  */
  223. smunch(col, ocp)
  224.     register int col;
  225.     char *ocp;
  226. {
  227.     register char *cp;
  228.  
  229.     cp = ocp;
  230.     for (;;)
  231.         switch (*cp++) {
  232.  
  233.         case ' ':
  234.             col++;
  235.             continue;
  236.  
  237.         case '\t':
  238.             col += value(TABSTOP) - (col % value(TABSTOP));
  239.             continue;
  240.  
  241.         default:
  242.             cp--;
  243.             CP(ocp, cp);
  244.             return (col);
  245.         }
  246. }
  247.  
  248. char    *cntrlhm =    "^H discarded\n";
  249.  
  250. checkjunk(c)
  251.     char c;
  252. {
  253.  
  254.     if (junkbs == 0 && c == '\b') {
  255.         write(2, cntrlhm, 13);
  256.         junkbs = 1;
  257.     }
  258. }
  259.  
  260. line *
  261. setin(addr)
  262.     line *addr;
  263. {
  264.  
  265.     if (addr == zero)
  266.         lastin = 0;
  267.     else
  268.         getline(*addr), lastin = smunch(0, linebuf);
  269. }
  270.