Subversion Repositories planix.SVN

Rev

Rev 115 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (c) 1980 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#if     !defined(lint) && defined(DOSCCS)
static char *sccsid = "@(#)ex_get.c     7.6 (Berkeley) 6/7/85";
#endif

#include "ex.h"
#include "ex_tty.h"

/*
 * Input routines for command mode.
 * Since we translate the end of reads into the implied ^D's
 * we have different flavors of routines which do/don't return such.
 */
static  bool junkbs;
short   lastc = '\n';

ignchar()
{
        ignore(getchar());
}

getchar()
{
        register int c;

        do
                c = getcd();
        while (!globp && c == CTRL('d'));
        return (c);
}

getcd()
{
        register int c;

again:
        c = getach();
        if (c == EOF)
                return (c);
#ifdef  ISO
        if (niso(c))
#endif
        c &= TRIM;
        if (!inopen)
                if (!globp && c == CTRL('d'))
                        setlastchar('\n');
                else if (junk(c)) {
                        checkjunk(c);
                        goto again;
                }
        return (c);
}

peekchar()
{

        if (peekc == 0)
                peekc = getchar();
        return (peekc);
}

peekcd()
{
        if (peekc == 0)
                peekc = getcd();
        return (peekc);
}

getach()
{
        register int c;
        static char in_line[BUFSIZ];
        struct stat statb;

        c = peekc;
        if (c != 0) {
                peekc = 0;
                return (c);
        }
        if (globp) {
                if (*globp)
                        return (*globp++);
                globp = 0;
                return (lastc = EOF);
        }
top:
        if (input) {
                if (c = *input++) {
#ifndef ISO
                        if (c &= TRIM)
#else
                        if (niso(c))
                                c &= TRIM;
                        if (c)
#endif
                                return (lastc = c);
                        goto top;
                }
                input = 0;
        }
        flush();
        if (intty) {
                c = read(0, in_line, sizeof in_line - 4);
                if (c < 0)
                        return (lastc = EOF);
                if (c == 0 || in_line[c-1] != '\n')
                        in_line[c++] = CTRL('d');
                if (in_line[c-1] == '\n')
                        noteinp();
                in_line[c] = 0;
                for (c--; c >= 0; c--)
                        if (in_line[c] == 0)
#ifndef BIT8
                                in_line[c] = QUOTE;
#else
                                in_line[c] = '_';
#endif
                input = in_line;
                goto top;
        }
        c = read(0, in_line, sizeof in_line - 1);
        if(c <= 0)
                return(lastc = EOF);
        in_line[c] = '\0';
        input = in_line;
        goto top;
}

/*
 * Input routine for insert/append/change in command mode.
 * Most work here is in handling autoindent.
 */
static  short   lastin;

gettty()
{
        register int c = 0;
        register char *cp = genbuf;
        char hadup = 0;
        int numbline();
        extern int (*Pline)();
        int offset = Pline == numbline ? 8 : 0;
        int ch;

        if (intty && !inglobal) {
                if (offset) {
                        holdcm = 1;
                        printf("  %4d  ", lineDOT() + 1);
                        flush();
                        holdcm = 0;
                }
                if (value(AUTOINDENT) ^ aiflag) {
                        holdcm = 1;
#ifdef LISPCODE
                        if (value(LISP))
                                lastin = lindent(dot + 1);
#endif
                        tab(lastin + offset);
                        while ((c = getcd()) == CTRL('d')) {
                                if (lastin == 0 && isatty(0) == -1) {
                                        holdcm = 0;
                                        return (EOF);
                                }
                                lastin = backtab(lastin);
                                tab(lastin + offset);
                        }
                        switch (c) {

                        case '^':
                        case '0':
                                ch = getcd();
                                if (ch == CTRL('d')) {
                                        if (c == '0')
                                                lastin = 0;
                                        if (!OS) {
                                                putchar('\b' | QUOTE);
                                                putchar(' ' | QUOTE);
                                                putchar('\b' | QUOTE);
                                        }
                                        tab(offset);
                                        hadup = 1;
                                        c = getchar();
                                } else
                                        ungetchar(ch);
                                break;

                        case '.':
                                if (peekchar() == '\n') {
                                        ignchar();
                                        noteinp();
                                        holdcm = 0;
                                        return (EOF);
                                }
                                break;

                        case '\n':
                                hadup = 1;
                                break;
                        }
                }
                flush();
                holdcm = 0;
        }
        if (c == 0)
                c = getchar();
        while (c != EOF && c != '\n') {
                if (cp > &genbuf[LBSIZE - 2])
                        error("Input line too long");
                *cp++ = c;
                c = getchar();
        }
        if (c == EOF) {
                if (inglobal)
                        ungetchar(EOF);
                return (EOF);
        }
        *cp = 0;
        cp = linebuf;
        if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) {
                lastin = c = smunch(lastin, genbuf);
                for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP))
                        *cp++ = '\t';
                for (; c > 0; c--)
                        *cp++ = ' ';
        }
        CP(cp, genbuf);
        if (linebuf[0] == '.' && linebuf[1] == 0)
                return (EOF);
        return (0);
}

/*
 * Crunch the indent.
 * Hard thing here is that in command mode some of the indent
 * is only implicit, so we must seed the column counter.
 * This should really be done differently so as to use the whitecnt routine
 * and also to hack indenting for LISP.
 */
smunch(col, ocp)
        register int col;
        char *ocp;
{
        register char *cp;

        cp = ocp;
        for (;;)
                switch (*cp++) {

                case ' ':
                        col++;
                        continue;

                case '\t':
                        col += value(TABSTOP) - (col % value(TABSTOP));
                        continue;

                default:
                        cp--;
                        CP(ocp, cp);
                        return (col);
                }
}

char    *cntrlhm =      "^H discarded\n";

checkjunk(c)
        char c;
{

        if (junkbs == 0 && c == '\b') {
                write(2, cntrlhm, 13);
                junkbs = 1;
        }
}

line *
setin(addr)
        line *addr;
{

        if (addr == zero)
                lastin = 0;
        else
                getline(*addr), lastin = smunch(0, linebuf);
}