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 44f6db9f27Scf46844 ignchar(void) 457c478bd9Sstevel@tonic-gate { 467c478bd9Sstevel@tonic-gate (void)getchar(); 477c478bd9Sstevel@tonic-gate } 487c478bd9Sstevel@tonic-gate 49f6db9f27Scf46844 int 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 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 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 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 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 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 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 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 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