BSD 4_3 development
[unix-history] / usr / contrib / nntp / rrn / term.c
CommitLineData
25a197fc
C
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
26char ERASECH; /* rubout character */
27char KILLCH; /* line delete character */
28char 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
36struct 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
53typedef struct keymap KEYMAP;
54
55KEYMAP *topmap INIT(Null(KEYMAP*));
56
57void mac_init();
58KEYMAP *newkeymap();
59void show_keymap();
60void pushstring();
61#endif
62
63/* terminal initialization */
64
65void
66term_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
112void
113term_set(tcbuf)
114char *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
233void
234mac_init(tcbuf)
235char *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
248void
249mac_line(line,tmpbuf,tbsize)
250char *line;
251char *tmpbuf;
252int 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
300KEYMAP*
301newkeymap()
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
318void
319show_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
330void
331show_keymap(curmap,prefix)
332register KEYMAP *curmap;
333char *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
378char
379putchr(ch)
380register 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
392bool
393finish_command(donewline)
394int 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++;
415re_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
524void
525eat_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
542void
543settle_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
557int
558read_tty(addr,size)
559char *addr;
560int 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
578int
579circfill()
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
592void
593pushchar(c)
594char 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
610int
611read_tty(addr,size)
612char *addr;
613int 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
633void
634underprint(s)
635register 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
674void
675no_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
685void
686no_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
699void
700getcmd(whatbuf)
701register 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
710tryagain:
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
760got_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
770void
771pushstring(str)
772char *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
787int
788get_anything()
789{
790 char tmpbuf[2];
791
792reask_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
849void
850in_char(prompt)
851char *prompt;
852{
853 char oldmode = mode;
854
855reask_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
869int
870print_lines(what_to_print,hilite)
871char *what_to_print;
872int 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
934void
935page_init()
936{
937 page_line = 1;
938 if (erase_screen)
939 clear();
940 else
941 putchar('\n') FLUSH;
942}
943
944void
945pad(num)
946int 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
958void
959printcmd()
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
977void
978rubout()
979{
980 backspace(); /* do the old backspace, */
981 putchar(' '); /* space, */
982 backspace(); /* backspace trick */
983}
984
985void
986reprint()
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
1004void
1005home_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