예제 #1
0
파일: ex_put.c 프로젝트: chungy/ex-vi
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;
}
예제 #2
0
파일: n5.c 프로젝트: aksr/heirloom
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);
}
예제 #3
0
파일: ex_put.c 프로젝트: chungy/ex-vi
/*
 * 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);
}
예제 #4
0
파일: n10.c 프로젝트: 00001/plan9port
void n_ptpause(void )
{
	char	junk;

	flusho();
	read(2, &junk, 1);
}
예제 #5
0
파일: n7.c 프로젝트: 99years/plan9
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++;
}
예제 #6
0
파일: n5.c 프로젝트: aksr/heirloom
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);
}
예제 #7
0
파일: ex_put.c 프로젝트: chungy/ex-vi
void
flush2(void)
{

	fgoto();
	flusho();
	pstop();
}
예제 #8
0
파일: n5.c 프로젝트: aksr/heirloom
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);
		}
}
예제 #9
0
파일: ex_put.c 프로젝트: chungy/ex-vi
/*
 * Stop open, restoring tty modes.
 */
void
ostop(struct termios f)
{

	pfast = (f.c_oflag & ONLCR) == 0;
	termreset(), fgoto(), flusho();
	normal(f);
	tostop();
}
예제 #10
0
파일: n1.c 프로젝트: 99years/plan9
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();
}
예제 #11
0
void
done2(int x) 
{
	ptlead();
#ifndef NROFF
	if (!ascii)
		ptstop();
#endif
	flusho();
	done3(x);
}
예제 #12
0
/*
 * 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();
}
예제 #13
0
파일: n10.c 프로젝트: 00001/plan9port
void twdone(void)
{
	if (!TROFF && t.twrest) {
		obufp = obuf;
		oputs(t.twrest);
		flusho();
		if (pipeflg) {
			pclose(ptid);
		}
		restore_tty();
	}
}
예제 #14
0
twdone(){
	obufp = obuf;
	oputs(t.twrest);
	flusho();
	if(pipeflg){
		close(ptid);
		wait(&waitf);
	}
	if(ttysave != -1) {
		ttys.sg_flags = ttysave;
		stty(1, &ttys);
	}
}
예제 #15
0
파일: n7.c 프로젝트: 99years/plan9
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;
	}
}
예제 #16
0
파일: ex_v.c 프로젝트: n-t-roff/ex-3.7
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);
}
예제 #17
0
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);
	}
}
예제 #18
0
파일: jove_main.c 프로젝트: cciechad/brlcad
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);
}
예제 #19
0
파일: n7.c 프로젝트: 99years/plan9
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++;
}
예제 #20
0
파일: ex_vops2.c 프로젝트: n-t-roff/ex-2.2
/*
 * 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);
}
예제 #21
0
파일: n4.c 프로젝트: aahud/harvey
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);
}
예제 #22
0
파일: n7.c 프로젝트: 99years/plan9
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);
	}
}
예제 #23
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);
}
예제 #24
0
파일: ex_vops.c 프로젝트: chungy/ex-vi
/*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);
}
예제 #25
0
파일: ex_vget.c 프로젝트: n-t-roff/ex-3.6
/*
 * 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);
}
예제 #26
0
파일: n5.c 프로젝트: aksr/heirloom
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--;
}
예제 #27
0
파일: n5.c 프로젝트: aksr/heirloom
void
casefl(void)
{
	tbreak();
	flusho();
}