|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char *sccsid = "@(#)ex_get.c 7.6 (Berkeley) 6/7/85"; ! 9: #endif not lint ! 10: ! 11: #include "ex.h" ! 12: #include "ex_tty.h" ! 13: ! 14: /* ! 15: * Input routines for command mode. ! 16: * Since we translate the end of reads into the implied ^D's ! 17: * we have different flavors of routines which do/don't return such. ! 18: */ ! 19: static bool junkbs; ! 20: short lastc = '\n'; ! 21: ! 22: ignchar() ! 23: { ! 24: ignore(getchar()); ! 25: } ! 26: ! 27: getchar() ! 28: { ! 29: register int c; ! 30: ! 31: do ! 32: c = getcd(); ! 33: while (!globp && c == CTRL(d)); ! 34: return (c); ! 35: } ! 36: ! 37: getcd() ! 38: { ! 39: register int c; ! 40: ! 41: again: ! 42: c = getach(); ! 43: if (c == EOF) ! 44: return (c); ! 45: c &= TRIM; ! 46: if (!inopen) ! 47: if (!globp && c == CTRL(d)) ! 48: setlastchar('\n'); ! 49: else if (junk(c)) { ! 50: checkjunk(c); ! 51: goto again; ! 52: } ! 53: return (c); ! 54: } ! 55: ! 56: peekchar() ! 57: { ! 58: ! 59: if (peekc == 0) ! 60: peekc = getchar(); ! 61: return (peekc); ! 62: } ! 63: ! 64: peekcd() ! 65: { ! 66: if (peekc == 0) ! 67: peekc = getcd(); ! 68: return (peekc); ! 69: } ! 70: ! 71: getach() ! 72: { ! 73: register int c; ! 74: static char inline[BUFSIZ]; ! 75: struct stat statb; ! 76: ! 77: c = peekc; ! 78: if (c != 0) { ! 79: peekc = 0; ! 80: return (c); ! 81: } ! 82: if (globp) { ! 83: if (*globp) ! 84: return (*globp++); ! 85: globp = 0; ! 86: return (lastc = EOF); ! 87: } ! 88: top: ! 89: if (input) { ! 90: if (c = *input++) { ! 91: if (c &= TRIM) ! 92: return (lastc = c); ! 93: goto top; ! 94: } ! 95: input = 0; ! 96: } ! 97: flush(); ! 98: if (intty) { ! 99: c = read(0, inline, sizeof inline - 4); ! 100: if (c < 0) ! 101: return (lastc = EOF); ! 102: if (c == 0 || inline[c-1] != '\n') ! 103: inline[c++] = CTRL(d); ! 104: if (inline[c-1] == '\n') ! 105: noteinp(); ! 106: inline[c] = 0; ! 107: for (c--; c >= 0; c--) ! 108: if (inline[c] == 0) ! 109: inline[c] = QUOTE; ! 110: input = inline; ! 111: goto top; ! 112: } ! 113: c = read(0, inline, sizeof inline - 1); ! 114: if(c <= 0) ! 115: return(lastc = EOF); ! 116: inline[c] = '\0'; ! 117: input = inline; ! 118: goto top; ! 119: } ! 120: ! 121: /* ! 122: * Input routine for insert/append/change in command mode. ! 123: * Most work here is in handling autoindent. ! 124: */ ! 125: static short lastin; ! 126: ! 127: gettty() ! 128: { ! 129: register int c = 0; ! 130: register char *cp = genbuf; ! 131: char hadup = 0; ! 132: int numbline(); ! 133: extern int (*Pline)(); ! 134: int offset = Pline == numbline ? 8 : 0; ! 135: int ch; ! 136: ! 137: if (intty && !inglobal) { ! 138: if (offset) { ! 139: holdcm = 1; ! 140: printf(" %4d ", lineDOT() + 1); ! 141: flush(); ! 142: holdcm = 0; ! 143: } ! 144: if (value(AUTOINDENT) ^ aiflag) { ! 145: holdcm = 1; ! 146: #ifdef LISPCODE ! 147: if (value(LISP)) ! 148: lastin = lindent(dot + 1); ! 149: #endif ! 150: tab(lastin + offset); ! 151: while ((c = getcd()) == CTRL(d)) { ! 152: if (lastin == 0 && isatty(0) == -1) { ! 153: holdcm = 0; ! 154: return (EOF); ! 155: } ! 156: lastin = backtab(lastin); ! 157: tab(lastin + offset); ! 158: } ! 159: switch (c) { ! 160: ! 161: case '^': ! 162: case '0': ! 163: ch = getcd(); ! 164: if (ch == CTRL(d)) { ! 165: if (c == '0') ! 166: lastin = 0; ! 167: if (!OS) { ! 168: putchar('\b' | QUOTE); ! 169: putchar(' ' | QUOTE); ! 170: putchar('\b' | QUOTE); ! 171: } ! 172: tab(offset); ! 173: hadup = 1; ! 174: c = getchar(); ! 175: } else ! 176: ungetchar(ch); ! 177: break; ! 178: ! 179: case '.': ! 180: if (peekchar() == '\n') { ! 181: ignchar(); ! 182: noteinp(); ! 183: holdcm = 0; ! 184: return (EOF); ! 185: } ! 186: break; ! 187: ! 188: case '\n': ! 189: hadup = 1; ! 190: break; ! 191: } ! 192: } ! 193: flush(); ! 194: holdcm = 0; ! 195: } ! 196: if (c == 0) ! 197: c = getchar(); ! 198: while (c != EOF && c != '\n') { ! 199: if (cp > &genbuf[LBSIZE - 2]) ! 200: error("Input line too long"); ! 201: *cp++ = c; ! 202: c = getchar(); ! 203: } ! 204: if (c == EOF) { ! 205: if (inglobal) ! 206: ungetchar(EOF); ! 207: return (EOF); ! 208: } ! 209: *cp = 0; ! 210: cp = linebuf; ! 211: if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) { ! 212: lastin = c = smunch(lastin, genbuf); ! 213: for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP)) ! 214: *cp++ = '\t'; ! 215: for (; c > 0; c--) ! 216: *cp++ = ' '; ! 217: } ! 218: CP(cp, genbuf); ! 219: if (linebuf[0] == '.' && linebuf[1] == 0) ! 220: return (EOF); ! 221: return (0); ! 222: } ! 223: ! 224: /* ! 225: * Crunch the indent. ! 226: * Hard thing here is that in command mode some of the indent ! 227: * is only implicit, so we must seed the column counter. ! 228: * This should really be done differently so as to use the whitecnt routine ! 229: * and also to hack indenting for LISP. ! 230: */ ! 231: smunch(col, ocp) ! 232: register int col; ! 233: char *ocp; ! 234: { ! 235: register char *cp; ! 236: ! 237: cp = ocp; ! 238: for (;;) ! 239: switch (*cp++) { ! 240: ! 241: case ' ': ! 242: col++; ! 243: continue; ! 244: ! 245: case '\t': ! 246: col += value(TABSTOP) - (col % value(TABSTOP)); ! 247: continue; ! 248: ! 249: default: ! 250: cp--; ! 251: CP(ocp, cp); ! 252: return (col); ! 253: } ! 254: } ! 255: ! 256: char *cntrlhm = "^H discarded\n"; ! 257: ! 258: checkjunk(c) ! 259: char c; ! 260: { ! 261: ! 262: if (junkbs == 0 && c == '\b') { ! 263: write(2, cntrlhm, 13); ! 264: junkbs = 1; ! 265: } ! 266: } ! 267: ! 268: line * ! 269: setin(addr) ! 270: line *addr; ! 271: { ! 272: ! 273: if (addr == zero) ! 274: lastin = 0; ! 275: else ! 276: getline(*addr), lastin = smunch(0, linebuf); ! 277: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.