17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*23a1cceaSRoger A. Faulkner * Common Development and Distribution License (the "License").
6*23a1cceaSRoger A. Faulkner * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21*23a1cceaSRoger A. Faulkner
22f6db9f27Scf46844 /*
23*23a1cceaSRoger A. Faulkner * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24f6db9f27Scf46844 */
25f6db9f27Scf46844
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include "ex.h"
337c478bd9Sstevel@tonic-gate #include "ex_tty.h"
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate * Input routines for command mode.
377c478bd9Sstevel@tonic-gate * Since we translate the end of reads into the implied ^D's
387c478bd9Sstevel@tonic-gate * we have different flavors of routines which do/don't return such.
397c478bd9Sstevel@tonic-gate */
407c478bd9Sstevel@tonic-gate static bool junkbs;
417c478bd9Sstevel@tonic-gate short lastc = '\n';
427c478bd9Sstevel@tonic-gate
43f6db9f27Scf46844 void
ignchar(void)44f6db9f27Scf46844 ignchar(void)
457c478bd9Sstevel@tonic-gate {
467c478bd9Sstevel@tonic-gate (void)getchar();
477c478bd9Sstevel@tonic-gate }
487c478bd9Sstevel@tonic-gate
49f6db9f27Scf46844 int
getchar(void)50f6db9f27Scf46844 getchar(void)
517c478bd9Sstevel@tonic-gate {
52f6db9f27Scf46844 int c;
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate do
557c478bd9Sstevel@tonic-gate c = getcd();
567c478bd9Sstevel@tonic-gate while (!globp && c == CTRL('d'));
577c478bd9Sstevel@tonic-gate return (c);
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate
60f6db9f27Scf46844 int
getcd(void)61f6db9f27Scf46844 getcd(void)
627c478bd9Sstevel@tonic-gate {
63f6db9f27Scf46844 int c;
647c478bd9Sstevel@tonic-gate extern short slevel;
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate again:
677c478bd9Sstevel@tonic-gate c = getach();
687c478bd9Sstevel@tonic-gate if (c == EOF)
697c478bd9Sstevel@tonic-gate return (c);
707c478bd9Sstevel@tonic-gate if (!inopen && slevel==0)
717c478bd9Sstevel@tonic-gate if (!globp && c == CTRL('d'))
727c478bd9Sstevel@tonic-gate setlastchar('\n');
737c478bd9Sstevel@tonic-gate else if (junk(c)) {
747c478bd9Sstevel@tonic-gate checkjunk(c);
757c478bd9Sstevel@tonic-gate goto again;
767c478bd9Sstevel@tonic-gate }
777c478bd9Sstevel@tonic-gate return (c);
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate
80f6db9f27Scf46844 int
peekchar(void)81f6db9f27Scf46844 peekchar(void)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate if (peekc == 0)
857c478bd9Sstevel@tonic-gate peekc = getchar();
867c478bd9Sstevel@tonic-gate return (peekc);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate
89f6db9f27Scf46844 int
peekcd(void)90f6db9f27Scf46844 peekcd(void)
917c478bd9Sstevel@tonic-gate {
927c478bd9Sstevel@tonic-gate if (peekc == 0)
937c478bd9Sstevel@tonic-gate peekc = getcd();
947c478bd9Sstevel@tonic-gate return (peekc);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate int verbose;
98f6db9f27Scf46844 int
getach(void)99f6db9f27Scf46844 getach(void)
1007c478bd9Sstevel@tonic-gate {
101f6db9f27Scf46844 int c, i, prev;
1027c478bd9Sstevel@tonic-gate static unsigned char inputline[128];
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate c = peekc;
1057c478bd9Sstevel@tonic-gate if (c != 0) {
1067c478bd9Sstevel@tonic-gate peekc = 0;
1077c478bd9Sstevel@tonic-gate return (c);
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate if (globp) {
1107c478bd9Sstevel@tonic-gate if (*globp)
1117c478bd9Sstevel@tonic-gate return (*globp++);
1127c478bd9Sstevel@tonic-gate globp = 0;
1137c478bd9Sstevel@tonic-gate return (lastc = EOF);
1147c478bd9Sstevel@tonic-gate }
1157c478bd9Sstevel@tonic-gate top:
1167c478bd9Sstevel@tonic-gate if (input) {
1177c478bd9Sstevel@tonic-gate if(c = *input++)
1187c478bd9Sstevel@tonic-gate return (lastc = c);
1197c478bd9Sstevel@tonic-gate input = 0;
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate flush();
1227c478bd9Sstevel@tonic-gate if (intty) {
1237c478bd9Sstevel@tonic-gate c = read(0, inputline, sizeof inputline - 4);
1247c478bd9Sstevel@tonic-gate if (c < 0)
1257c478bd9Sstevel@tonic-gate return (lastc = EOF);
1267c478bd9Sstevel@tonic-gate if (c == 0 || inputline[c-1] != '\n')
1277c478bd9Sstevel@tonic-gate inputline[c++] = CTRL('d');
1287c478bd9Sstevel@tonic-gate if (inputline[c-1] == '\n')
1297c478bd9Sstevel@tonic-gate noteinp();
1307c478bd9Sstevel@tonic-gate prev = 0;
1317c478bd9Sstevel@tonic-gate /* remove nulls from input buffer */
1327c478bd9Sstevel@tonic-gate for (i = 0; i < c; i++)
1337c478bd9Sstevel@tonic-gate if(inputline[i] != 0)
1347c478bd9Sstevel@tonic-gate inputline[prev++] = inputline[i];
1357c478bd9Sstevel@tonic-gate inputline[prev] = 0;
1367c478bd9Sstevel@tonic-gate input = inputline;
1377c478bd9Sstevel@tonic-gate goto top;
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate if (read(0, inputline, 1) != 1)
1407c478bd9Sstevel@tonic-gate lastc = EOF;
1417c478bd9Sstevel@tonic-gate else {
1427c478bd9Sstevel@tonic-gate lastc = inputline[0];
1437c478bd9Sstevel@tonic-gate if (verbose)
1447c478bd9Sstevel@tonic-gate write(2, inputline, 1);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate return (lastc);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate * Input routine for insert/append/change in command mode.
1517c478bd9Sstevel@tonic-gate * Most work here is in handling autoindent.
1527c478bd9Sstevel@tonic-gate */
1537c478bd9Sstevel@tonic-gate static short lastin;
1547c478bd9Sstevel@tonic-gate
155f6db9f27Scf46844 int
gettty(void)156f6db9f27Scf46844 gettty(void)
1577c478bd9Sstevel@tonic-gate {
158f6db9f27Scf46844 int c = 0;
159f6db9f27Scf46844 unsigned char *cp = genbuf;
1607c478bd9Sstevel@tonic-gate unsigned char hadup = 0;
1617c478bd9Sstevel@tonic-gate extern int (*Pline)();
1627c478bd9Sstevel@tonic-gate int offset = Pline == numbline ? 8 : 0;
1637c478bd9Sstevel@tonic-gate int ch;
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate if (intty && !inglobal) {
1667c478bd9Sstevel@tonic-gate if (offset) {
1677c478bd9Sstevel@tonic-gate holdcm = 1;
168f6db9f27Scf46844 viprintf(" %4d ", lineDOT() + 1);
1697c478bd9Sstevel@tonic-gate flush();
1707c478bd9Sstevel@tonic-gate holdcm = 0;
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate if (value(vi_AUTOINDENT) ^ aiflag) {
1737c478bd9Sstevel@tonic-gate holdcm = 1;
1747c478bd9Sstevel@tonic-gate if (value(vi_LISP))
1757c478bd9Sstevel@tonic-gate lastin = lindent(dot + 1);
1767c478bd9Sstevel@tonic-gate gotab(lastin + offset);
1777c478bd9Sstevel@tonic-gate while ((c = getcd()) == CTRL('d')) {
1787c478bd9Sstevel@tonic-gate if (lastin == 0 && isatty(0) == -1) {
1797c478bd9Sstevel@tonic-gate holdcm = 0;
1807c478bd9Sstevel@tonic-gate return (EOF);
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate lastin = backtab(lastin);
1837c478bd9Sstevel@tonic-gate gotab(lastin + offset);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate switch (c) {
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate case '^':
1887c478bd9Sstevel@tonic-gate case '0':
1897c478bd9Sstevel@tonic-gate ch = getcd();
1907c478bd9Sstevel@tonic-gate if (ch == CTRL('d')) {
1917c478bd9Sstevel@tonic-gate if (c == '0')
1927c478bd9Sstevel@tonic-gate lastin = 0;
1937c478bd9Sstevel@tonic-gate if (!over_strike) {
1947c478bd9Sstevel@tonic-gate putchar((int)('\b' | QUOTE));
1957c478bd9Sstevel@tonic-gate putchar((int)(' ' | QUOTE));
1967c478bd9Sstevel@tonic-gate putchar((int)('\b' | QUOTE));
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate gotab(offset);
1997c478bd9Sstevel@tonic-gate hadup = 1;
2007c478bd9Sstevel@tonic-gate c = getchar();
2017c478bd9Sstevel@tonic-gate } else
2027c478bd9Sstevel@tonic-gate ungetchar(ch);
2037c478bd9Sstevel@tonic-gate break;
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate case '.':
2067c478bd9Sstevel@tonic-gate if (peekchar() == '\n') {
2077c478bd9Sstevel@tonic-gate ignchar();
2087c478bd9Sstevel@tonic-gate noteinp();
2097c478bd9Sstevel@tonic-gate holdcm = 0;
2107c478bd9Sstevel@tonic-gate return (EOF);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate break;
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate case '\n':
2157c478bd9Sstevel@tonic-gate hadup = 1;
2167c478bd9Sstevel@tonic-gate break;
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate flush();
2207c478bd9Sstevel@tonic-gate holdcm = 0;
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate if (c == 0)
2237c478bd9Sstevel@tonic-gate c = getchar();
2247c478bd9Sstevel@tonic-gate while (c != EOF && c != '\n') {
2257c478bd9Sstevel@tonic-gate if (cp > &genbuf[LBSIZE - 2])
2267c478bd9Sstevel@tonic-gate error(gettext("Input line too long"));
2277c478bd9Sstevel@tonic-gate *cp++ = c;
2287c478bd9Sstevel@tonic-gate c = getchar();
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate if (c == EOF) {
2317c478bd9Sstevel@tonic-gate if (inglobal)
2327c478bd9Sstevel@tonic-gate ungetchar(EOF);
2337c478bd9Sstevel@tonic-gate return (EOF);
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate *cp = 0;
2367c478bd9Sstevel@tonic-gate cp = linebuf;
2377c478bd9Sstevel@tonic-gate if ((value(vi_AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) {
2387c478bd9Sstevel@tonic-gate lastin = c = smunch(lastin, genbuf);
2397c478bd9Sstevel@tonic-gate for (c = lastin; c >= value(vi_TABSTOP); c -= value(vi_TABSTOP))
2407c478bd9Sstevel@tonic-gate *cp++ = '\t';
2417c478bd9Sstevel@tonic-gate for (; c > 0; c--)
2427c478bd9Sstevel@tonic-gate *cp++ = ' ';
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate CP(cp, genbuf);
2457c478bd9Sstevel@tonic-gate if (linebuf[0] == '.' && linebuf[1] == 0)
2467c478bd9Sstevel@tonic-gate return (EOF);
2477c478bd9Sstevel@tonic-gate return (0);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate /*
2517c478bd9Sstevel@tonic-gate * Crunch the indent.
2527c478bd9Sstevel@tonic-gate * Hard thing here is that in command mode some of the indent
2537c478bd9Sstevel@tonic-gate * is only implicit, so we must seed the column counter.
2547c478bd9Sstevel@tonic-gate * This should really be done differently so as to use the whitecnt routine
2557c478bd9Sstevel@tonic-gate * and also to hack indenting for LISP.
2567c478bd9Sstevel@tonic-gate */
257f6db9f27Scf46844 int
smunch(int col,unsigned char * ocp)258f6db9f27Scf46844 smunch(int col, unsigned char *ocp)
2597c478bd9Sstevel@tonic-gate {
260f6db9f27Scf46844 unsigned char *cp;
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate cp = ocp;
2637c478bd9Sstevel@tonic-gate for (;;)
2647c478bd9Sstevel@tonic-gate switch (*cp++) {
2657c478bd9Sstevel@tonic-gate
2667c478bd9Sstevel@tonic-gate case ' ':
2677c478bd9Sstevel@tonic-gate col++;
2687c478bd9Sstevel@tonic-gate continue;
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate case '\t':
2717c478bd9Sstevel@tonic-gate col += value(vi_TABSTOP) - (col % value(vi_TABSTOP));
2727c478bd9Sstevel@tonic-gate continue;
2737c478bd9Sstevel@tonic-gate
2747c478bd9Sstevel@tonic-gate default:
2757c478bd9Sstevel@tonic-gate cp--;
2767c478bd9Sstevel@tonic-gate CP(ocp, cp);
2777c478bd9Sstevel@tonic-gate return (col);
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate unsigned char *cntrlhm = (unsigned char *)"^H discarded\n";
2827c478bd9Sstevel@tonic-gate
283f6db9f27Scf46844 void
checkjunk(unsigned char c)284f6db9f27Scf46844 checkjunk(unsigned char c)
2857c478bd9Sstevel@tonic-gate {
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate if (junkbs == 0 && c == '\b') {
2887c478bd9Sstevel@tonic-gate write(2, cntrlhm, 13);
2897c478bd9Sstevel@tonic-gate junkbs = 1;
2907c478bd9Sstevel@tonic-gate }
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate
293f6db9f27Scf46844 void
setin(line * addr)294f6db9f27Scf46844 setin(line *addr)
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate if (addr == zero)
2987c478bd9Sstevel@tonic-gate lastin = 0;
2997c478bd9Sstevel@tonic-gate else
300*23a1cceaSRoger A. Faulkner getaline(*addr), lastin = smunch(0, linebuf);
3017c478bd9Sstevel@tonic-gate }
302