diff options
Diffstat (limited to 'ex_get.c')
-rw-r--r-- | ex_get.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/ex_get.c b/ex_get.c new file mode 100644 index 0000000..f2325b9 --- /dev/null +++ b/ex_get.c @@ -0,0 +1,355 @@ +/* + * This code contains changes by + * Gunnar Ritter, Freiburg i. Br., Germany, 2002. All rights reserved. + * + * Conditions 1, 2, and 4 and the no-warranty notice below apply + * to these changes. + * + * + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef lint +#ifdef DOSCCS +static char sccsid[] = "@(#)ex_get.c 1.17 (gritter) 2/17/05"; +#endif +#endif + +/* from ex_get.c 7.6 (Berkeley) 6/7/85 */ + +#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; +int lastc = '\n'; + +void +ignchar(void) +{ + ignore(getchar()); +} + +int +getach(void) +{ + 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++&0377); + globp = 0; + return (lastc = EOF); + } +top: + if (input) { + if (c = *input++&0377) { + if (verbose && !intty) + write(2, &input[-1], 1); + if (c &= TRIM) + 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] = '\200'; +#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; +} + +int +getchar(void) +{ + register int c; + + do + c = getcd(); + while (!globp && c == CTRL('d')); + return (c); +} + +void +checkjunk(int c) +{ + + if (junkbs == 0 && c == '\b') { + write(2, cntrlhm, 13); + junkbs = 1; + } +} + +int +getcd(void) +{ + register int c; + +again: + c = getach(); + if (c == EOF) + return (c); + c &= TRIM; + if (!inopen) + if (!globp && c == CTRL('d')) + setlastchar('\n'); + else if (junk(c)) { + checkjunk(c); + goto again; + } + return (c); +} + +int +peekchar(void) +{ + + if (peekc == 0) + peekc = getchar(); + return (peekc); +} + +int +peekcd(void) +{ + if (peekc == 0) + peekc = getcd(); + return (peekc); +} + +/* + * 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. + */ +int +smunch(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); + } +} + +/* + * Input routine for insert/append/change in command mode. + * Most work here is in handling autoindent. + */ +static short lastin; + +int +gettty(void) +{ + register int c = 0; + register char *cp = genbuf; + char hadup = 0; + 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(catgets(catd, 1, 71, "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); +} + +void +setin(line *addr) +{ + + if (addr == zero) + lastin = 0; + else + getline(*addr), lastin = smunch(0, linebuf); +} |