|
|
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.8 (Berkeley) 1/2/88"; ! 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(ex_getchar()); ! 25: } ! 26: ! 27: ex_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 = ex_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: ! 76: c = peekc; ! 77: if (c != 0) { ! 78: peekc = 0; ! 79: return (c); ! 80: } ! 81: if (globp) { ! 82: if (*globp) ! 83: return (*globp++); ! 84: globp = 0; ! 85: return (lastc = EOF); ! 86: } ! 87: top: ! 88: if (input) { ! 89: if (c = *input++) { ! 90: if (c &= TRIM) ! 91: return (lastc = c); ! 92: goto top; ! 93: } ! 94: input = 0; ! 95: } ! 96: flush(); ! 97: if (intty) { ! 98: c = read(0, inline, sizeof inline - 4); ! 99: if (c < 0) ! 100: return (lastc = EOF); ! 101: if (c == 0 || inline[c-1] != '\n') ! 102: inline[c++] = CTRL('d'); ! 103: if (inline[c-1] == '\n') ! 104: noteinp(); ! 105: inline[c] = 0; ! 106: for (c--; c >= 0; c--) ! 107: if (inline[c] == 0) ! 108: inline[c] = QUOTE; ! 109: input = inline; ! 110: goto top; ! 111: } ! 112: c = read(0, inline, sizeof inline - 1); ! 113: if(c <= 0) ! 114: return(lastc = EOF); ! 115: inline[c] = '\0'; ! 116: input = inline; ! 117: goto top; ! 118: } ! 119: ! 120: /* ! 121: * Input routine for insert/append/change in command mode. ! 122: * Most work here is in handling autoindent. ! 123: */ ! 124: static short lastin; ! 125: ! 126: gettty() ! 127: { ! 128: register int c = 0; ! 129: register char *cp = genbuf; ! 130: char hadup = 0; ! 131: int numbline(); ! 132: extern int (*Pline)(); ! 133: int offset = Pline == numbline ? 8 : 0; ! 134: int ch; ! 135: ! 136: if (intty && !inglobal) { ! 137: if (offset) { ! 138: holdcm = 1; ! 139: ex_printf(" %4d ", lineDOT() + 1); ! 140: flush(); ! 141: holdcm = 0; ! 142: } ! 143: if (value(AUTOINDENT) ^ aiflag) { ! 144: holdcm = 1; ! 145: #ifdef LISPCODE ! 146: if (value(LISP)) ! 147: lastin = lindent(dot + 1); ! 148: #endif ! 149: tab(lastin + offset); ! 150: while ((c = getcd()) == CTRL('d')) { ! 151: if (lastin == 0 && isatty(0) == -1) { ! 152: holdcm = 0; ! 153: return (EOF); ! 154: } ! 155: lastin = backtab(lastin); ! 156: tab(lastin + offset); ! 157: } ! 158: switch (c) { ! 159: ! 160: case '^': ! 161: case '0': ! 162: ch = getcd(); ! 163: if (ch == CTRL('d')) { ! 164: if (c == '0') ! 165: lastin = 0; ! 166: if (!OS) { ! 167: ex_putchar('\b' | QUOTE); ! 168: ex_putchar(' ' | QUOTE); ! 169: ex_putchar('\b' | QUOTE); ! 170: } ! 171: tab(offset); ! 172: hadup = 1; ! 173: c = ex_getchar(); ! 174: } else ! 175: ungetchar(ch); ! 176: break; ! 177: ! 178: case '.': ! 179: if (peekchar() == '\n') { ! 180: ignchar(); ! 181: noteinp(); ! 182: holdcm = 0; ! 183: return (EOF); ! 184: } ! 185: break; ! 186: ! 187: case '\n': ! 188: hadup = 1; ! 189: break; ! 190: } ! 191: } ! 192: flush(); ! 193: holdcm = 0; ! 194: } ! 195: if (c == 0) ! 196: c = ex_getchar(); ! 197: while (c != EOF && c != '\n') { ! 198: if (cp > &genbuf[LBSIZE - 2]) ! 199: error("Input line too long"); ! 200: *cp++ = c; ! 201: c = ex_getchar(); ! 202: } ! 203: if (c == EOF) { ! 204: if (inglobal) ! 205: ungetchar(EOF); ! 206: return (EOF); ! 207: } ! 208: *cp = 0; ! 209: cp = linebuf; ! 210: if ((value(AUTOINDENT) ^ aiflag) && hadup == 0 && intty && !inglobal) { ! 211: lastin = c = smunch(lastin, genbuf); ! 212: for (c = lastin; c >= value(TABSTOP); c -= value(TABSTOP)) ! 213: *cp++ = '\t'; ! 214: for (; c > 0; c--) ! 215: *cp++ = ' '; ! 216: } ! 217: CP(cp, genbuf); ! 218: if (linebuf[0] == '.' && linebuf[1] == 0) ! 219: return (EOF); ! 220: return (0); ! 221: } ! 222: ! 223: /* ! 224: * Crunch the indent. ! 225: * Hard thing here is that in command mode some of the indent ! 226: * is only implicit, so we must seed the column counter. ! 227: * This should really be done differently so as to use the whitecnt routine ! 228: * and also to hack indenting for LISP. ! 229: */ ! 230: smunch(col, ocp) ! 231: register int col; ! 232: char *ocp; ! 233: { ! 234: register char *cp; ! 235: ! 236: cp = ocp; ! 237: for (;;) ! 238: switch (*cp++) { ! 239: ! 240: case ' ': ! 241: col++; ! 242: continue; ! 243: ! 244: case '\t': ! 245: col += value(TABSTOP) - (col % value(TABSTOP)); ! 246: continue; ! 247: ! 248: default: ! 249: cp--; ! 250: CP(ocp, cp); ! 251: return (col); ! 252: } ! 253: } ! 254: ! 255: char *cntrlhm = "^H discarded\n"; ! 256: ! 257: checkjunk(c) ! 258: char c; ! 259: { ! 260: ! 261: if (junkbs == 0 && c == '\b') { ! 262: write(2, cntrlhm, 13); ! 263: junkbs = 1; ! 264: } ! 265: } ! 266: ! 267: line * ! 268: setin(addr) ! 269: line *addr; ! 270: { ! 271: ! 272: if (addr == zero) ! 273: lastin = 0; ! 274: else ! 275: getline(*addr), lastin = smunch(0, linebuf); ! 276: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.