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