|
|
1.1 root 1: /* $Header: term.c,v 4.3.1.2 85/05/16 16:45:35 lwall Exp $
2: *
3: * $Log: term.c,v $
4: * Revision 4.3.1.2 85/05/16 16:45:35 lwall
5: * Forced \r to \n on input.
6: * Fix for terminfo braindamage regarding bc emulation.
7: *
8: * Revision 4.3.1.1 85/05/10 11:41:03 lwall
9: * Branch for patches.
10: *
11: * Revision 4.3 85/05/01 11:51:10 lwall
12: * Baseline for release with 4.3bsd.
13: *
14: */
15:
16: #include "EXTERN.h"
17: #include "common.h"
18: #include "util.h"
19: #include "final.h"
20: #include "help.h"
21: #include "cheat.h"
22: #include "intrp.h"
23: #include "INTERN.h"
24: #include "term.h"
25:
26: char ERASECH; /* rubout character */
27: char KILLCH; /* line delete character */
28: char tcarea[TCSIZE]; /* area for "compiled" termcap strings */
29:
30: /* guarantee capability pointer != Nullch */
31: /* (I believe terminfo will ignore the &tmpaddr argument.) */
32:
33: #define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
34:
35: #ifdef PUSHBACK
36: struct keymap {
37: char km_type[128];
38: union km_union {
39: struct keymap *km_km;
40: char *km_str;
41: } km_ptr[128];
42: };
43:
44: #define KM_NOTHIN 0
45: #define KM_STRING 1
46: #define KM_KEYMAP 2
47: #define KM_BOGUS 3
48:
49: #define KM_TMASK 3
50: #define KM_GSHIFT 4
51: #define KM_GMASK 7
52:
53: typedef struct keymap KEYMAP;
54:
55: KEYMAP *topmap INIT(Null(KEYMAP*));
56:
57: void mac_init();
58: KEYMAP *newkeymap();
59: void show_keymap();
60: void pushstring();
61: #endif
62:
63: /* terminal initialization */
64:
65: void
66: term_init()
67: {
68: savetty(); /* remember current tty state */
69:
70: #ifdef TERMIO
71: ospeed = _tty.c_cflag & CBAUD; /* for tputs() */
72: ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
73: KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
74: #else
75: ospeed = _tty.sg_ospeed; /* for tputs() */
76: ERASECH = _tty.sg_erase; /* for finish_command() */
77: KILLCH = _tty.sg_kill; /* for finish_command() */
78: #endif
79:
80: /* The following could be a table but I can't be sure that there isn't */
81: /* some degree of sparsity out there in the world. */
82:
83: switch (ospeed) { /* 1 second of padding */
84: #ifdef BEXTA
85: case BEXTA: just_a_sec = 1920; break;
86: #else
87: #ifdef B19200
88: case B19200: just_a_sec = 1920; break;
89: #endif
90: #endif
91: case B9600: just_a_sec = 960; break;
92: case B4800: just_a_sec = 480; break;
93: case B2400: just_a_sec = 240; break;
94: case B1800: just_a_sec = 180; break;
95: case B1200: just_a_sec = 120; break;
96: case B600: just_a_sec = 60; break;
97: case B300: just_a_sec = 30; break;
98: /* do I really have to type the rest of this??? */
99: case B200: just_a_sec = 20; break;
100: case B150: just_a_sec = 15; break;
101: case B134: just_a_sec = 13; break;
102: case B110: just_a_sec = 11; break;
103: case B75: just_a_sec = 8; break;
104: case B50: just_a_sec = 5; break;
105: default: just_a_sec = 960; break;
106: /* if we are running detached I */
107: } /* don't want to know about it! */
108: }
109:
110: /* set terminal characteristics */
111:
112: void
113: term_set(tcbuf)
114: char *tcbuf; /* temp area for "uncompiled" termcap entry */
115: {
116: char *tmpaddr; /* must not be register */
117: register char *tmpstr;
118: char *tgetstr();
119: char *s;
120: int status;
121:
122: #ifdef PENDING
123: #ifndef FIONREAD
124: /* do no delay reads on something that always gets closed on exit */
125:
126: devtty = open("/dev/tty",0);
127: if (devtty < 0) {
128: printf(cantopen,"/dev/tty") FLUSH;
129: finalize(1);
130: }
131: fcntl(devtty,F_SETFL,O_NDELAY);
132: #endif
133: #endif
134:
135: /* get all that good termcap stuff */
136:
137: #ifdef HAVETERMLIB
138: status = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */
139: if (status < 1) {
140: #ifdef VERBOSE
141: printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
142: #else
143: fputs("Termcap botch\n",stdout) FLUSH
144: #endif
145: finalize(1);
146: }
147: tmpaddr = tcarea; /* set up strange tgetstr pointer */
148: s = Tgetstr("pc"); /* get pad character */
149: PC = *s; /* get it where tputs wants it */
150: if (!tgetflag("bs")) { /* is backspace not used? */
151: BC = Tgetstr("bc"); /* find out what is */
152: if (BC == nullstr) /* terminfo grok's 'bs' but not 'bc' */
153: BC = Tgetstr("le");
154: } else
155: BC = "\b"; /* make a backspace handy */
156: UP = Tgetstr("up"); /* move up a line */
157: if (!*UP) /* no UP string? */
158: marking = 0; /* disable any marking */
159: if (muck_up_clear) /* this is for weird HPs */
160: CL = "\n\n\n\n";
161: else
162: CL = Tgetstr("cl"); /* get clear string */
163: CE = Tgetstr("ce"); /* clear to end of line string */
164: #ifdef CLEAREOL
165: CM = Tgetstr("cm"); /* cursor motion - PWP */
166: HO = Tgetstr("ho"); /* home cursor if no CM - PWP */
167: CD = Tgetstr("cd"); /* clear to end of display - PWP */
168: if (!*CE || !*CD || (!*CM && !*HO)) /* can we CE, CD, and home? */
169: can_home_clear = FALSE; /* no, so disable use of clear eol */
170: #endif CLEAREOL
171: SO = Tgetstr("so"); /* begin standout */
172: SE = Tgetstr("se"); /* end standout */
173: if ((SG = tgetnum("sg"))<0)
174: SG = 0; /* blanks left by SG, SE */
175: US = Tgetstr("us"); /* start underline */
176: UE = Tgetstr("ue"); /* end underline */
177: if ((UG = tgetnum("ug"))<0)
178: UG = 0; /* blanks left by US, UE */
179: if (*US)
180: UC = nullstr; /* UC must not be NULL */
181: else
182: UC = Tgetstr("uc"); /* underline a character */
183: if (!*US && !*UC) { /* no underline mode? */
184: US = SO; /* substitute standout mode */
185: UE = SE;
186: UG = SG;
187: }
188: LINES = tgetnum("li"); /* lines per page */
189: COLS = tgetnum("co"); /* columns on page */
190: AM = tgetflag("am"); /* terminal wraps automatically? */
191: XN = tgetflag("xn"); /* then eats next newline? */
192: VB = Tgetstr("vb");
193: if (!*VB)
194: VB = "\007";
195: CR = Tgetstr("cr");
196: if (!*CR) {
197: if (tgetflag("nc") && *UP) {
198: CR = safemalloc((MEM_SIZE)strlen(UP)+2);
199: sprintf(CR,"%s\r",UP);
200: }
201: else
202: CR = "\r";
203: }
204: #else
205: ?????? /* Roll your own... */
206: #endif
207: if (LINES > 0) { /* is this a crt? */
208: if (!initlines) /* no -i? */
209: if (ospeed >= B9600) /* whole page at >= 9600 baud */
210: initlines = LINES;
211: else if (ospeed >= B4800) /* 16 lines at 4800 */
212: initlines = 16;
213: else /* otherwise just header */
214: initlines = 8;
215: }
216: else { /* not a crt */
217: LINES = 30000; /* so don't page */
218: CL = "\n\n"; /* put a couple of lines between */
219: if (!initlines) /* make initlines reasonable */
220: initlines = 8;
221: }
222: if (COLS <= 0)
223: COLS = 80;
224: noecho(); /* turn off echo */
225: crmode(); /* enter cbreak mode */
226:
227: #ifdef PUSHBACK
228: mac_init(tcbuf);
229: #endif
230: }
231:
232: #ifdef PUSHBACK
233: void
234: mac_init(tcbuf)
235: char *tcbuf;
236: {
237: char tmpbuf[1024];
238:
239: tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
240: if (tmpfp != Nullfp) {
241: while (fgets(tcbuf,1024,tmpfp) != Nullch) {
242: mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
243: }
244: fclose(tmpfp);
245: }
246: }
247:
248: void
249: mac_line(line,tmpbuf,tbsize)
250: char *line;
251: char *tmpbuf;
252: int tbsize;
253: {
254: register char *s, *m;
255: register KEYMAP *curmap;
256: register int ch;
257: register int garbage = 0;
258: static char override[] = "\nkeymap overrides string\n";
259:
260: if (topmap == Null(KEYMAP*))
261: topmap = newkeymap();
262: if (*line == '#' || *line == '\n')
263: return;
264: if (line[ch = strlen(line)-1] == '\n')
265: line[ch] = '\0';
266: m = dointerp(tmpbuf,tbsize,line," \t");
267: if (!*m)
268: return;
269: while (*m == ' ' || *m == '\t') m++;
270: for (s=tmpbuf,curmap=topmap; *s; s++) {
271: ch = *s & 0177;
272: if (s[1] == '+' && isdigit(s[2])) {
273: s += 2;
274: garbage = (*s & KM_GMASK) << KM_GSHIFT;
275: }
276: else
277: garbage = 0;
278: if (s[1]) {
279: if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
280: puts(override,stdout) FLUSH;
281: free(curmap->km_ptr[ch].km_str);
282: curmap->km_ptr[ch].km_str = Nullch;
283: }
284: curmap->km_type[ch] = KM_KEYMAP + garbage;
285: if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
286: curmap->km_ptr[ch].km_km = newkeymap();
287: curmap = curmap->km_ptr[ch].km_km;
288: }
289: else {
290: if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
291: puts(override,stdout) FLUSH;
292: else {
293: curmap->km_type[ch] = KM_STRING + garbage;
294: curmap->km_ptr[ch].km_str = savestr(m);
295: }
296: }
297: }
298: }
299:
300: KEYMAP*
301: newkeymap()
302: {
303: register int i;
304: register KEYMAP *map;
305:
306: #ifndef lint
307: map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
308: #else
309: map = Null(KEYMAP*);
310: #endif lint
311: for (i=127; i>=0; --i) {
312: map->km_ptr[i].km_km = Null(KEYMAP*);
313: map->km_type[i] = KM_NOTHIN;
314: }
315: return map;
316: }
317:
318: void
319: show_macros()
320: {
321: char prebuf[64];
322:
323: if (topmap != Null(KEYMAP*)) {
324: print_lines("Macros:\n",STANDOUT);
325: *prebuf = '\0';
326: show_keymap(topmap,prebuf);
327: }
328: }
329:
330: void
331: show_keymap(curmap,prefix)
332: register KEYMAP *curmap;
333: char *prefix;
334: {
335: register int i;
336: register char *next = prefix + strlen(prefix);
337: register int kt;
338:
339: for (i=0; i<128; i++) {
340: if (kt = curmap->km_type[i]) {
341: if (i < ' ')
342: sprintf(next,"^%c",i+64);
343: else if (i == ' ')
344: strcpy(next,"\\040");
345: else if (i == 127)
346: strcpy(next,"^?");
347: else
348: sprintf(next,"%c",i);
349: if ((kt >> KM_GSHIFT) & KM_GMASK) {
350: sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
351: strcat(next,cmd_buf);
352: }
353: switch (kt & KM_TMASK) {
354: case KM_NOTHIN:
355: sprintf(cmd_buf,"%s %c\n",prefix,i);
356: print_lines(cmd_buf,NOMARKING);
357: break;
358: case KM_KEYMAP:
359: show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
360: break;
361: case KM_STRING:
362: sprintf(cmd_buf,"%s %s\n",prefix,curmap->km_ptr[i].km_str);
363: print_lines(cmd_buf,NOMARKING);
364: break;
365: case KM_BOGUS:
366: sprintf(cmd_buf,"%s BOGUS\n",prefix);
367: print_lines(cmd_buf,STANDOUT);
368: break;
369: }
370: }
371: }
372: }
373:
374: #endif
375:
376: /* routine to pass to tputs */
377:
378: char
379: putchr(ch)
380: register char ch;
381: {
382: putchar(ch);
383: #ifdef lint
384: ch = Null(char);
385: ch = ch;
386: #endif
387: }
388:
389: /* input the 2nd and succeeding characters of a multi-character command */
390: /* returns TRUE if command finished, FALSE if they rubbed out first character */
391:
392: bool
393: finish_command(donewline)
394: int donewline;
395: {
396: register char *s;
397: register bool quoteone = FALSE;
398:
399: s = buf;
400: if (s[1] != FINISHCMD) /* someone faking up a command? */
401: return TRUE;
402: do {
403: top:
404: if (*s < ' ') {
405: putchar('^');
406: putchar(*s | 64);
407: }
408: else if (*s == '\177') {
409: putchar('^');
410: putchar('?');
411: }
412: else
413: putchar(*s); /* echo previous character */
414: s++;
415: re_read:
416: fflush(stdout);
417: getcmd(s);
418: if (quoteone) {
419: quoteone = FALSE;
420: continue;
421: }
422: if (errno || *s == Ctl('l')) {
423: *s = Ctl('r'); /* force rewrite on CONT */
424: }
425: if (*s == '\033') { /* substitution desired? */
426: #ifdef ESCSUBS
427: char tmpbuf[4], *cpybuf;
428:
429: tmpbuf[0] = '%';
430: read_tty(&tmpbuf[1],1);
431: #ifdef RAWONLY
432: tmpbuf[1] &= 0177;
433: #endif
434: tmpbuf[2] = '\0';
435: if (tmpbuf[1] == 'h') {
436: (void) help_subs();
437: *s = '\0';
438: reprint();
439: goto re_read;
440: }
441: else if (tmpbuf[1] == '\033') {
442: *s = '\0';
443: cpybuf = savestr(buf);
444: interp(buf, (sizeof buf), cpybuf);
445: free(cpybuf);
446: s = buf + strlen(buf);
447: reprint();
448: goto re_read;
449: }
450: else {
451: interp(s,(sizeof buf) - (s-buf),tmpbuf);
452: fputs(s,stdout);
453: s += strlen(s);
454: }
455: goto re_read;
456: #else
457: notincl("^[");
458: *s = '\0';
459: reprint();
460: goto re_read;
461: #endif
462: }
463: else if (*s == ERASECH) { /* they want to rubout a char? */
464: rubout();
465: s--; /* discount the char rubbed out */
466: if (*s < ' ' || *s == '\177')
467: rubout();
468: if (s == buf) { /* entire string gone? */
469: fflush(stdout); /* return to single char command mode */
470: return FALSE;
471: }
472: else
473: goto re_read;
474: }
475: else if (*s == KILLCH) { /* wipe out the whole line? */
476: while (s-- != buf) { /* emulate that many ERASEs */
477: rubout();
478: if (*s < ' ' || *s == '\177')
479: rubout();
480: }
481: fflush(stdout);
482: return FALSE; /* return to single char mode */
483: }
484: #ifdef WORDERASE
485: else if (*s == Ctl('w')) { /* wipe out one word? */
486: *s-- = ' ';
487: while (!isspace(*s) || isspace(s[1])) {
488: rubout();
489: if (s-- == buf) {
490: fflush(stdout);
491: return FALSE; /* return to single char mode */
492: }
493: if (*s < ' ' || *s == '\177')
494: rubout();
495: }
496: s++;
497: goto re_read;
498: }
499: #endif
500: else if (*s == Ctl('r')) {
501: *s = '\0';
502: reprint();
503: goto re_read;
504: }
505: else if (*s == Ctl('v')) {
506: putchar('^');
507: backspace();
508: fflush(stdout);
509: getcmd(s);
510: goto top;
511: }
512: else if (*s == '\\') {
513: quoteone = TRUE;
514: }
515: } while (*s != '\n'); /* till a newline (not echoed) */
516: *s = '\0'; /* terminate the string nicely */
517: if (donewline)
518: putchar('\n') FLUSH;
519: return TRUE; /* say we succeeded */
520: }
521:
522: /* discard any characters typed ahead */
523:
524: void
525: eat_typeahead()
526: {
527: #ifdef PUSHBACK
528: if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
529: #else
530: if (!typeahead)
531: #endif
532: {
533: #ifdef PENDING
534: while (input_pending())
535: read_tty(buf,sizeof(buf));
536: #else /* this is probably v7 */
537: ioctl(_tty_ch,TIOCSETP,&_tty);
538: #endif
539: }
540: }
541:
542: void
543: settle_down()
544: {
545: dingaling();
546: fflush(stdout);
547: sleep(1);
548: #ifdef PUSHBACK
549: nextout = nextin; /* empty circlebuf */
550: #endif
551: eat_typeahead();
552: }
553:
554: #ifdef PUSHBACK
555: /* read a character from the terminal, with multi-character pushback */
556:
557: int
558: read_tty(addr,size)
559: char *addr;
560: int size;
561: {
562: if (nextout != nextin) {
563: *addr = circlebuf[nextout++];
564: nextout %= PUSHSIZE;
565: return 1;
566: }
567: else {
568: size = read(0,addr,size);
569: #ifdef RAWONLY
570: *addr &= 0177;
571: #endif
572: return size;
573: }
574: }
575:
576: #ifdef PENDING
577: #ifndef FIONREAD
578: int
579: circfill()
580: {
581: register int howmany = read(devtty,circlebuf+nextin,1);
582:
583: if (howmany) {
584: nextin += howmany;
585: nextin %= PUSHSIZE;
586: }
587: return howmany;
588: }
589: #endif PENDING
590: #endif FIONREAD
591:
592: void
593: pushchar(c)
594: char c;
595: {
596: nextout--;
597: if (nextout < 0)
598: nextout = PUSHSIZE - 1;
599: if (nextout == nextin) {
600: fputs("\npushback buffer overflow\n",stdout) FLUSH;
601: sig_catcher(0);
602: }
603: circlebuf[nextout] = c;
604: }
605:
606: #else PUSHBACK
607: #ifndef read_tty
608: /* read a character from the terminal, with hacks for O_NDELAY reads */
609:
610: int
611: read_tty(addr,size)
612: char *addr;
613: int size;
614: {
615: if (is_input) {
616: *addr = pending_ch;
617: is_input = FALSE;
618: return 1;
619: }
620: else {
621: size = read(0,addr,size)
622: #ifdef RAWONLY
623: *addr &= 0177;
624: #endif
625: return size;
626: }
627: }
628: #endif read_tty
629: #endif PUSHBACK
630:
631: /* print an underlined string, one way or another */
632:
633: void
634: underprint(s)
635: register char *s;
636: {
637: assert(UC);
638: if (*UC) { /* char by char underline? */
639: while (*s) {
640: if (*s < ' ') {
641: putchar('^');
642: backspace();/* back up over it */
643: underchar();/* and do the underline */
644: putchar(*s+64);
645: backspace();/* back up over it */
646: underchar();/* and do the underline */
647: }
648: else {
649: putchar(*s);
650: backspace();/* back up over it */
651: underchar();/* and do the underline */
652: }
653: s++;
654: }
655: }
656: else { /* start and stop underline */
657: underline(); /* start underlining */
658: while (*s) {
659: if (*s < ' ') {
660: putchar('^');
661: putchar(*s+64);
662: }
663: else
664: putchar(*s);
665: s++;
666: }
667: un_underline(); /* stop underlining */
668: }
669: }
670:
671: /* keep screen from flashing strangely on magic cookie terminals */
672:
673: #ifdef NOFIREWORKS
674: void
675: no_sofire()
676: {
677: if (*UP && *SE) { /* should we disable fireworks? */
678: putchar('\n');
679: un_standout();
680: up_line();
681: carriage_return();
682: }
683: }
684:
685: void
686: no_ulfire()
687: {
688: if (*UP && *US) { /* should we disable fireworks? */
689: putchar('\n');
690: un_underline();
691: up_line();
692: carriage_return();
693: }
694: }
695: #endif
696:
697: /* get a character into a buffer */
698:
699: void
700: getcmd(whatbuf)
701: register char *whatbuf;
702: {
703: #ifdef PUSHBACK
704: register KEYMAP *curmap;
705: register int i;
706: bool no_macros;
707: int times = 0; /* loop detector */
708: char scrchar;
709:
710: tryagain:
711: curmap = topmap;
712: no_macros = (whatbuf != buf && nextin == nextout);
713: #endif
714: for (;;) {
715: int_count = 0;
716: errno = 0;
717: if (read_tty(whatbuf,1) < 0 && !errno)
718: errno = EINTR;
719: if (errno && errno != EINTR) {
720: perror(readerr);
721: sig_catcher(0);
722: }
723: #ifdef PUSHBACK
724: if (*whatbuf & 0200 || no_macros) {
725: *whatbuf &= 0177;
726: goto got_canonical;
727: }
728: if (curmap == Null(KEYMAP*))
729: goto got_canonical;
730: for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
731: read_tty(&scrchar,1);
732: }
733: switch (curmap->km_type[*whatbuf] & KM_TMASK) {
734: case KM_NOTHIN: /* no entry? */
735: if (curmap == topmap) /* unmapped canonical */
736: goto got_canonical;
737: settle_down();
738: goto tryagain;
739: case KM_KEYMAP: /* another keymap? */
740: curmap = curmap->km_ptr[*whatbuf].km_km;
741: assert(curmap != Null(KEYMAP*));
742: break;
743: case KM_STRING: /* a string? */
744: pushstring(curmap->km_ptr[*whatbuf].km_str);
745: if (++times > 20) { /* loop? */
746: fputs("\nmacro loop?\n",stdout);
747: settle_down();
748: }
749: no_macros = FALSE;
750: goto tryagain;
751: }
752: #else
753: #ifdef RAWONLY
754: *whatbuf &= 0177;
755: #endif
756: break;
757: #endif
758: }
759:
760: got_canonical:
761: #ifndef TERMIO
762: if (*whatbuf == '\r')
763: *whatbuf = '\n';
764: #endif
765: if (whatbuf == buf)
766: whatbuf[1] = FINISHCMD; /* tell finish_command to work */
767: }
768:
769: #ifdef PUSHBACK
770: void
771: pushstring(str)
772: char *str;
773: {
774: register int i;
775: char tmpbuf[PUSHSIZE];
776: register char *s = tmpbuf;
777:
778: assert(str != Nullch);
779: interp(s,PUSHSIZE,str);
780: for (i = strlen(s)-1; i >= 0; --i) {
781: s[i] ^= 0200;
782: pushchar(s[i]);
783: }
784: }
785: #endif
786:
787: int
788: get_anything()
789: {
790: char tmpbuf[2];
791:
792: reask_anything:
793: unflush_output(); /* disable any ^O in effect */
794: standout();
795: #ifdef VERBOSE
796: IF(verbose)
797: fputs("[Type space to continue] ",stdout);
798: ELSE
799: #endif
800: #ifdef TERSE
801: fputs("[MORE] ",stdout);
802: #endif
803: un_standout();
804: fflush(stdout);
805: eat_typeahead();
806: if (int_count) {
807: return -1;
808: }
809: collect_subjects(); /* loads subject cache until */
810: /* input is pending */
811: getcmd(tmpbuf);
812: if (errno || *tmpbuf == '\f') {
813: putchar('\n') FLUSH; /* if return from stop signal */
814: goto reask_anything; /* give them a prompt again */
815: }
816: if (*tmpbuf == 'h') {
817: #ifdef VERBOSE
818: IF(verbose)
819: fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
820: ELSE
821: #endif
822: #ifdef TERSE
823: fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
824: #endif
825: goto reask_anything;
826: }
827: else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
828: carriage_return();
829: erase_eol(); /* erase the prompt */
830: return *tmpbuf == 'q' ? -1 : *tmpbuf;
831: }
832: if (*tmpbuf == '\n') {
833: page_line = LINES - 1;
834: carriage_return();
835: erase_eol();
836: }
837: else {
838: page_line = 1;
839: if (erase_screen) /* -e? */
840: clear(); /* clear screen */
841: else {
842: carriage_return();
843: erase_eol(); /* erase the prompt */
844: }
845: }
846: return 0;
847: }
848:
849: void
850: in_char(prompt)
851: char *prompt;
852: {
853: char oldmode = mode;
854:
855: reask_in_char:
856: unflush_output(); /* disable any ^O in effect */
857: fputs(prompt,stdout);
858: fflush(stdout);
859: eat_typeahead();
860: mode = 'm';
861: getcmd(buf);
862: if (errno || *buf == '\f') {
863: putchar('\n') FLUSH; /* if return from stop signal */
864: goto reask_in_char; /* give them a prompt again */
865: }
866: mode = oldmode;
867: }
868:
869: int
870: print_lines(what_to_print,hilite)
871: char *what_to_print;
872: int hilite;
873: {
874: register char *s;
875: register int i;
876:
877: if (page_line < 0) /* they do not want to see this? */
878: return -1;
879: for (s=what_to_print; *s; ) {
880: if (page_line >= LINES || int_count) {
881: if (i = -1, int_count || (i = get_anything())) {
882: page_line = -1; /* disable further print_lines */
883: return i;
884: }
885: }
886: page_line++;
887: if (hilite == STANDOUT) {
888: #ifdef NOFIREWORKS
889: if (erase_screen)
890: no_sofire();
891: #endif
892: standout();
893: }
894: else if (hilite == UNDERLINE) {
895: #ifdef NOFIREWORKS
896: if (erase_screen)
897: no_ulfire();
898: #endif
899: underline();
900: }
901: for (i=0; i<COLS; i++) {
902: if (!*s)
903: break;
904: if (*s >= ' ')
905: putchar(*s);
906: else if (*s == '\t') {
907: putchar(*s);
908: i = ((i+8) & ~7) - 1;
909: }
910: else if (*s == '\n') {
911: i = 32000;
912: }
913: else {
914: i++;
915: putchar('^');
916: putchar(*s + 64);
917: }
918: s++;
919: }
920: if (i) {
921: if (hilite == STANDOUT)
922: un_standout();
923: else if (hilite == UNDERLINE)
924: un_underline();
925: if (AM && i == COLS)
926: fflush(stdout);
927: else
928: putchar('\n') FLUSH;
929: }
930: }
931: return 0;
932: }
933:
934: void
935: page_init()
936: {
937: page_line = 1;
938: if (erase_screen)
939: clear();
940: else
941: putchar('\n') FLUSH;
942: }
943:
944: void
945: pad(num)
946: int num;
947: {
948: register int i;
949:
950: for (i = num; i; --i)
951: putchar(PC);
952: fflush(stdout);
953: }
954:
955: /* echo the command just typed */
956:
957: #ifdef VERIFY
958: void
959: printcmd()
960: {
961: if (verify && buf[1] == FINISHCMD) {
962: if (*buf < ' ') {
963: putchar('^');
964: putchar(*buf | 64);
965: backspace();
966: backspace();
967: }
968: else {
969: putchar(*buf);
970: backspace();
971: }
972: fflush(stdout);
973: }
974: }
975: #endif
976:
977: void
978: rubout()
979: {
980: backspace(); /* do the old backspace, */
981: putchar(' '); /* space, */
982: backspace(); /* backspace trick */
983: }
984:
985: void
986: reprint()
987: {
988: register char *s;
989:
990: fputs("^R\n",stdout) FLUSH;
991: for (s = buf; *s; s++) {
992: if (*s < ' ') {
993: putchar('^');
994: putchar(*s | 64);
995: }
996: else
997: putchar(*s);
998: }
999: }
1000:
1001: #ifdef CLEAREOL
1002: /* start of additions by Paul Placeway (PWP) */
1003:
1004: void
1005: home_cursor()
1006: {
1007: char *tgoto();
1008:
1009: if (!*HO) { /* no home sequence? */
1010: if (!*CM) { /* no cursor motion either? */
1011: fputs ("\n\n\n", stdout);
1012: return; /* forget it. */
1013: }
1014: tputs (tgoto (CM, 0, 0), 1, putchr); /* go to home via CM */
1015: return;
1016: }
1017: else { /* we have home sequence */
1018: tputs (HO, 1, putchr); /* home via HO */
1019: }
1020: }
1021: #endif CLEAREOL
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.