summaryrefslogtreecommitdiff
path: root/ex_get.c
diff options
context:
space:
mode:
Diffstat (limited to 'ex_get.c')
-rw-r--r--ex_get.c355
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);
+}