/* * 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); }