int putch(int c) { #ifdef OLD3BTTY /* mjm */ if(c == '\n') /* mjm: Fake "\n\r" for '\n' til fix in 3B firmware */ putch('\r'); /* mjm: vi does "stty -icanon" => -onlcr !! */ #endif if (c & MULTICOL) { c &= ~MULTICOL; if (c == 0) return MULTICOL; } c &= ~INVBIT; /* strip '~' | INVBIT multicolumn filler */ #ifdef MB if (mb_cur_max > 1 && c & ~(wchar_t)0177) { char mb[MB_LEN_MAX]; int i, n; n = wctomb(mb, c&TRIM); for (i = 0; i < n; i++) { *obp++ = mb[i]; if (obp >= &obuf[sizeof obuf]) flusho(); } } else #endif /* MB */ *obp++ = c & TRIM; if (obp >= &obuf[sizeof obuf]) flusho(); return c; }
static void _casewh(struct d *dp) { register int i, j, k; lgf++; skip(1); i = vnumb((int *)0); if (nonumb) return; skip(0); j = getrq(1); if ((k = findn(dp, i)) != NTRAP) { dp->mlist[k] = j; return; } for (k = 0; k < NTRAP; k++) if (dp->mlist[k] == 0) break; if (k == NTRAP) { flusho(); errprint("cannot plant trap."); return; } dp->mlist[k] = j; dp->nlist[k] = i; chkt(dp, i); }
/* * Try to start -nl mode. */ void pstart(void) { if (NONL) return; if (!value(OPTIMIZE)) return; if (ruptible == 0 || pfast) return; fgoto(); flusho(); pfast = 1; normtty++; tty = normf; tty.c_oflag &= ~(ONLCR #if defined (TAB3) | TAB3 #elif defined (XTABS) | XTABS #endif ); tty.c_lflag &= ~ECHO; sTTY(1); }
void n_ptpause(void ) { char junk; flusho(); read(2, &junk, 1); }
void storeline(Tchar c, int w) { int diff; if (linep >= line + lnsize - 2) { lnsize += LNSIZE; diff = linep - line; if (( line = (Tchar *)realloc((char *)line, lnsize * sizeof(Tchar))) != NULL) { if (linep && diff) linep = line + diff; } else { if (over) { return; } else { flusho(); ERROR "Line overflow." WARN; over++; *linep++ = LEFTHAND; w = width(LEFTHAND); nc++; c = '\n'; } } } *linep++ = c; ne += w; nel -= w; nc++; }
void caserd(void) { lgf++; skip(0); getname(); if (!iflg) { if (quiet) { #ifdef NROFF echo_off(); flusho(); #endif /* NROFF */ fdprintf(stderr, "\007"); /*bell*/ } else { if (nextf[0]) { fdprintf(stderr, "%s:", nextf); } else { fdprintf(stderr, "\007"); /*bell*/ } } } collect(); tty++; pushi(-1, PAIR('r','d'), 0); }
void flush2(void) { fgoto(); flusho(); pstop(); }
void caseev(void) { char *name; int nxev; struct env *np, *op; if (getev(&nxev, &name) == 0) { if (evi == 0) return; nxev = evlist[--evi]; goto e1; } if (xflag == 0 && ((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ))) goto cannot; if (evi >= evlsz) { evlsz = evi + 1; if ((evlist = realloc(evlist, evlsz * sizeof *evlist)) == NULL) goto cannot; } if (name && findev(&nxev, name) == NULL || nxev >= Nev) { if ((evp = realloc(evp, (Nev-NEV+1) * sizeof *evp)) == NULL || (evnames = realloc(evnames, (Nev-NEV+1) * sizeof *evnames)) == NULL) goto cannot; evnames[Nev-NEV].number = nxev; evnames[Nev-NEV].name = name; evp[Nev-NEV] = initenv; Nev++; } if (name == NULL && nxev < 0) { flusho(); cannot: errprint("cannot do ev."); if (error) done2(040); else edone(040); return; } evlist[evi++] = ev; e1: if (ev == nxev) return; if ((np = findev(&nxev, name)) == NULL || (op = findev(&ev, NULL)) == NULL) goto cannot; *op = env; env = *np; ev = nxev; if (evname == NULL) if (name) evname = name; else { evname = malloc(20); roff_sprintf(evname, "%d", ev); } }
/* * Stop open, restoring tty modes. */ void ostop(struct termios f) { pfast = (f.c_oflag & ONLCR) == 0; termreset(), fgoto(), flusho(); normal(f); tostop(); }
void casecf(void) { /* copy file without change */ FILE *fd; char *eof, *p; extern int hpos, esc, po; /* this may not make much sense in nroff... */ lgf++; nextf[0] = 0; if (!skip() && getname()) { if (strncmp("<<", nextf, 2) != 0) { if ((fd = fopen(nextf, "r")) == NULL) { ERROR "can't open file %s", nextf WARN; done(02); } eof = (char *) NULL; } else { /* current file */ if (pbp > lastpbp || ip) { ERROR "casecf: not reading from file" WARN; done(02); } eof = &nextf[2]; if (!*eof) { ERROR "casecf: missing end of input token" WARN; done(02); } p = eof; while(*++p) ; *p++ = '\n'; *p = 0; fd = ifile; } } else { ERROR "casecf: no argument" WARN; lgf--; return; } lgf--; /* make it into a clean state, be sure that everything is out */ tbreak(); hpos = po; esc = 0; ptesc(); /* to left margin */ esc = un; ptesc(); ptlead(); ptps(); ptfont(); flusho(); cpout(fd, eof); ptps(); ptfont(); }
void done2(int x) { ptlead(); #ifndef NROFF if (!ascii) ptstop(); #endif flusho(); done3(x); }
/* * Fix the echo area for use, setting * the state variable splitw so we wont rollup * when we move the cursor there. */ void fixech(void) { splitw++; if (state != VISUAL && state != CRTOPEN) { vclean(); vcnt = 0; } vgoto(WECHO, 0); flusho(); }
void twdone(void) { if (!TROFF && t.twrest) { obufp = obuf; oputs(t.twrest); flusho(); if (pipeflg) { pclose(ptid); } restore_tty(); } }
twdone(){ obufp = obuf; oputs(t.twrest); flusho(); if(pipeflg){ close(ptid); wait(&waitf); } if(ttysave != -1) { ttys.sg_flags = ttysave; stty(1, &ttys); } }
void chkpn(void) { pto = *(pnp++); pfrom = pto>=0 ? pto : -pto; if (pto == -INT_MAX) { flusho(); done1(0); } if (pto < 0) { pto = -pto; print++; pfrom = 0; } }
static void ovend(ttymode f) { splitw++; vgoto(WECHO, 0); vclreol(); vgoto(WECHO, 0); holdcm = 0; splitw = 0; ostop(f); setoutt(); undvis(); COLUMNS = OCOLUMNS; inopen = 0; flusho(); netchHAD(Vlines); }
void done1(int x) { error |= x; if (numtab[NL].val) { trap = 0; eject((struct s *)0); longjmp(sjbuf, 1); } if (nofeed) { ptlead(); flusho(); done3(0); } else { pttrailer(); done2(0); } }
void finish(code) { if (code == SIGINT) { char c; ignorf(signal(code, finish)); message("Quit? "); UpdateMesg(); ignore(read(0, &c, 1)); message(""); if ((c & 0377) != 'y') { redisplay(); return; } } if (code) { if (code == SIGHUP) ignorf(signal(code, SIG_IGN)); /* A little privacy */ if (!Crashing) { putstr("Writing modified JOVE buffers..."); Crashing++; jove_exp_p = 0; WtModBuf(); } else putstr("Complete lossage!"); } ttyset(0); Placur(LI - 1, 0); putpad(CE, 1); if (KE) putpad(KE, 1); if (VE) putpad(VE, 1); if (TE) putpad(TE, 1); flusho(); byebye(code); }
void storeword(Tchar c, int w) { Tchar *savp; int i; if (wordp >= word + wdsize - 2) { wdsize += WDSIZE; savp = word; if (( word = (Tchar *)realloc((char *)word, wdsize * sizeof(Tchar))) != NULL) { if (wordp) wordp = word + (wordp - savp); if (pendw) pendw = word + (pendw - savp); if (wdstart) wdstart = word + (wdstart - savp); if (wdend) wdend = word + (wdend - savp); for (i = 0; i < NHYP; i++) if (hyptr[i]) hyptr[i] = word + (hyptr[i] - savp); } else { if (over) { return; } else { flusho(); ERROR "Word overflow." WARN; over++; c = LEFTHAND; w = width(LEFTHAND); } } } widthp = w; wne += w; *wordp++ = c; wch++; }
/* * Get a line into genbuf after gcursor. * Cnt limits the number of input characters * accepted and is used for handling the replace * single character command. Aescaped is the location * where we stick a termination indicator (whether we * ended with an ESCAPE or a newline/return. * * We do erase-kill type processing here and also * are careful about the way we do this so that it is * repeatable. (I.e. so that your kill doesn't happen, * when you repeat an insert if it was escaped with \ the * first time you did it. */ char * vgetline(int cnt, char *gcursor, bool *aescaped) { register int c, ch; register char *cp; int x, y, iwhite; char *iglobp; void (*OO)() = Outchar; /* * Clear the output state and counters * for autoindent backwards motion (counts of ^D, etc.) * Remember how much white space at beginning of line so * as not to allow backspace over autoindent. */ *aescaped = 0; ogcursor = gcursor; flusho(); CDCNT = 0; HADUP = 0; HADZERO = 0; gobbled = 0; iwhite = whitecnt(genbuf); iglobp = vglobp; /* * Carefully avoid using vinschar in the echo area. */ if (splitw) Outchar = vputchar; else { Outchar = vinschar; vprepins(); } for (;;) { if (gobblebl) gobblebl--; if (cnt != 0) { cnt--; if (cnt == 0) goto vadone; } ch = c = getkey() & (QUOTE|TRIM); if (!iglobp) { /* * Erase-kill type processing. * Only happens if we were not reading * from untyped input when we started. * Map users erase to ^H, kill to -1 for switch. */ if (c == tty.c_cc[VERASE]) c = CTRL('h'); else if (c == tty.c_cc[VKILL]) c = -1; switch (c) { /* * ^? Interrupt drops you back to visual * command mode with an unread interrupt * still in the input buffer. * * ^\ Quit does the same as interrupt. * If you are a ex command rather than * a vi command this will drop you * back to command mode for sure. */ case ATTN: case QUIT: ungetkey(c); goto vadone; /* * ^H Backs up a character in the input. * * BUG: Can't back around line boundaries. * This is hard because stuff has * already been saved for repeat. */ case CTRL('h'): bakchar: cp = gcursor - 1; if (cp < ogcursor) { beep(); continue; } goto vbackup; /* * ^W Back up a white/non-white word. */ case CTRL('w'): wdkind = 1; for (cp = gcursor; cp > ogcursor && isspace((int)cp[-1]); cp--) continue; for (c = wordch(cp - 1); cp > ogcursor && wordof(c, cp - 1); cp--) continue; goto vbackup; /* * users kill Kill input on this line, back to * the autoindent. */ case -1: cp = ogcursor; vbackup: if (cp == gcursor) { beep(); continue; } endim(); *cp = 0; c = cindent(); vgotoCL(qcolumn(cursor - 1, genbuf)); if (doomed >= 0) doomed += c - cindent(); gcursor = cp; continue; /* * \ Followed by erase or kill * maps to just the erase or kill. */ case '\\': x = destcol, y = destline; ex_putchar('\\'); vcsync(); c = getkey(); if (c == tty.c_cc[VERASE] || c == tty.c_cc[VKILL]) { vgoto(y, x); if (doomed >= 0) doomed++; goto def; } ungetkey(c), c = '\\'; goto noput; /* * ^Q Super quote following character * Only ^@ is verboten (trapped at * a lower level) and \n forces a line * split so doesn't really go in. * * ^V Synonym for ^Q */ case CTRL('q'): case CTRL('v'): x = destcol, y = destline; ex_putchar('^'); vgoto(y, x); c = getkey(); if (c != NL) { if (doomed >= 0) doomed++; goto def; } break; } } /* * If we get a blank not in the echo area * consider splitting the window in the wrapmargin. */ if (c == ' ' && !splitw) { if (gobblebl) { gobbled = 1; continue; } if (value(WRAPMARGIN) && outcol >= WCOLS - value(WRAPMARGIN)) { c = NL; gobblebl = 2; } } switch (c) { /* * ^M Except in repeat maps to \n. */ case CR: if (vglobp) goto def; c = '\n'; /* presto chango ... */ /* * \n Start new line. */ case NL: *aescaped = c; goto vadone; /* * escape End insert unless repeat and more to repeat. */ case ESCAPE: if (vglobp && *vglobp) goto def; goto vadone; /* * ^D Backtab. * ^T Software forward tab. * * Unless in repeat where this means these * were superquoted in. */ case CTRL('d'): case CTRL('t'): if (vglobp) goto def; /* fall into ... */ /* * ^D|QUOTE Is a backtab (in a repeated command). */ case CTRL('d') | QUOTE: *gcursor = 0; cp = vpastwh(genbuf); c = whitecnt(genbuf); if (ch == CTRL('t')) { /* * ^t just generates new indent replacing * current white space rounded up to soft * tab stop increment. */ if (cp != gcursor) /* * BUG: Don't hack ^T except * right after initial * white space. */ continue; cp = genindent(iwhite = backtab(c + value(SHIFTWIDTH) + 1)); ogcursor = cp; goto vbackup; } /* * ^D works only if we are at the (end of) the * generated autoindent. We count the ^D for repeat * purposes. */ if (c == iwhite && c != 0) { if (cp == gcursor) { iwhite = backtab(c); CDCNT++; ogcursor = cp = genindent(iwhite); goto vbackup; } else if (&cp[1] == gcursor && (*cp == '^' || *cp == '0')) { /* * ^^D moves to margin, then back * to current indent on next line. * * 0^D moves to margin and then * stays there. */ HADZERO = *cp == '0'; ogcursor = cp = genbuf; HADUP = 1 - HADZERO; CDCNT = 1; endim(); back1(); vputc(' '); goto vbackup; } } if (vglobp && vglobp - iglobp >= 2 && (vglobp[-2] == '^' || vglobp[-2] == '0') && gcursor == ogcursor + 1) goto bakchar; continue; default: /* * Possibly discard control inputs. */ if (!vglobp && junk(c)) { beep(); continue; } def: ex_putchar(c); noput: if (gcursor > &genbuf[LBSIZE - 2]) error("Line too long"); *gcursor++ = c & TRIM; vcsync(); #ifdef LISP if (value(SHOWMATCH) && !iglobp) if (c == ')' || c == '}') lsmatch(gcursor); #endif continue; } } vadone: *gcursor = 0; Outchar = OO; endim(); return (gcursor); }
int32_t atoi0(void) { int c, k, cnt; Tchar ii; int32_t i, acc; acc = 0; nonumb = 0; cnt = -1; a0: cnt++; ii = getch(); c = cbits(ii); switch (c) { default: ch = ii; if (cnt) break; case '+': i = ckph(); if (nonumb) break; acc += i; goto a0; case '-': i = ckph(); if (nonumb) break; acc -= i; goto a0; case '*': i = ckph(); if (nonumb) break; acc *= i; goto a0; case '/': i = ckph(); if (nonumb) break; if (i == 0) { flusho(); ERROR "divide by zero." WARN; acc = 0; } else acc /= i; goto a0; case '%': i = ckph(); if (nonumb) break; acc %= i; goto a0; case '&': /*and*/ i = ckph(); if (nonumb) break; if ((acc > 0) && (i > 0)) acc = 1; else acc = 0; goto a0; case ':': /*or*/ i = ckph(); if (nonumb) break; if ((acc > 0) || (i > 0)) acc = 1; else acc = 0; goto a0; case '=': if (cbits(ii = getch()) != '=') ch = ii; i = ckph(); if (nonumb) { acc = 0; break; } if (i == acc) acc = 1; else acc = 0; goto a0; case '>': k = 0; if (cbits(ii = getch()) == '=') k++; else ch = ii; i = ckph(); if (nonumb) { acc = 0; break; } if (acc > (i - k)) acc = 1; else acc = 0; goto a0; case '<': k = 0; if (cbits(ii = getch()) == '=') k++; else ch = ii; i = ckph(); if (nonumb) { acc = 0; break; } if (acc < (i + k)) acc = 1; else acc = 0; goto a0; case ')': break; case '(': acc = atoi0(); goto a0; } return(acc); }
void newline(int a) { int i, j, nlss; int opn; nlss = 0; if (a) goto nl1; if (dip != d) { j = lss; pchar1((Tchar)FLSS); if (flss) lss = flss; i = lss + dip->blss; dip->dnl += i; pchar1((Tchar)i); pchar1((Tchar)'\n'); lss = j; dip->blss = flss = 0; if (dip->alss) { pchar1((Tchar)FLSS); pchar1((Tchar)dip->alss); pchar1((Tchar)'\n'); dip->dnl += dip->alss; dip->alss = 0; } if (dip->ditrap && !dip->ditf && dip->dnl >= dip->ditrap && dip->dimac) if (control(dip->dimac, 0)) { trap++; dip->ditf++; } return; } j = lss; if (flss) lss = flss; nlss = dip->alss + dip->blss + lss; numtabp[NL].val += nlss; if (TROFF && ascii) { dip->alss = dip->blss = 0; } pchar1((Tchar)'\n'); flss = 0; lss = j; if (numtabp[NL].val < pl) goto nl2; nl1: ejf = dip->hnl = numtabp[NL].val = 0; ejl = frame; if (donef) { if ((!nc && !wch) || ndone) done1(0); ndone++; donef = 0; if (frame == stk) nflush++; } opn = numtabp[PN].val; numtabp[PN].val++; if (npnflg) { numtabp[PN].val = npn; npn = npnflg = 0; } nlpn: if (numtabp[PN].val == pfrom) { print++; pfrom = -1; } else if (opn == pto) { print = 0; opn = -1; chkpn(); goto nlpn; } if (print) ptpage(numtabp[PN].val); /* supposedly in a clean state so can pause */ if (stop && print) { dpn++; if (dpn >= stop) { dpn = 0; ptpause(); } } nl2: trap = 0; if (numtabp[NL].val == 0) { if ((j = findn(0)) != NTRAP) trap = control(mlist[j], 0); } else if ((i = findt(numtabp[NL].val - nlss)) <= nlss) { if ((j = findn1(numtabp[NL].val - nlss + i)) == NTRAP) { flusho(); ERROR "Trap botch." WARN; done2(-5); } trap = control(mlist[j], 0); } }
/* * Get a line into genbuf after gcursor. * Cnt limits the number of input characters * accepted and is used for handling the replace * single character command. Aescaped is the location * where we stick a termination indicator (whether we * ended with an ESCAPE or a newline/return. * * We do erase-kill type processing here and also * are careful about the way we do this so that it is * repeatable. (I.e. so that your kill doesn't happen, * when you repeat an insert if it was escaped with \ the * first time you did it. commch is the command character * involved, including the prompt for readline. */ char * vgetline(int cnt, char *gcursor, bool *aescaped, int commch) { register int c, ch; register char *cp; int x, y, iwhite, backsl=0; cell *iglobp; char cstr[2]; int (*OO)(int) = Outchar; /* * Clear the output state and counters * for autoindent backwards motion (counts of ^D, etc.) * Remember how much white space at beginning of line so * as not to allow backspace over autoindent. */ *aescaped = 0; ogcursor = gcursor; flusho(); CDCNT = 0; HADUP = 0; HADZERO = 0; gobbled = 0; iwhite = whitecnt(genbuf); iglobp = vglobp; /* * Carefully avoid using vinschar in the echo area. */ if (splitw) Outchar = vputchar; else { Outchar = vinschar; vprepins(); } for (;;) { backsl = 0; if (gobblebl) gobblebl--; if (cnt != 0) { cnt--; if (cnt == 0) goto vadone; } c = getkey(); if (c != ATTN) c &= (QUOTE|TRIM); ch = c; maphopcnt = 0; if (vglobp == 0 && Peekkey == 0 && commch != 'r') while ((ch = map(c, immacs)) != c) { c = ch; if (!value(REMAP)) break; if (++maphopcnt > 256) error(catgets(catd, 1, 234, "Infinite macro loop")); } if (!iglobp) { /* * Erase-kill type processing. * Only happens if we were not reading * from untyped input when we started. * Map users erase to ^H, kill to -1 for switch. */ if (c == tty.c_cc[VERASE]) c = CTRL('h'); else if (c == tty.c_cc[VKILL]) c = -1; if (c == ATTN) goto case_ATTN; switch (c) { /* * ^? Interrupt drops you back to visual * command mode with an unread interrupt * still in the input buffer. * * ^\ Quit does the same as interrupt. * If you are a ex command rather than * a vi command this will drop you * back to command mode for sure. */ case QUIT: case_ATTN: ungetkey(c); goto vadone; /* * ^H Backs up a character in the input. * * BUG: Can't back around line boundaries. * This is hard because stuff has * already been saved for repeat. */ case CTRL('h'): bakchar: cp = gcursor + skipleft(ogcursor, gcursor); if (cp < ogcursor) { if (splitw) { /* * Backspacing over readecho * prompt. Pretend delete but * don't beep. */ ungetkey(c); goto vadone; } beep(); continue; } goto vbackup; /* * ^W Back up a white/non-white word. */ case CTRL('w'): wdkind = 1; for (cp = gcursor; cp > ogcursor && isspace(cp[-1]&0377); cp--) continue; for (c = wordch(cp - 1); cp > ogcursor && wordof(c, cp - 1); cp--) continue; goto vbackup; /* * users kill Kill input on this line, back to * the autoindent. */ case -1: cp = ogcursor; vbackup: if (cp == gcursor) { beep(); continue; } endim(); *cp = 0; c = cindent(); vgotoCL(qcolumn(cursor + skipleft(linebuf, cursor), genbuf)); if (doomed >= 0) doomed += c - cindent(); gcursor = cp; continue; /* * \ Followed by erase or kill * maps to just the erase or kill. */ case '\\': x = destcol, y = destline; putchar('\\'); vcsync(); c = getkey(); if (c == tty.c_cc[VERASE] || c == tty.c_cc[VKILL]) { vgoto(y, x); if (doomed >= 0) doomed++; goto def; } ungetkey(c), c = '\\'; backsl = 1; break; /* * ^Q Super quote following character * Only ^@ is verboten (trapped at * a lower level) and \n forces a line * split so doesn't really go in. * * ^V Synonym for ^Q */ case CTRL('q'): case CTRL('v'): x = destcol, y = destline; putchar('^'); vgoto(y, x); c = getkey(); if (c != NL) { if (doomed >= 0) doomed++; goto def; } break; } } /* * If we get a blank not in the echo area * consider splitting the window in the wrapmargin. */ if (c != NL && !splitw) { if (c == ' ' && gobblebl) { gobbled = 1; continue; } if (value(WRAPMARGIN) && (outcol >= OCOLUMNS - value(WRAPMARGIN) || (backsl && outcol == 0)) && commch != 'r') { /* * At end of word and hit wrapmargin. * Move the word to next line and keep going. */ wdkind = 1; gappend(c); if (backsl) gappend(getkey()); *gcursor = 0; /* * Find end of previous word if we are past it. */ for (cp=gcursor; cp>ogcursor && isspace(cp[-1]&0377); cp--) ; if (outcol+(backsl?OCOLUMNS:0) - (gcursor-cp) >= OCOLUMNS - value(WRAPMARGIN)) { /* * Find beginning of previous word. */ for (; cp>ogcursor && !isspace(cp[-1]&0377); cp--) ; if (cp <= ogcursor) { /* * There is a single word that * is too long to fit. Just * let it pass, but beep for * each new letter to warn * the luser. */ c = *--gcursor; *gcursor = 0; beep(); goto dontbreak; } /* * Save it for next line. */ macpush(cp, 0); cp--; } macpush("\n", 0); /* * Erase white space before the word. */ while (cp > ogcursor && isspace(cp[-1]&0377)) cp--; /* skip blank */ gobblebl = 3; goto vbackup; } dontbreak:; } /* * Word abbreviation mode. */ cstr[0] = c; if (anyabbrs && gcursor > ogcursor && !wordch(cstr) && wordch(gcursor-1)) { int wdtype, abno; cstr[1] = 0; wdkind = 1; cp = gcursor + skipleft(ogcursor, gcursor); for (wdtype = wordch(cp - 1); cp > ogcursor && wordof(wdtype, cp - 1); cp--) ; *gcursor = 0; for (abno=0; abbrevs[abno].mapto; abno++) { if (!abbrevs[abno].hadthis && eq(cp, abbrevs[abno].cap)) { abbrevs[abno].hadthis++; macpush(cstr, 0); macpush(abbrevs[abno].mapto, 0); goto vbackup; } } } #ifdef BIT8 if (c == OVERBUF) goto btrp; #endif switch (c) { /* * ^M Except in repeat maps to \n. */ case CR: if (vglobp) goto def; c = '\n'; /* presto chango ... */ /* * \n Start new line. */ case NL: *aescaped = c; goto vadone; /* * escape End insert unless repeat and more to repeat. */ case ESCAPE: if (lastvgk) goto def; goto vadone; /* * ^D Backtab. * ^T Software forward tab. * * Unless in repeat where this means these * were superquoted in. */ case CTRL('d'): case CTRL('t'): if (vglobp) goto def; /* fall into ... */ /* * ^D|QUOTE Is a backtab (in a repeated command). */ #ifndef BIT8 case CTRL('d') | QUOTE: #else btrp: #endif *gcursor = 0; cp = vpastwh(genbuf); c = whitecnt(genbuf); if (ch == CTRL('t')) { /* * ^t just generates new indent replacing * current white space rounded up to soft * tab stop increment. */ if (cp != gcursor) /* * BUG: Don't hack ^T except * right after initial * white space. */ continue; cp = genindent(iwhite = backtab(c + value(SHIFTWIDTH) + 1)); ogcursor = cp; goto vbackup; } /* * ^D works only if we are at the (end of) the * generated autoindent. We count the ^D for repeat * purposes. */ if (c == iwhite && c != 0) { if (cp == gcursor) { iwhite = backtab(c); CDCNT++; ogcursor = cp = genindent(iwhite); goto vbackup; } else if (&cp[1] == gcursor && (*cp == '^' || *cp == '0')) { /* * ^^D moves to margin, then back * to current indent on next line. * * 0^D moves to margin and then * stays there. */ HADZERO = *cp == '0'; ogcursor = cp = genbuf; HADUP = 1 - HADZERO; CDCNT = 1; endim(); back1(); vputchar(' '); goto vbackup; } } if (vglobp && vglobp - iglobp >= 2 && (vglobp[-2] == '^' || vglobp[-2] == '0') && gcursor == ogcursor + 1) goto bakchar; continue; default: /* * Possibly discard control inputs. */ if (!vglobp && junk(c)) { beep(); continue; } def: if (!backsl) { /* int cnt; */ putchar(c); flush(); } if (gcursor > &genbuf[LBSIZE - 2]) error(catgets(catd, 1, 235, "Line too long")); gappend(c & TRIM); vcsync(); if (value(SHOWMATCH) && !iglobp) if (c == ')' || c == '}') lsmatch(gcursor); continue; } } vadone: *gcursor = 0; if (Outchar != termchar) Outchar = OO; endim(); return (gcursor); }
/*ARGSUSED*/ void vfilter(int unused) { register line *addr; register int cnt; char *oglobp; short d; #ifdef BIT8 cell cuxb[UXBSIZE + 2]; #endif if ((cnt = xdw()) < 0) return; if (vglobp) #ifdef BIT8 vglobp = cuxb; #else vglobp = uxb; #endif if (readecho('!')) return; oglobp = globp; globp = genbuf + 1; d = peekc; ungetchar(0); CATCH fixech(); unix0(0); #ifdef BIT8 str2cell(cuxb, uxb); #endif ONERR splitw = 0; ungetchar(d); vrepaint(cursor); globp = oglobp; return; ENDCATCH ungetchar(d); globp = oglobp; addr = dot; CATCH vgoto(WECHO, 0); flusho(); vremote(cnt, filter, 2); ONERR vdirty(0, TLINES); ENDCATCH if (dot == zero && dol > zero) dot = one; splitw = 0; notenam = ""; /* * BUG: we shouldn't be depending on what undap2 and undap1 are, * since we may be inside a macro. What's really wanted is the * number of lines we read from the filter. However, the mistake * will be an overestimate so it only results in extra work, * it shouldn't cause any real screwups. */ vreplace(vcline, cnt, undap2 - undap1); dot = addr; if (dot > dol) { dot--; vcline--; } vrepaint(NOSTR); }
/* * Get a keystroke, including a ^@. * If an key was returned with ungetkey, that * comes back first. Next comes unread input (e.g. * from repeating commands with .), and finally new * keystrokes. * * The hard work here is in mapping of \ escaped * characters on upper case only terminals. */ static int getbr(void) { char ch; register int c, d; register char *colp; #define BEEHIVE #ifdef BEEHIVE static char Peek2key; #endif extern short slevel, ttyindes; getATTN: if (Peekkey) { c = Peekkey; Peekkey = 0; return (c); } #ifdef BEEHIVE if (Peek2key) { c = Peek2key; Peek2key = 0; return (c); } #endif if (vglobp) { if (*vglobp) return (lastvgk = *vglobp++); lastvgk = 0; return (ESCAPE); } if (vmacp) { if (*vmacp) return(*vmacp++); /* End of a macro or set of nested macros */ vmacp = 0; if (inopen == -1) /* don't screw up undo for esc esc */ vundkind = VMANY; inopen = 1; /* restore old setting now that macro done */ vch_mac = VC_NOTINMAC; } flusho(); again: if (read(slevel == 0 ? 0 : ttyindes, &ch, 1) != 1) { if (errno == EINTR) goto getATTN; error("Input read error"); } c = ch & TRIM; #ifdef BEEHIVE if (XB && slevel==0 && c == ESCAPE) { if (read(0, &Peek2key, 1) != 1) goto getATTN; Peek2key &= TRIM; switch (Peek2key) { case 'C': /* SPOW mode sometimes sends \EC for space */ c = ' '; Peek2key = 0; break; case 'q': /* f2 -> ^C */ c = CTRL('c'); Peek2key = 0; break; case 'p': /* f1 -> esc */ Peek2key = 0; break; } } #endif #ifdef UCVISUAL /* * The algorithm here is that of the UNIX kernel. * See the description in the programmers manual. */ if (UPPERCASE) { if (isupper(c)) c = tolower(c); if (c == '\\') { if (precbksl < 2) precbksl++; if (precbksl == 1) goto again; } else if (precbksl) { d = 0; if (islower(c)) d = toupper(c); else { colp = "({)}!|^~'~"; while ((d = *colp++)) if (d == c) { d = *colp++; break; } else colp++; } if (precbksl == 2) { if (!d) { Peekkey = c; precbksl = 0; c = '\\'; } } else if (d) c = d; else { Peekkey = c; precbksl = 0; c = '\\'; } } if (c != '\\') precbksl = 0; } #endif #ifdef TRACE if (trace) { if (!techoin) { tfixnl(); techoin = 1; fprintf(trace, "*** Input: "); } tracec(c); } #endif lastvgk = 0; return (c); }
static void tmtmcwr(int ab, int tmc, int wr, int ep, int tmm) { const char tmtab[] = { 'a',000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, '{','}','&',000,'%','c','e',' ', '!',000,000,000,000,000,000,'~', 000 }; struct contab *cp; register int i, j; tchar c; char tmbuf[NTM]; filep savip = ip; int discard = 0; lgf++; if (tmm) { if (skip(1) || (i = getrq(0)) == 0) return; if ((cp = findmn(i)) == NULL || !cp->mx) { nosuch(i); return; } savip = ip; ip = (filep)cp->mx; app++; copyf++; } else { copyf++; if (skip(0) && ab) errprint("User Abort"); } loop: for (i = 0; i < NTM - 5 - mb_cur_max; ) { if (tmm) { if ((c = rbf()) == 0) { ip = savip; tmm = 0; app--; break; } } else c = getch(); if (discard) { discard--; continue; } if (c == '\n') { tmbuf[i++] = '\n'; break; } c: j = cbits(c); if (iscopy(c)) { int n; if ((n = wctomb(&tmbuf[i], j)) > 0) { i += n; continue; } } if (xflag == 0) { tmbuf[i++] = c; continue; } if (ismot(c)) continue; tmbuf[i++] = '\\'; if (c == (OHC|BLBIT)) j = ':'; else if (istrans(c)) j = ')'; else if (j >= 0 && j < sizeof tmtab && tmtab[j]) j = tmtab[j]; else if (j == ACUTE) j = '\''; else if (j == GRAVE) j = '`'; else if (j == UNDERLINE) j = '_'; else if (j == MINUS) j = '-'; else { i--; if (c == WORDSP) j = ' '; else if (j == WORDSP) continue; else if (j == FLSS) { discard++; continue; } } if (j == XFUNC) switch (fbits(c)) { case CHAR: c = charout[sbits(c)].ch; goto c; default: continue; } tmbuf[i++] = j; } if (i == NTM - 2) tmbuf[i++] = '\n'; if (tmc) i--; tmbuf[i] = 0; if (ab) /* truncate output */ obufp = obuf; /* should be a function in n2.c */ if (ep) { flusho(); errprint("%s", tmbuf); } else if (wr < 0) { flusho(); fdprintf(stderr, "%s", tmbuf); } else if (i) write(wr, tmbuf, i); if (tmm) goto loop; copyf--; lgf--; }
void casefl(void) { tbreak(); flusho(); }