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