|
|
1.1 ! root 1: /* Copyright (c) 1981 Regents of the University of California */ ! 2: static char *sccsid = "@(#)ex_get.c 7.1 7/8/81"; ! 3: #include "ex.h" ! 4: #include "ex_tty.h" ! 5: ! 6: /* ! 7: * Input routines for command mode. ! 8: * Since we translate the end of reads into the implied ^D's ! 9: * we have different flavors of routines which do/don't return such. ! 10: */ ! 11: static bool junkbs; ! 12: short lastc = '\n'; ! 13: ! 14: ignchar() ! 15: { ! 16: ignore(getchar()); ! 17: } ! 18: ! 19: getchar() ! 20: { ! 21: register int c; ! 22: ! 23: do ! 24: c = getcd(); ! 25: while (!globp && c == CTRL(d)); ! 26: return (c); ! 27: } ! 28: ! 29: getcd() ! 30: { ! 31: register int c; ! 32: ! 33: again: ! 34: c = getach(); ! 35: if (c == EOF) ! 36: return (c); ! 37: c &= TRIM; ! 38: if (!inopen) ! 39: if (!globp && c == CTRL(d)) ! 40: setlastchar('\n'); ! 41: else if (junk(c)) { ! 42: checkjunk(c); ! 43: goto again; ! 44: } ! 45: return (c); ! 46: } ! 47: ! 48: peekchar() ! 49: { ! 50: ! 51: if (peekc == 0) ! 52: peekc = getchar(); ! 53: return (peekc); ! 54: } ! 55: ! 56: peekcd() ! 57: { ! 58: if (peekc == 0) ! 59: peekc = getcd(); ! 60: return (peekc); ! 61: } ! 62: ! 63: getach() ! 64: { ! 65: register int c; ! 66: static char inline[128]; ! 67: struct stat statb; ! 68: ! 69: c = peekc; ! 70: if (c != 0) { ! 71: peekc = 0; ! 72: return (c); ! 73: } ! 74: if (globp) { ! 75: if (*globp) ! 76: return (*globp++); ! 77: globp = 0; ! 78: return (lastc = EOF); ! 79: } ! 80: top: ! 81: if (input) { ! 82: if (c = *input++) { ! 83: if (c &= TRIM) ! 84: return (lastc = c); ! 85: goto top; ! 86: } ! 87: input = 0; ! 88: } ! 89: flush(); ! 90: if (intty) { ! 91: c = read(0, inline, sizeof inline - 4); ! 92: if (c < 0) ! 93: return (lastc = EOF); ! 94: if (c == 0 || inline[c-1] != '\n') ! 95: inline[c++] = CTRL(d); ! 96: if (inline[c-1] == '\n') ! 97: noteinp(); ! 98: inline[c] = 0; ! 99: for (c--; c >= 0; c--) ! 100: if (inline[c] == 0) ! 101: inline[c] = QUOTE; ! 102: input = inline; ! 103: goto top; ! 104: } ! 105: /* mjm: if (read(0, (char *) &lastc, 1) != 1) CHANGED and added else */ ! 106: if (read(0, inline, 1) != 1) ! 107: lastc = EOF; ! 108: else /* mjm: lastc is a short! */ ! 109: lastc = inline[0]; /* mjm: in rightmost 8 bits ! */ ! 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.