xref: /csrg-svn/usr.bin/ex/ex_subr.c (revision 63046)
148255Sbostic /*-
2*63046Sbostic  * Copyright (c) 1980, 1993
3*63046Sbostic  *	The Regents of the University of California.  All rights reserved.
448255Sbostic  *
548255Sbostic  * %sccs.include.proprietary.c%
621665Sdist  */
721665Sdist 
821665Sdist #ifndef lint
9*63046Sbostic static char sccsid[] = "@(#)ex_subr.c	8.1 (Berkeley) 06/09/93";
1048255Sbostic #endif /* not lint */
1121665Sdist 
12441Smark #include "ex.h"
13441Smark #include "ex_re.h"
14441Smark #include "ex_tty.h"
15441Smark #include "ex_vis.h"
1637881Sbostic #include "pathnames.h"
17441Smark 
18441Smark /*
19441Smark  * Random routines, in alphabetical order.
20441Smark  */
21441Smark 
any(c,s)22441Smark any(c, s)
23441Smark 	int c;
24441Smark 	register char *s;
25441Smark {
26441Smark 	register int x;
27441Smark 
28441Smark 	while (x = *s++)
29441Smark 		if (x == c)
30441Smark 			return (1);
31441Smark 	return (0);
32441Smark }
33441Smark 
backtab(i)34441Smark backtab(i)
35441Smark 	register int i;
36441Smark {
37441Smark 	register int j;
38441Smark 
39441Smark 	j = i % value(SHIFTWIDTH);
40441Smark 	if (j == 0)
41441Smark 		j = value(SHIFTWIDTH);
42441Smark 	i -= j;
43441Smark 	if (i < 0)
44441Smark 		i = 0;
45441Smark 	return (i);
46441Smark }
47441Smark 
change()48441Smark change()
49441Smark {
50441Smark 
51441Smark 	tchng++;
52441Smark 	chng = tchng;
53441Smark }
54441Smark 
55441Smark /*
56441Smark  * Column returns the number of
57441Smark  * columns occupied by printing the
58441Smark  * characters through position cp of the
59441Smark  * current line.
60441Smark  */
column(cp)61441Smark column(cp)
62441Smark 	register char *cp;
63441Smark {
64441Smark 
65441Smark 	if (cp == 0)
66441Smark 		cp = &linebuf[LBSIZE - 2];
67441Smark 	return (qcolumn(cp, (char *) 0));
68441Smark }
69441Smark 
70519Smark /*
71519Smark  * Ignore a comment to the end of the line.
72519Smark  * This routine eats the trailing newline so don't call newline().
73519Smark  */
comment()74519Smark comment()
75519Smark {
76519Smark 	register int c;
77519Smark 
78519Smark 	do {
7930596Sconrad 		c = ex_getchar();
80519Smark 	} while (c != '\n' && c != EOF);
81519Smark 	if (c == EOF)
82519Smark 		ungetchar(c);
83519Smark }
84519Smark 
Copy(to,from,size)85441Smark Copy(to, from, size)
86441Smark 	register char *from, *to;
87441Smark 	register int size;
88441Smark {
89441Smark 
90441Smark 	if (size > 0)
91441Smark 		do
92441Smark 			*to++ = *from++;
93441Smark 		while (--size > 0);
94441Smark }
95441Smark 
copyw(to,from,size)96441Smark copyw(to, from, size)
97441Smark 	register line *from, *to;
98441Smark 	register int size;
99441Smark {
100441Smark 	if (size > 0)
101441Smark 		do
102441Smark 			*to++ = *from++;
103441Smark 		while (--size > 0);
104441Smark }
105441Smark 
copywR(to,from,size)106441Smark copywR(to, from, size)
107441Smark 	register line *from, *to;
108441Smark 	register int size;
109441Smark {
110441Smark 
111441Smark 	while (--size >= 0)
112441Smark 		to[size] = from[size];
113441Smark }
114441Smark 
ctlof(c)115441Smark ctlof(c)
116441Smark 	int c;
117441Smark {
118441Smark 
119441Smark 	return (c == TRIM ? '?' : c | ('A' - 1));
120441Smark }
121441Smark 
dingdong()122441Smark dingdong()
123441Smark {
124441Smark 
125441Smark 	if (VB)
126441Smark 		putpad(VB);
127441Smark 	else if (value(ERRORBELLS))
128441Smark 		putch('\207');
129441Smark }
130441Smark 
fixindent(indent)131441Smark fixindent(indent)
132441Smark 	int indent;
133441Smark {
134441Smark 	register int i;
135441Smark 	register char *cp;
136441Smark 
137441Smark 	i = whitecnt(genbuf);
138441Smark 	cp = vpastwh(genbuf);
139441Smark 	if (*cp == 0 && i == indent && linebuf[0] == 0) {
140441Smark 		genbuf[0] = 0;
141441Smark 		return (i);
142441Smark 	}
143441Smark 	CP(genindent(i), cp);
144441Smark 	return (i);
145441Smark }
146441Smark 
filioerr(cp)147441Smark filioerr(cp)
148441Smark 	char *cp;
149441Smark {
150441Smark 	register int oerrno = errno;
151441Smark 
152441Smark 	lprintf("\"%s\"", cp);
153441Smark 	errno = oerrno;
154441Smark 	syserror();
155441Smark }
156441Smark 
157441Smark char *
genindent(indent)158441Smark genindent(indent)
159441Smark 	register int indent;
160441Smark {
161441Smark 	register char *cp;
162441Smark 
163441Smark 	for (cp = genbuf; indent >= value(TABSTOP); indent -= value(TABSTOP))
164441Smark 		*cp++ = '\t';
165441Smark 	for (; indent > 0; indent--)
166441Smark 		*cp++ = ' ';
167441Smark 	return (cp);
168441Smark }
169441Smark 
getDOT()170441Smark getDOT()
171441Smark {
172441Smark 
173441Smark 	getline(*dot);
174441Smark }
175441Smark 
176441Smark line *
getmark(c)177441Smark getmark(c)
178441Smark 	register int c;
179441Smark {
180441Smark 	register line *addr;
181441Smark 
182441Smark 	for (addr = one; addr <= dol; addr++)
183441Smark 		if (names[c - 'a'] == (*addr &~ 01)) {
184441Smark 			return (addr);
185441Smark 		}
186441Smark 	return (0);
187441Smark }
188441Smark 
getn(cp)189441Smark getn(cp)
190441Smark 	register char *cp;
191441Smark {
192441Smark 	register int i = 0;
193441Smark 
194441Smark 	while (isdigit(*cp))
195441Smark 		i = i * 10 + *cp++ - '0';
196441Smark 	if (*cp)
197441Smark 		return (0);
198441Smark 	return (i);
199441Smark }
200441Smark 
ignnEOF()201441Smark ignnEOF()
202441Smark {
20330596Sconrad 	register int c = ex_getchar();
204441Smark 
205441Smark 	if (c == EOF)
206441Smark 		ungetchar(c);
207519Smark 	else if (c=='"')
208519Smark 		comment();
209441Smark }
210441Smark 
iswhite(c)211441Smark iswhite(c)
212441Smark 	int c;
213441Smark {
214441Smark 
215441Smark 	return (c == ' ' || c == '\t');
216441Smark }
217441Smark 
junk(c)218441Smark junk(c)
219441Smark 	register int c;
220441Smark {
221441Smark 
222441Smark 	if (c && !value(BEAUTIFY))
223441Smark 		return (0);
224441Smark 	if (c >= ' ' && c != TRIM)
225441Smark 		return (0);
226441Smark 	switch (c) {
227441Smark 
228441Smark 	case '\t':
229441Smark 	case '\n':
230441Smark 	case '\f':
231441Smark 		return (0);
232441Smark 
233441Smark 	default:
234441Smark 		return (1);
235441Smark 	}
236441Smark }
237441Smark 
killed()238441Smark killed()
239441Smark {
240441Smark 
241441Smark 	killcnt(addr2 - addr1 + 1);
242441Smark }
243441Smark 
killcnt(cnt)244441Smark killcnt(cnt)
245441Smark 	register int cnt;
246441Smark {
247441Smark 
248441Smark 	if (inopen) {
249441Smark 		notecnt = cnt;
250441Smark 		notenam = notesgn = "";
251441Smark 		return;
252441Smark 	}
253441Smark 	if (!notable(cnt))
254441Smark 		return;
25530596Sconrad 	ex_printf("%d lines", cnt);
256441Smark 	if (value(TERSE) == 0) {
25730596Sconrad 		ex_printf(" %c%s", Command[0] | ' ', Command + 1);
258441Smark 		if (Command[strlen(Command) - 1] != 'e')
25930596Sconrad 			ex_putchar('e');
26030596Sconrad 		ex_putchar('d');
261441Smark 	}
262441Smark 	putNFL();
263441Smark }
264441Smark 
lineno(a)265441Smark lineno(a)
266441Smark 	line *a;
267441Smark {
268441Smark 
269441Smark 	return (a - zero);
270441Smark }
271441Smark 
lineDOL()272441Smark lineDOL()
273441Smark {
274441Smark 
275441Smark 	return (lineno(dol));
276441Smark }
277441Smark 
lineDOT()278441Smark lineDOT()
279441Smark {
280441Smark 
281441Smark 	return (lineno(dot));
282441Smark }
283441Smark 
markDOT()284441Smark markDOT()
285441Smark {
286441Smark 
287441Smark 	markpr(dot);
288441Smark }
289441Smark 
markpr(which)290441Smark markpr(which)
291441Smark 	line *which;
292441Smark {
293441Smark 
294441Smark 	if ((inglobal == 0 || inopen) && which <= endcore) {
295441Smark 		names['z'-'a'+1] = *which & ~01;
296441Smark 		if (inopen)
297441Smark 			ncols['z'-'a'+1] = cursor;
298441Smark 	}
299441Smark }
300441Smark 
markreg(c)301441Smark markreg(c)
302441Smark 	register int c;
303441Smark {
304441Smark 
305441Smark 	if (c == '\'' || c == '`')
306441Smark 		return ('z' + 1);
307441Smark 	if (c >= 'a' && c <= 'z')
308441Smark 		return (c);
309441Smark 	return (0);
310441Smark }
311441Smark 
312441Smark /*
313441Smark  * Mesg decodes the terse/verbose strings. Thus
314441Smark  *	'xxx@yyy' -> 'xxx' if terse, else 'xxx yyy'
315441Smark  *	'xxx|yyy' -> 'xxx' if terse, else 'yyy'
316441Smark  * All others map to themselves.
317441Smark  */
318441Smark char *
mesg(str)319441Smark mesg(str)
320441Smark 	register char *str;
321441Smark {
322441Smark 	register char *cp;
323441Smark 
324441Smark 	str = strcpy(genbuf, str);
325441Smark 	for (cp = str; *cp; cp++)
326441Smark 		switch (*cp) {
327441Smark 
328441Smark 		case '@':
329441Smark 			if (value(TERSE))
330441Smark 				*cp = 0;
331441Smark 			else
332441Smark 				*cp = ' ';
333441Smark 			break;
334441Smark 
335441Smark 		case '|':
336441Smark 			if (value(TERSE) == 0)
337441Smark 				return (cp + 1);
338441Smark 			*cp = 0;
339441Smark 			break;
340441Smark 		}
341441Smark 	return (str);
342441Smark }
343441Smark 
344441Smark /*VARARGS2*/
merror(seekpt,i)345441Smark merror(seekpt, i)
34630596Sconrad #ifndef EXSTRINGS
347441Smark 	char *seekpt;
348441Smark #else
349474Smark # ifdef lint
350474Smark 	char *seekpt;
351474Smark # else
352441Smark 	int seekpt;
353474Smark # endif
354441Smark #endif
355441Smark 	int i;
356441Smark {
357441Smark 	register char *cp = linebuf;
358441Smark 
359441Smark 	if (seekpt == 0)
360441Smark 		return;
361441Smark 	merror1(seekpt);
362441Smark 	if (*cp == '\n')
363441Smark 		putnl(), cp++;
36421690Sdist 	if (inopen > 0 && CE)
365441Smark 		vclreol();
366441Smark 	if (SO && SE)
367441Smark 		putpad(SO);
36830596Sconrad 	ex_printf(mesg(cp), i);
369441Smark 	if (SO && SE)
370441Smark 		putpad(SE);
371441Smark }
372441Smark 
merror1(seekpt)373441Smark merror1(seekpt)
37430596Sconrad #ifndef EXSTRINGS
375441Smark 	char *seekpt;
376441Smark #else
377474Smark # ifdef lint
378474Smark 	char *seekpt;
379474Smark # else
380441Smark 	int seekpt;
381474Smark # endif
382441Smark #endif
383441Smark {
384441Smark 
38530596Sconrad #ifndef EXSTRINGS
386474Smark 	strcpy(linebuf, seekpt);
387474Smark #else
388441Smark 	lseek(erfile, (long) seekpt, 0);
389441Smark 	if (read(erfile, linebuf, 128) < 2)
390441Smark 		CP(linebuf, "ERROR");
391474Smark #endif
392441Smark }
393441Smark 
morelines()394441Smark morelines()
395441Smark {
39630596Sconrad #ifdef UNIX_SBRK
39730596Sconrad 	char *sbrk();
398441Smark 
399441Smark 	if ((int) sbrk(1024 * sizeof (line)) == -1)
400441Smark 		return (-1);
401441Smark 	endcore += 1024;
402441Smark 	return (0);
40330596Sconrad #else
40430596Sconrad 	/*
40530596Sconrad 	 * We can never be guaranteed that we can get more memory
40630596Sconrad 	 * beyond "endcore".  So we just punt every time.
40730596Sconrad 	 */
40830596Sconrad 	return -1;
40930596Sconrad #endif
410441Smark }
411441Smark 
nonzero()412441Smark nonzero()
413441Smark {
414441Smark 
415441Smark 	if (addr1 == zero) {
416441Smark 		notempty();
417441Smark 		error("Nonzero address required@on this command");
418441Smark 	}
419441Smark }
420441Smark 
notable(i)421441Smark notable(i)
422441Smark 	int i;
423441Smark {
424441Smark 
425441Smark 	return (hush == 0 && !inglobal && i > value(REPORT));
426441Smark }
427441Smark 
428441Smark 
notempty()429441Smark notempty()
430441Smark {
431441Smark 
432441Smark 	if (dol == zero)
433441Smark 		error("No lines@in the buffer");
434441Smark }
435441Smark 
436441Smark 
netchHAD(cnt)437441Smark netchHAD(cnt)
438441Smark 	int cnt;
439441Smark {
440441Smark 
441441Smark 	netchange(lineDOL() - cnt);
442441Smark }
443441Smark 
netchange(i)444441Smark netchange(i)
445441Smark 	register int i;
446441Smark {
447441Smark 	register char *cp;
448441Smark 
449441Smark 	if (i > 0)
450441Smark 		notesgn = cp = "more ";
451441Smark 	else
452441Smark 		notesgn = cp = "fewer ", i = -i;
453441Smark 	if (inopen) {
454441Smark 		notecnt = i;
455441Smark 		notenam = "";
456441Smark 		return;
457441Smark 	}
458441Smark 	if (!notable(i))
459441Smark 		return;
46030596Sconrad 	ex_printf(mesg("%d %slines@in file after %s"), i, cp, Command);
461441Smark 	putNFL();
462441Smark }
463441Smark 
putmark(addr)464441Smark putmark(addr)
465441Smark 	line *addr;
466441Smark {
467441Smark 
468441Smark 	putmk1(addr, putline());
469441Smark }
470441Smark 
putmk1(addr,n)471441Smark putmk1(addr, n)
472441Smark 	register line *addr;
473441Smark 	int n;
474441Smark {
475441Smark 	register line *markp;
476519Smark 	register oldglobmk;
477441Smark 
478519Smark 	oldglobmk = *addr & 1;
479441Smark 	*addr &= ~1;
480441Smark 	for (markp = (anymarks ? names : &names['z'-'a'+1]);
481441Smark 	  markp <= &names['z'-'a'+1]; markp++)
482441Smark 		if (*markp == *addr)
483441Smark 			*markp = n;
484519Smark 	*addr = n | oldglobmk;
485441Smark }
486441Smark 
487441Smark char *
plural(i)488441Smark plural(i)
489441Smark 	long i;
490441Smark {
491441Smark 
492441Smark 	return (i == 1 ? "" : "s");
493441Smark }
494441Smark 
495441Smark int	qcount();
496441Smark short	vcntcol;
497441Smark 
qcolumn(lim,gp)498441Smark qcolumn(lim, gp)
499441Smark 	register char *lim, *gp;
500441Smark {
501441Smark 	register int x;
502441Smark 	int (*OO)();
503441Smark 
504441Smark 	OO = Outchar;
505441Smark 	Outchar = qcount;
506441Smark 	vcntcol = 0;
507441Smark 	if (lim != NULL)
508441Smark 		x = lim[1], lim[1] = 0;
509441Smark 	pline(0);
510441Smark 	if (lim != NULL)
511441Smark 		lim[1] = x;
512441Smark 	if (gp)
513441Smark 		while (*gp)
51430596Sconrad 			ex_putchar(*gp++);
515441Smark 	Outchar = OO;
516441Smark 	return (vcntcol);
517441Smark }
518441Smark 
519441Smark int
qcount(c)520441Smark qcount(c)
521441Smark 	int c;
522441Smark {
523441Smark 
524441Smark 	if (c == '\t') {
525441Smark 		vcntcol += value(TABSTOP) - vcntcol % value(TABSTOP);
526441Smark 		return;
527441Smark 	}
528441Smark 	vcntcol++;
529441Smark }
530441Smark 
reverse(a1,a2)531441Smark reverse(a1, a2)
532441Smark 	register line *a1, *a2;
533441Smark {
534441Smark 	register line t;
535441Smark 
536441Smark 	for (;;) {
537441Smark 		t = *--a2;
538441Smark 		if (a2 <= a1)
539441Smark 			return;
540441Smark 		*a2 = *a1;
541441Smark 		*a1++ = t;
542441Smark 	}
543441Smark }
544441Smark 
save(a1,a2)545441Smark save(a1, a2)
546441Smark 	line *a1;
547441Smark 	register line *a2;
548441Smark {
549441Smark 	register int more;
550441Smark 
551493Smark 	if (!FIXUNDO)
552493Smark 		return;
553493Smark #ifdef TRACE
554493Smark 	if (trace)
555493Smark 		vudump("before save");
556493Smark #endif
557441Smark 	undkind = UNDNONE;
558441Smark 	undadot = dot;
559441Smark 	more = (a2 - a1 + 1) - (unddol - dol);
560441Smark 	while (more > (endcore - truedol))
561441Smark 		if (morelines() < 0)
56230596Sconrad #ifdef UNIX_SBRK
56321690Sdist 			error("Out of memory@saving lines for undo - try using ed");
56430596Sconrad #else
56530596Sconrad 			error("Out of memory@saving lines for undo - try increasing linelimit");
56630596Sconrad #endif
567441Smark 	if (more)
568441Smark 		(*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
569441Smark 		    (truedol - unddol));
570441Smark 	unddol += more;
571441Smark 	truedol += more;
572441Smark 	copyw(dol + 1, a1, a2 - a1 + 1);
573441Smark 	undkind = UNDALL;
574441Smark 	unddel = a1 - 1;
575441Smark 	undap1 = a1;
576441Smark 	undap2 = a2 + 1;
577493Smark #ifdef TRACE
578493Smark 	if (trace)
579493Smark 		vudump("after save");
580493Smark #endif
581441Smark }
582441Smark 
save12()583441Smark save12()
584441Smark {
585441Smark 
586441Smark 	save(addr1, addr2);
587441Smark }
588441Smark 
saveall()589441Smark saveall()
590441Smark {
591441Smark 
592441Smark 	save(one, dol);
593441Smark }
594441Smark 
span()595441Smark span()
596441Smark {
597441Smark 
598441Smark 	return (addr2 - addr1 + 1);
599441Smark }
600441Smark 
ex_sync()60130596Sconrad ex_sync()
602441Smark {
603441Smark 
604441Smark 	chng = 0;
605441Smark 	tchng = 0;
606441Smark 	xchng = 0;
607441Smark }
608441Smark 
609441Smark 
skipwh()610441Smark skipwh()
611441Smark {
612441Smark 	register int wh;
613441Smark 
614441Smark 	wh = 0;
615441Smark 	while (iswhite(peekchar())) {
616441Smark 		wh++;
617441Smark 		ignchar();
618441Smark 	}
619441Smark 	return (wh);
620441Smark }
621441Smark 
622441Smark /*VARARGS2*/
smerror(seekpt,cp)623441Smark smerror(seekpt, cp)
624441Smark #ifdef lint
625441Smark 	char *seekpt;
626441Smark #else
627441Smark 	int seekpt;
628441Smark #endif
629441Smark 	char *cp;
630441Smark {
631441Smark 
632441Smark 	if (seekpt == 0)
633441Smark 		return;
634441Smark 	merror1(seekpt);
635441Smark 	if (inopen && CE)
636441Smark 		vclreol();
637441Smark 	if (SO && SE)
638441Smark 		putpad(SO);
639441Smark 	lprintf(mesg(linebuf), cp);
640441Smark 	if (SO && SE)
641441Smark 		putpad(SE);
642441Smark }
643441Smark 
644441Smark char *
strend(cp)645441Smark strend(cp)
646441Smark 	register char *cp;
647441Smark {
648441Smark 
649441Smark 	while (*cp)
650441Smark 		cp++;
651441Smark 	return (cp);
652441Smark }
653441Smark 
strcLIN(dp)654441Smark strcLIN(dp)
655441Smark 	char *dp;
656441Smark {
657441Smark 
658441Smark 	CP(linebuf, dp);
659441Smark }
660441Smark 
syserror()661441Smark syserror()
662441Smark {
66342421Sbostic 	char *strerror();
664441Smark 
665441Smark 	dirtcnt = 0;
66630596Sconrad 	ex_putchar(' ');
66742421Sbostic 	error(strerror(errno));
668441Smark }
669441Smark 
670519Smark /*
671519Smark  * Return the column number that results from being in column col and
672519Smark  * hitting a tab, where tabs are set every ts columns.  Work right for
673519Smark  * the case where col > COLUMNS, even if ts does not divide COLUMNS.
674519Smark  */
tabcol(col,ts)675519Smark tabcol(col, ts)
676519Smark int col, ts;
677519Smark {
678519Smark 	int offset, result;
679519Smark 
680519Smark 	if (col >= COLUMNS) {
681519Smark 		offset = COLUMNS * (col/COLUMNS);
682519Smark 		col -= offset;
683519Smark 	} else
684519Smark 		offset = 0;
685519Smark 	result = col + ts - (col % ts) + offset;
686519Smark 	return (result);
687519Smark }
688519Smark 
689441Smark char *
vfindcol(i)690441Smark vfindcol(i)
691441Smark 	int i;
692441Smark {
693441Smark 	register char *cp;
694441Smark 	register int (*OO)() = Outchar;
695441Smark 
696441Smark 	Outchar = qcount;
697441Smark 	ignore(qcolumn(linebuf - 1, NOSTR));
698441Smark 	for (cp = linebuf; *cp && vcntcol < i; cp++)
69930596Sconrad 		ex_putchar(*cp);
700441Smark 	if (cp != linebuf)
701441Smark 		cp--;
702441Smark 	Outchar = OO;
703441Smark 	return (cp);
704441Smark }
705441Smark 
706441Smark char *
vskipwh(cp)707441Smark vskipwh(cp)
708441Smark 	register char *cp;
709441Smark {
710441Smark 
711441Smark 	while (iswhite(*cp) && cp[1])
712441Smark 		cp++;
713441Smark 	return (cp);
714441Smark }
715441Smark 
716441Smark 
717441Smark char *
vpastwh(cp)718441Smark vpastwh(cp)
719441Smark 	register char *cp;
720441Smark {
721441Smark 
722441Smark 	while (iswhite(*cp))
723441Smark 		cp++;
724441Smark 	return (cp);
725441Smark }
726441Smark 
whitecnt(cp)727441Smark whitecnt(cp)
728441Smark 	register char *cp;
729441Smark {
730441Smark 	register int i;
731441Smark 
732441Smark 	i = 0;
733441Smark 	for (;;)
734441Smark 		switch (*cp++) {
735441Smark 
736441Smark 		case '\t':
737441Smark 			i += value(TABSTOP) - i % value(TABSTOP);
738441Smark 			break;
739441Smark 
740441Smark 		case ' ':
741441Smark 			i++;
742441Smark 			break;
743441Smark 
744441Smark 		default:
745441Smark 			return (i);
746441Smark 		}
747441Smark }
748441Smark 
749441Smark #ifdef lint
Ignore(a)750441Smark Ignore(a)
751441Smark 	char *a;
752441Smark {
753441Smark 
754441Smark 	a = a;
755441Smark }
756441Smark 
757441Smark Ignorf(a)
758441Smark 	int (*a)();
759441Smark {
760441Smark 
761441Smark 	a = a;
762441Smark }
763441Smark #endif
764441Smark 
markit(addr)765441Smark markit(addr)
766441Smark 	line *addr;
767441Smark {
768441Smark 
769441Smark 	if (addr != dot && addr >= one && addr <= dol)
770441Smark 		markDOT();
771441Smark }
77221690Sdist 
77321690Sdist /*
77421690Sdist  * The following code is defensive programming against a bug in the
77521690Sdist  * pdp-11 overlay implementation.  Sometimes it goes nuts and asks
77621690Sdist  * for an overlay with some garbage number, which generates an emt
77721690Sdist  * trap.  This is a less than elegant solution, but it is somewhat
77821690Sdist  * better than core dumping and losing your work, leaving your tty
77921690Sdist  * in a weird state, etc.
78021690Sdist  */
78121690Sdist int _ovno;
78246826Sbostic void
onemt()78321690Sdist onemt()
78421690Sdist {
78521690Sdist 	signal(SIGEMT, onemt);
78621690Sdist 	/* 2 and 3 are valid on 11/40 type vi, so */
78721690Sdist 	if (_ovno < 0 || _ovno > 3)
78821690Sdist 		_ovno = 0;
78921690Sdist 	error("emt trap, _ovno is %d @ - try again");
79021690Sdist }
79121690Sdist 
79221690Sdist /*
79321690Sdist  * When a hangup occurs our actions are similar to a preserve
79421690Sdist  * command.  If the buffer has not been [Modified], then we do
79521690Sdist  * nothing but remove the temporary files and exit.
79621690Sdist  * Otherwise, we sync the temp file and then attempt a preserve.
79721690Sdist  * If the preserve succeeds, we unlink our temp files.
79821690Sdist  * If the preserve fails, we leave the temp files as they are
79921690Sdist  * as they are a backup even without preservation if they
80021690Sdist  * are not removed.
80121690Sdist  */
80246826Sbostic void
onhup()80321690Sdist onhup()
80421690Sdist {
80521690Sdist 
80621690Sdist 	/*
80721690Sdist 	 * USG tty driver can send multiple HUP's!!
80821690Sdist 	 */
80921690Sdist 	signal(SIGINT, SIG_IGN);
81021690Sdist 	signal(SIGHUP, SIG_IGN);
81121690Sdist 	if (chng == 0) {
81221690Sdist 		cleanup(1);
81330596Sconrad 		ex_exit(0);
81421690Sdist 	}
81521690Sdist 	if (setexit() == 0) {
81621690Sdist 		if (preserve()) {
81721690Sdist 			cleanup(1);
81830596Sconrad 			ex_exit(0);
81921690Sdist 		}
82021690Sdist 	}
82130596Sconrad 	ex_exit(1);
82221690Sdist }
82321690Sdist 
82421690Sdist /*
82521690Sdist  * An interrupt occurred.  Drain any output which
82621690Sdist  * is still in the output buffering pipeline.
82721690Sdist  * Catch interrupts again.  Unless we are in visual
82821690Sdist  * reset the output state (out of -nl mode, e.g).
82921690Sdist  * Then like a normal error (with the \n before Interrupt
83021690Sdist  * suppressed in visual mode).
83121690Sdist  */
83246826Sbostic void
onintr()83321690Sdist onintr()
83421690Sdist {
83521690Sdist 
83621690Sdist #ifndef CBREAK
83721690Sdist 	signal(SIGINT, onintr);
83821690Sdist #else
83921690Sdist 	signal(SIGINT, inopen ? vintr : onintr);
84021690Sdist #endif
84121690Sdist 	alarm(0);	/* in case we were called from map */
84221690Sdist 	draino();
84321690Sdist 	if (!inopen) {
84421690Sdist 		pstop();
84521690Sdist 		setlastchar('\n');
84621690Sdist #ifdef CBREAK
84721690Sdist 	}
84821690Sdist #else
84921690Sdist 	} else
85021690Sdist 		vraw();
85121690Sdist #endif
85221690Sdist 	error("\nInterrupt" + inopen);
85321690Sdist }
85421690Sdist 
85521690Sdist /*
85621690Sdist  * If we are interruptible, enable interrupts again.
85721690Sdist  * In some critical sections we turn interrupts off,
85821690Sdist  * but not very often.
85921690Sdist  */
setrupt()86021690Sdist setrupt()
86121690Sdist {
86221690Sdist 
86321690Sdist 	if (ruptible) {
86421690Sdist #ifndef CBREAK
86521690Sdist 		signal(SIGINT, onintr);
86621690Sdist #else
86721690Sdist 		signal(SIGINT, inopen ? vintr : onintr);
86821690Sdist #endif
86921690Sdist #ifdef SIGTSTP
87021690Sdist 		if (dosusp)
87121690Sdist 			signal(SIGTSTP, onsusp);
87221690Sdist #endif
87321690Sdist 	}
87421690Sdist }
87521690Sdist 
preserve()87621690Sdist preserve()
87721690Sdist {
87821690Sdist 
87921690Sdist #ifdef VMUNIX
88021690Sdist 	tflush();
88121690Sdist #endif
88221690Sdist 	synctmp();
88330596Sconrad 	pid = vfork();
88421690Sdist 	if (pid < 0)
88521690Sdist 		return (0);
88621690Sdist 	if (pid == 0) {
88721690Sdist 		close(0);
88821690Sdist 		dup(tfile);
88937881Sbostic 		execl(_PATH_EXPRESERVE, "expreserve", (char *) 0);
89030596Sconrad 		ex_exit(1);
89121690Sdist 	}
89221690Sdist 	waitfor();
89321690Sdist 	if (rpid == pid && status == 0)
89421690Sdist 		return (1);
89521690Sdist 	return (0);
89621690Sdist }
89721690Sdist 
89821690Sdist #ifndef V6
ex_exit(i)89930596Sconrad ex_exit(i)
90021690Sdist 	int i;
90121690Sdist {
90221690Sdist 
90321690Sdist # ifdef TRACE
90421690Sdist 	if (trace)
90521690Sdist 		fclose(trace);
90621690Sdist # endif
90721690Sdist 	_exit(i);
90821690Sdist }
90921690Sdist #endif
91021690Sdist 
91121690Sdist #ifdef SIGTSTP
91221690Sdist /*
91321690Sdist  * We have just gotten a susp.  Suspend and prepare to resume.
91421690Sdist  */
91546826Sbostic void
onsusp()91621690Sdist onsusp()
91721690Sdist {
91821690Sdist 	ttymode f;
91921690Sdist 	struct winsize win;
92021690Sdist 
92121690Sdist 	f = setty(normf);
92221690Sdist 	vnfl();
92321690Sdist 	putpad(TE);
92421690Sdist 	flush();
92521690Sdist 
92621690Sdist 	(void) sigsetmask(0);
92721690Sdist 	signal(SIGTSTP, SIG_DFL);
92821690Sdist 	kill(0, SIGTSTP);
92921690Sdist 
93021690Sdist 	/* the pc stops here */
93121690Sdist 
93221690Sdist 	signal(SIGTSTP, onsusp);
93321690Sdist 	vcontin(0);
93430596Sconrad 	ignore(setty(f));
93521690Sdist 	if (!inopen)
93630596Sconrad 		error((char *) 0);
93721690Sdist 	else {
93830596Sconrad #ifdef	TIOCGWINSZ
93921690Sdist 		if (ioctl(0, TIOCGWINSZ, &win) >= 0)
94021690Sdist 			if (win.ws_row != winsz.ws_row ||
94121690Sdist 			    win.ws_col != winsz.ws_col)
94221690Sdist 				winch();
94330596Sconrad #endif
94421690Sdist 		if (vcnt < 0) {
94521690Sdist 			vcnt = -vcnt;
94621690Sdist 			if (state == VISUAL)
94721690Sdist 				vclear();
94821690Sdist 			else if (state == CRTOPEN)
94921690Sdist 				vcnt = 0;
95021690Sdist 		}
95121690Sdist 		vdirty(0, LINES);
95221690Sdist 		vrepaint(cursor);
95321690Sdist 	}
95421690Sdist }
95521690Sdist #endif
956