|
|
1.1 root 1: #include <stdio.h>
2: #ifdef ux3
3: #include <termio.h>
4: #else
5: #include <sgtty.h>
6: #endif
7: /* EMACS_MODES: c !fill */
8: char *getenv();
9: /* macro definitions */
10:
11: #define EOL '\n'
12:
13: char *UP; /* cursor up line */
14: char *DOWN;
15: char *BACK;
16: char *FORWARD;
17: char *HOME;
18: char *CLEAR;
19: char *CLREST;
20: char *CLINE;
21: char *BELL;
22: char *CURAD;
23: char *TMAP;
24: char *SMAP;
25: char *NOP;
26: char *LOPEN;
27: char *LDEL;
28: char *INSERTC;
29: char *INSERTM;
30: char *OSERTC;
31: char *INSERTP;
32: char *DELC;
33: char *SSCROLL;
34: char *RSCROLL;
35: char *CR;
36: char *SCREG;
37: char *ULINE;
38: char *UEND;
39: int EOVER;
40: char *SCINIT;
41: char *VEXIT;
42: char *RELDOWN;
43: char *RELUP;
44: char *RELFORW;
45: char *RELBACK;
46: int XBASE;
47: int YBASE;
48: int SCRWID;
49: int SCRNLIN;
50: int SCRWRAP;
51: int VCOST;
52: int SRCADD;
53: int MI;
54: int IN;
55: int DELMODE;
56:
57: /* character definitions */
58:
59: #define META 0200
60: #define MTA(mtach) ('mtach'+0200) /* make meta char */
61: #define ESC 033
62: #define NEWLINE 037
63: #define RUB 0177
64:
65: /* DISPLAY MODE PARAMETERS */
66:
67: int WRAPON = 0; /* perform ! processing at EOL */
68: int INSON = 0; /* use INSERTC/DELC */
69:
70: /* screen display data */
71:
72: char ttobuf[BUFSIZ];
73:
74: int drain;
75: int mline;
76: int mcol;
77: int SCRLINES; /* number of lines in window */
78: int ECHOL; /* line for prompting */
79: int MODLN; /* line for buffer and file data */
80:
81:
82:
83: /* statistics */
84:
85: long nmput; /* calls to mputc */
86: long noutc; /* actual characters output */
87: int ninch; /* number of characters input */
88: int ntwrite; /* number of terminal writes */
89: int nbwrite; /* number of buffer writes */
90: int nbseek; /* number of seeks of buffer */
91: int nbread; /* number of buffer reads */
92: int nmkline; /* number of makeline calls */
93:
94: extern int errno;
95:
96: /* function definitions */
97:
98: char *getname();
99: /*VARARGS*/ char *execl();
100:
101: /* lint definitions */
102:
103: #ifdef lint
104: #define IGNORE(x) if(x);
105: #else
106: #define IGNORE(x) (x)
107: #endif
108:
109: /* emacs display definitions */
110:
111:
112: /* EMACS_MODES: c !fill */
113:
114: char ldchar; /* last clobbered character */
115: char ldcol; /* collumn of ldchar */
116: char osert = 0; /* flag indicating insert char mode */
117: int acost; /* cost of absolute positioning */
118: int lUP; /* cost of UP */
119: int lDOWN; /* cost of DOWN */
120: int lBAK; /* cost of BACK */
121: int lCR;
122:
123: int psx;
124: int psy;
125: int saveline;
126: int savecol;
127: int scrlin;
128: int scrcol;
129: int ttywarp; /* tty warp factor (stty speed) */
130:
131: /* display data */
132:
133: #define TTYLEN 256 /* total area for tty data strings */
134: char ttystrings[TTYLEN];
135:
136:
137: struct sparm {
138: char *t_pname;
139: int *t_padd;
140: };
141:
142: struct sparm ttydata[] = {
143: "up",(int *) &UP,
144: "do",(int *) &DOWN,
145: "bc",(int *) &BACK,
146: "nd",(int *) &FORWARD,
147: "ho",(int *) &HOME,
148: "cl",(int *) &CLEAR,
149: "cd",(int *) &CLREST,
150: "ce",(int *) &CLINE,
151: "bl",(int *) &BELL,
152: "cm",(int *) &CURAD,
153: "tm",(int *) &TMAP,
154: "tM",(int *) &SMAP,
155: "pc",(int *) &NOP,
156: "al",(int *) &LOPEN,
157: "dl",(int *) &LDEL,
158: "ic",(int *) &INSERTC,
159: "im",(int *) &INSERTM,
160: "ei",(int *) &OSERTC,
161: "ip",(int *) &INSERTP,
162: "dc",(int *) &DELC,
163: "sf",(int *) &SSCROLL,
164: "sr",(int *) &RSCROLL,
165: "cr",(int *) &CR,
166: "cs",(int *) &SCREG,
167: "ul",(int *) &ULINE,
168: "ue",(int *) &UEND,
169: "eo",&EOVER,
170: "vs",(int *) &SCINIT,
171: "ve",(int *) &VEXIT,
172: "bx",&XBASE,
173: "by",&YBASE,
174: "co",&SCRWID,
175: "li",&SCRNLIN,
176: "am",&SCRWRAP,
177: "vc",(int *) &VCOST,
178: "rc",(int *) &SRCADD,
179: "mi",(int *) &MI,
180: "in",(int *) &IN,
181: "dm",&DELMODE,
182: "ru",(int *) &RELUP,
183: "rd",(int *) &RELDOWN,
184: "rl",(int *) &RELFORW,
185: "rr",(int *) &RELBACK,
186: 0,0,
187: };
188:
189: char *endput = "____________________";
190:
191:
192:
193: #define SCRCONT '!'
194: int TABSTOP = 8;
195:
196: #define NSCRLIN 48 /* max screen lines */
197: #define NSCRCOL 128 /* max screen columns */
198: char cmap[NSCRLIN] [NSCRCOL];
199: int scrjnk[NSCRLIN]; /* column of last non-white character */
200:
201:
202:
203: /* character type table */
204:
205: #define PLAIN 0
206: #define CONTRL 1
207: #define TAB 2
208: #define BACKSP 3
209:
210: char ctype[128] = {
211: CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
212: BACKSP, TAB, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
213: CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
214: CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL, CONTRL,
215: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
216: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
217: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
218: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
219: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
220: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
221: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
222: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
223: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
224: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
225: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN,
226: PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, PLAIN, CONTRL,
227: };
228:
229:
230: /* display heuristics */
231:
232: #define CFILL 30 /* average chars/line */
233: #define PATIENCE 2000 /* number of millisecends of */
234: /* output to buffer before */
235: /* looking for type ahead */
236:
237:
238: /* display macros */
239:
240: #define mputc(chr) (((mcol<scrjnk[mline]) && (chr == cmap[mline][mcol]))? mcol++ : mptc(chr))
241:
242: /* trace stuff */
243:
244:
245: char *termdir = SDIR/terminals/%s";
246:
247:
248: /* Terminal I/O modes, sgttyb for before unix 3.0, termio for later */
249:
250: int SREGION = 24;
251:
252: #ifdef ux3
253: struct termio ttyjunk;
254: #else
255: struct sgttyb ttyjunk;
256: #endif
257:
258: int ttyerase = '#';
259: int ttykill = '@';
260: int ttyintr = '';
261: int ttyeof = '';
262:
263: #define NBAUD 16 /* number of baud rates */
264: char charms[NBAUD] = { /* ms per char in various rates */
265: 100,
266: 100, /* 50 */
267: 100, /* 75 */
268: 100, /* 110 */
269: 70, /* 134 */
270: 66, /* 150 */
271: 50, /* 200 */
272: 33, /* 300 */
273: 16, /* 600 */
274: 8, /* 1200 */
275: 5, /* 1800 */
276: 4, /* 2400 */
277: 2, /* 4800 */
278: 1, /* 9600 */
279: 1, /* EXTA */
280: 1, /* EXTB */
281: };
282:
283: xgo(x,y)
284:
285: {
286: ldchar = 0;
287: mline = x;
288: mcol = y;
289: }
290:
291:
292: /* beep -- obvious */
293:
294: beep()
295:
296: {
297: PUTS(BELL); /* print a bell */
298: }
299:
300: /* move both the display matrix pointer and the actual display to the
301: * specified line and column */
302:
303: mgo(x,y)
304:
305: register x,y;
306:
307: {
308:
309: sgo(mline = x,mcol = y);
310: }
311:
312:
313: /* move the display cursor to the specified destination. sgo attempts
314: * to optimize the movement, using single character or absolute
315: * positioning */
316:
317: sgo(x,y)
318:
319: register x,y;
320:
321: {
322: int mx,my;
323: int xcost; /* cost with all relative movement */
324: int ycost; /* cost with carriage return */
325: /* acost is cost of absolute positioning */
326:
327: /* calculate relative costs of various movements. cost functions */
328: /* automatically indicate that un-doable motions have infinite cost */
329:
330:
331:
332:
333: /* calculate xcost and ycost */
334:
335: mx = x-scrlin;
336: if (mx<0) {
337: mx = -mx;
338: xcost = mx*lUP;
339: } else xcost = mx*lDOWN;
340:
341: ycost = y + xcost + lCR;
342:
343: my = y-scrcol;
344: if (my<0) {
345: my = -my;
346: xcost +=my*lBAK;
347: } else xcost += my;
348:
349:
350: if (acost < ycost) {
351: if (acost < xcost) {
352: /* do absolute positioning */
353: if (CURAD) { /* have absolute addrs */
354: if (SRCADD) {
355: eprintf(CURAD,x+XBASE,y+YBASE);
356: } else {
357: eprintf(CURAD,y+YBASE,x+XBASE);
358: }
359: } else { /* have relative addrs */
360: if (x>scrlin) printf (RELDOWN,mx);
361: if (x<scrlin) printf (RELUP,mx);
362: if (y>scrcol) printf (RELFORW,my);
363: if (y<scrcol) printf (RELBACK,my);
364: }
365: scrlin=x;
366: scrcol=y;
367: return;
368: } /* else relative is cheap, do it */
369: } else {
370: if (osert && (MI == 0)) {
371: unsert();
372: }
373: if (ycost < xcost) { /* do carriage return processing */
374: PUTS(CR); /* carriage return */
375: scrcol = 0;
376: /* fall through to finish with relative motion */
377: }
378: }
379:
380: while (x != scrlin) {
381: if (x < scrlin) {
382: PUTS(UP);
383: scrlin--;
384: } else {
385: PUTS(DOWN);
386: scrlin++;
387: }
388: }
389:
390: /* now correct row */
391:
392: while (y != scrcol) {
393: if (y < scrcol) {
394: PUTS(BACK);
395: scrcol--;
396: } else {
397: if (FORWARD == NULL) {
398: if (osert) {
399: unsert();
400: }
401: x = cmap[scrlin] [scrcol];
402: if ((x == 0)|| (scrjnk[scrlin]<=scrcol)) x=cmap[scrlin] [scrcol] = ' ';
403: putit(x); /* re-write */
404: } else {
405: PUTS(FORWARD);
406: }
407: scrcol++;
408: }
409: };
410: return;
411: }
412:
413: /* unsert -- LEAVE insert character mode */
414:
415: unsert()
416: {
417: eprintf(OSERTC); /* can't stay inserting */
418: osert = 0;
419: }
420:
421: /* a simple guide to all of the various putc routines in this program:
422: * xputc puts a character out, translating control and meta characters
423: * to prefix sequences, and calling sputc to put out the individual
424: * characters. sputc checks for end of line, and if so wraps to the
425: * next line. sputc calls mputc to output characters. mputc updates
426: * the next character in the display to be whaat is put out. Display
427: * takes place only if the character on the screen is not that called for
428: * already. */
429:
430:
431: mptc(c)
432: register c;
433: {
434: nmput++; /* count for stats */
435: if ((c == ' ') && (mcol >= scrjnk[mline])) {
436:
437: cmap[mline] [mcol++] = c;
438: return;
439: }
440: if ((mcol != scrcol) || (mline != scrlin)) sgo(mline,mcol);
441: if (DELC && INSON && (c == cmap [mline] [mcol+1]) && (mcol+3 <scrjnk[mline]) && (ldchar == 0)) {
442: register i;
443: SREGION=scrjnk[mline]-mcol; /* number of char's gobbled */
444: if (DELMODE && (osert == 0)) {
445: eprintf(INSERTM);
446: osert++;
447: }
448: eprintf(DELC); /*clobber next char */
449: for (i = mcol; i <=scrjnk[mline];i++) {
450: cmap[mline] [i] = cmap[mline] [i+1];
451: }
452: scrjnk[mline]--;
453: } else {
454: if ((INSERTC || INSERTM) && INSON && (c == ldchar) && (mcol == ldcol+1) && (mcol<scrjnk[mline])) {
455: register i;
456: if (INSERTM && (osert == 0)) {
457: eprintf(INSERTM); /* open space */
458: osert = 1;
459: }
460: if (scrjnk[mline] >SCRWID) scrjnk[mline]--;
461: for (i = scrjnk[mline]++; i >= mcol;i--) {
462: cmap[mline] [i+1] = cmap[mline] [i];
463: }
464: if (INSERTC) eprintf(INSERTC);
465: cmap[mline] [mcol] = 0;
466: } else {
467: if (osert) {
468: unsert();
469: }
470: }
471: putit(c);
472: if (osert && INSERTP) eprintf(INSERTP);
473: if (ldchar == 0) ldcol = mcol; /* remember where it was */
474: ldchar = cmap[mline][mcol]; /* save last clobber */
475: if ((scrcol++ >= SCRWID) && SCRWRAP) {
476: scrlin++;
477: scrcol=0;
478: }
479: }
480: cmap[mline] [mcol] = c;
481: while (scrjnk[mline] <mcol) cmap[mline] [scrjnk[mline]++] = ' ';
482: if (++mcol> scrjnk[mline]) scrjnk[mline] = mcol;
483: }
484:
485: /* getname prompts for a string, using ps, and inputs a string */
486:
487: /* rubout and @ can be used to edit the string as enterred, and causes
488: * a quit, returning no input string
489: * ^Y causes the current buffer name to be brought out
490: */
491: #define FNLEN 128
492: char fnbuf[FNLEN];
493:
494:
495: char *
496: getname(ps)
497:
498: register char *ps;
499:
500: {
501: register i;
502: register char c;
503: char *xp;
504:
505: fnbuf[i=0] = 0;
506: for (;;) {
507: prompt1("%s%s",ps,fnbuf); /* display prompt */
508: mgo(mline,mcol);
509: c = mgetchar();
510:
511: if ((c == '') || (c == ttyintr)) {
512: beep();
513: unprompt();
514: return(NULL);
515: }
516: if ((c == '
') || (c == '\n')) {
517: unprompt();
518: return(fnbuf);
519: }
520: if (c == ttyerase) {
521: if (i) {
522: i--;
523: fnbuf[i] = 0;
524: } else beep();
525: continue;
526: }
527: if (c == ttykill) {
528: fnbuf[i=0]=0;
529: continue;
530: }
531: if (c == '') {
532: c = 0177 & getchar();
533: }
534: fnbuf[i++] = c;
535: if (i >= FNLEN) {
536: beep();
537: --i;
538: }
539: fnbuf[i] = 0;
540: continue;
541: }
542: }
543:
544: /* putout outputs a string (like eprintf) at the current position */
545:
546: /* position is advanced one line. If the position overflows the screen,
547: * -MORE- is printed, and input is read. Any character except ^G
548: * continues the display, ^G quits by returning -1 */
549:
550: /*VARARGS1*/
551:
552: putout(string,arg1,arg2,arg3,arg4,arg5,arg6)
553: char *string;
554: {
555: if (mline>=SCRLINES) {
556: prompt1("-- MORE --");
557: if ((mgetchar()) == ttykill) return(-1);
558: unprompt();
559: mline=0; /* TOP */
560: }
561: prompt(mline,string,arg1,arg2,arg3,arg4,arg5,arg6);
562: clrl();
563: mgo(++mline,0);
564: return(0);
565: }
566:
567: /* put out a string on ECHOL */
568: /*VARARGS1*/
569:
570: prompt1(string,arg1,arg2,arg3,arg4,arg5)
571: char *string;
572: {
573: prompt(ECHOL,string,arg1,arg2,arg3,arg4,arg5);
574: }
575:
576: /* put out a string at a specified line */
577:
578: /*VARARGS2*/
579:
580: prompt(ecl,string,arg1,arg2,arg3,arg4,arg5,arg6)
581:
582: char *string;
583: register int ecl;
584:
585: {
586: char pbuf[256];
587:
588: if (mline<=SCRLINES) {
589: saveline = mline;
590: savecol = mcol;
591: }
592: mline = ecl;
593: mcol = 0;
594: seprintf(pbuf,string,arg1,arg2,arg3,arg4,arg5,arg6);
595: sputs(pbuf);
596: psx = mline;
597: psy = mcol;
598: clrl();
599: }
600:
601: /* clear out prompt */
602:
603: unprompt()
604:
605: {
606:
607: if (mline<=SCRLINES) { /* if position to save */
608: saveline = mline;
609: savecol = mcol;
610: }
611: mgo(ECHOL,0);
612: clrl();
613: mgo(saveline,savecol);
614: }
615:
616:
617: /* return to the position saved before the last prompt */
618:
619: goback()
620:
621: {
622: mgo(saveline,savecol);
623: }
624:
625: /* put one character on the screen checking for end of screen line */
626:
627: sputc(c)
628:
629: register c;
630: {
631:
632: register i;
633:
634: if (mcol == SCRWID) {
635: if (WRAPON) {
636: if (mline>=NSCRLIN-1) {
637: mline--; /* don't run overboard */
638: } else {
639: mputc(SCRCONT);
640: mline++;
641: }
642: ldchar = 0; /* reset ldchar */
643: mcol = 0;
644: } else {
645: mputc(c);
646: mline++;
647: mcol=0;
648: ldchar=0;
649: return;
650: }
651: }
652: mputc(c);
653: }
654:
655: /* put one character in the display, checking for control and meta chars. */
656:
657: xputc(c)
658: register c;
659: {
660: register i;
661:
662: c &= 0377;
663: if (c & META) {
664: sputc('M');
665: sputc('-');
666: c-= META;
667: }
668: switch(ctype[c]) {
669: char oc;
670: case PLAIN:
671: if ((!ULINE)||(!EOVER)) {
672: sputc(c);
673: return;
674: }
675: if (scrjnk[mline] <= mcol) {
676: sputc(c);
677: return;
678: }
679: oc = cmap[mline][mcol] & 0177 ;
680: if ((oc == '_') && ((c & 0177) != ' ')
681: && ((c & 0177) != '_')) {
682: sputc(0200 | c);
683: return;
684: }
685: sputc(c);
686: return;
687: case BACKSP:
688: if ((ULINE)&&(EOVER)) {
689: if (mcol != 0) xgo(mline,mcol-1);
690: return;
691: }
692: /* NO BREAK HERE */
693: case CONTRL:
694: sputc('^');
695: sputc(c^0100);
696: return;
697:
698: case TAB:
699: i = TABSTOP-(mcol%TABSTOP);
700: while (i--) sputc(' ');
701: return;
702:
703: }
704: }
705:
706:
707:
708: /* clear the rest of the line, checking to see if the line previously
709: * displayed corresponds to the one displayed here now */
710:
711: clrl()
712:
713: {
714: register x;
715: register y;
716: register z;
717: int xline;
718: int xcol;
719:
720: ldchar = 0; /* wipe out last char */
721: x = mline;
722: z = mcol;
723: y = scrjnk[mline] - mcol;
724: if (y > 0) {
725: sgo(mline,mcol); /* go for real */
726: if (CLINE) {
727: SREGION=y; /* Number of characters cleared */
728: eprintf(CLINE);
729: } else {
730: xline = mline;
731: xcol = mcol;
732: while (y--) mputc (' ');
733: mgo(xline,xcol);
734: }
735: scrjnk[x] = z;
736: }
737: }
738:
739: /* put a string on the screen, translating control and meta */
740:
741: sputs(xp)
742: register char *xp;
743: {
744: register c;
745: while (c= *xp++) {
746: if (c == NEWLINE) {
747: if (mline < NSCRLIN) mline++; /* don't overflow */
748: mcol = 0;
749: xputc(' ');
750: } else xputc(c);
751: }
752: }
753:
754: clear()
755:
756: {
757: register int i;
758:
759: eprintf(CLEAR);
760: for (i = 0; i < NSCRLIN; i++) scrjnk[i] = 0;
761: scrlin = scrcol = mline = mcol = 0;
762: }
763:
764:
765: /* Refresh the screen. Clears and then restores what we think is there */
766:
767: rfrsh()
768: {
769: register xline;
770: register xcol;
771:
772: eprintf(CLEAR);
773: scrlin=scrcol=0;
774:
775: for (xline = 0; xline < SCRNLIN; xline++) {
776: for (xcol = 0; xcol < scrjnk[xline]; xcol++) {
777: if (cmap[xline][xcol]) {
778: sgo(xline,xcol);
779: putit(cmap[xline][xcol]);
780: if ((scrcol++ >= SCRWID) && SCRWRAP) {
781: scrlin++;
782: scrcol=0;
783: }
784: }
785: }
786: }
787: ldchar = 0;
788: }
789:
790: sdelay(ms)
791:
792: register int ms; /* milliseconds of delay */
793: {
794: register i;
795: for (i = 0; i < ms;) {
796: PUTS(NOP); /* idle */
797: i+=ttywarp; /* milliseconds/character */
798: }
799: }
800:
801: ttype() /* set terminal type */
802:
803: {
804: register char *mp;
805:
806: mp = getname("Terminal Type? ");
807: if (mp == NULL) return;
808: sttype(mp);
809: }
810:
811: int ttyptr = 0;
812:
813: /* terminal description file parser: */
814:
815: /* terminal description file contains lines with
816:
817: parameter=data
818:
819: * where data is either a number of a string */
820:
821:
822: ttyparse(mp)
823: char *mp;
824:
825: {
826: register FILE *file;
827: char xbuf[128];
828: char optbuf[128];
829: register char *cp;
830: register int c;
831: struct sparm *parmp;
832:
833: int parm;
834:
835:
836: /* find the terminal file and open it */
837:
838: seprintf(xbuf,termdir,mp); /* terminal file */
839:
840: file = fopen(xbuf,"r");
841:
842: if (file == NULL) file = fopen(mp,"r");
843:
844: if (file == NULL) {
845: eprintf ("Can't use terminal type %s\n", mp);
846: return(0);
847: }
848:
849: /* first find what option we are setting */
850:
851: nextparm: cp = optbuf;
852: while ((c = getc(file)) != '=') {
853: if (c == '\n') goto nextparm; /* comment line */
854: if (c == EOF) {
855: fclose(file);
856: return(1); /* abort during option scan */
857: }
858: *cp++=c;
859: }
860: *cp = 0;
861:
862: /* look up parameter in parameter table */
863:
864: for (parmp = ttydata; parmp->t_pname; parmp++) {
865: if ((optbuf[0]==parmp->t_pname[0])&& (optbuf[1]==parmp->t_pname[1])) {
866:
867: c = getc(file);
868: if ((c >= '0') && (c <= '9')) {
869: parm = 0;
870: while ((c >= '0') && (c <= '9')) {
871: parm = 10*parm + (c-'0');
872: c = getc(file);
873: }
874: *(parmp->t_padd) = parm;
875: if (c != EOF) goto nextparm;
876: fclose(file);
877: return(1);
878: }
879: *(parmp->t_padd) = ((int) &ttystrings[ttyptr]);
880:
881: while ((c != EOF) && (c != EOL)) {
882: if (c == '\\') {
883: c = getc(file);
884: if (c == 'n') c = '\n';
885: }
886:
887: ttystrings[ttyptr++] = c;
888: c = getc(file);
889: }
890: ttystrings[ttyptr++] = 0;
891: if (c != EOF) goto nextparm;
892: }
893: }
894: goto nextparm;
895: }
896:
897: PUTS(string)
898:
899: char *string;
900:
901: {
902: if (!drain) while(*string) putchar(0177 & *string++);
903: }
904: sttype(mp)
905: register char *mp;
906:
907: {
908: register struct sparm *parmp;
909:
910: /* First, initialize the tty data */
911:
912:
913:
914: ttyptr = 0;
915: for (parmp = ttydata; parmp->t_pname; parmp++) {
916: *(parmp->t_padd) = 0;
917: }
918: SCRLINES=20;
919: SCRWID=80; /* so we won't bomb */
920:
921: if (ttyparse(mp)) {
922:
923: SCRWID--;
924:
925: if (SCRNLIN>NSCRLIN) {
926: SCRNLIN=NSCRLIN;
927: }
928: if (SCRWID>NSCRCOL-1) {
929: SCRWID=NSCRCOL-1;
930: }
931: if (VCOST == 0) VCOST = 1;
932: SCRLINES = SCRNLIN-4;
933: ECHOL = SCRNLIN-1;
934: MODLN = SCRNLIN-3;
935:
936: if (CURAD) {
937: acost = dcost(CURAD);
938: } else {
939: acost = dcost(RELUP)+dcost(RELFORW);
940: }
941: lUP = dcost(UP);
942: lDOWN = dcost(DOWN);
943: lBAK = dcost(BACK);
944: lCR = dcost(CR);
945: if (OSERTC && (INSERTM == 0)) {
946: INSERTM=INSERTC; /* old style insert modes */
947: INSERTC=0;
948: }
949: if (SCREG) LOPEN = SCREG; /* make sure we use SCREG */
950: if ((NOP == NULL) || (*NOP == 0)) NOP = "\200"; /* null pads get lost */
951:
952: if (SCINIT) {
953: eprintf(SCINIT); /* initialize screen */
954: }
955: clear();
956: }
957: }
958:
959: /* dcost -- calculate display cost of a string */
960:
961: dcost(sp)
962: register char *sp;
963: {
964: register int dc;
965:
966: if (sp == NULL) return(1000); /* infinite cost for missing capability */
967:
968: dc = 0;
969: while (*sp) {
970: if (*sp++ != '%') dc++;
971: }
972: return(dc);
973: }
974:
975: /* yes or no question */
976: /*VARARGS1*/
977: int
978: gyn(string,arg1,arg2,arg3)
979:
980: char *string;
981: char *arg1;
982: char *arg2;
983: char *arg3;
984: {
985: register char c;
986:
987: while (1) {
988: prompt(ECHOL,string,arg1,arg2,arg3);
989: sgo(mline,mcol);
990: c = mgetchar();
991: switch(c) {
992:
993: case 'y':
994: case 'Y':
995: case ' ':
996: return(1);
997: case '': /* This is necessary to insure exit */
998: case 'n':
999: case 'N':
1000: case '':
1001: return(0);
1002: case '':
1003: return(-1);
1004: default:
1005: prompt(ECHOL-1,"y for yes, n for no, ^G to quit");
1006: }
1007: }
1008: };
1009:
1010: /* mtop -- move to top of display for message output */
1011:
1012: mtop()
1013: {
1014: mgo(0,0); /* for messages */
1015: }
1016:
1017: uncook()
1018: {
1019:
1020: /* UNIX 3 code thanks to J. Langer and M. Plotnick */
1021:
1022: #ifdef ux3
1023: struct termio nttyjunk;
1024:
1025: ioctl(1, TCGETA, &ttyjunk);
1026: nttyjunk=ttyjunk;
1027:
1028: #ifdef u370
1029:
1030: nttyjunk.c_iflag |= (BRKINT|ISTRIP|IGNPAR);
1031: nttyjunk.c_iflag &=
1032: ~(IGNBRK|IGNPAR|PARMRK|IXON|INLCR|IGNCR|ICRNL|INPCK);
1033: /* accept break, no crnl mapping, no ^S^Q */
1034: nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */
1035: nttyjunk.c_cflag |= CS8 ;
1036: nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals,
1037: or erase/kill processing */
1038: #else
1039: nttyjunk.c_iflag |= (BRKINT|ISTRIP);
1040: nttyjunk.c_iflag &= ~(IGNBRK|PARMRK|INLCR|ICRNL|IGNCR|IXON|IXOFF);
1041: /* accept break, no crnl mapping, no ^S^Q */
1042: nttyjunk.c_oflag = 0; /* no delays, no crlf mapping */
1043: nttyjunk.c_lflag &= ~(ISIG|ECHO|ICANON); /* no echo, signals,
1044: or erase/kill processing */
1045: #endif
1046: nttyjunk.c_cc[VMIN] = 1; /* return after every character read */
1047: nttyjunk.c_cc[VTIME] = 1;
1048: ttywarp = charms[ttyjunk.c_cflag&CBAUD]; /* milliseconds for character */
1049:
1050: ioctl(1, TCSETAW, &nttyjunk);
1051: ioctl(1, TCXONC,1); /* Force tty back on */
1052:
1053: #else
1054:
1055: struct sgttyb nttyjunk;
1056:
1057: gtty (1,&ttyjunk);
1058: nttyjunk=ttyjunk;
1059: nttyjunk.sg_flags &= (~ECHO); /* it was so SIMPLE in the old days */
1060: nttyjunk.sg_flags |= (RAW);
1061: ttywarp = charms[ttyjunk.sg_ospeed]; /* milliseconds for char */
1062: stty(1,&nttyjunk);
1063: #endif
1064:
1065: #ifndef RT
1066: ttyerase = ttyjunk.c_cc[VERASE];
1067: ttykill = ttyjunk.c_cc[VKILL];
1068: ttyeof = ttyjunk.c_cc[VEOF];
1069: ttyintr = ttyjunk.c_cc[VINTR];
1070: #else
1071: ttyerase = ttyjunk.sg_erase;
1072: ttykill = ttyjunk.sg_kill;
1073: ttyeof = '\004';
1074: ttyintr = '';
1075: #endif
1076: if (VEXIT) eprintf(SCINIT); /* RE-init terminal */
1077: }
1078:
1079: /* out of raw mode */
1080:
1081: cook()
1082: {
1083: if (VEXIT) eprintf(VEXIT);
1084: fflush(stdout); /* force output */
1085: #ifdef ux3
1086: ioctl(1,TCSETAW, &ttyjunk);
1087: ioctl(1, TCXONC,1); /* Force tty back on */
1088: #else
1089: stty(1,&ttyjunk);
1090: #endif
1091: }
1092:
1093:
1094: /*VARARGS2*/
1095:
1096: char *
1097: nscan(stptr,ret)
1098:
1099: register char *stptr;
1100: register int *ret;
1101: {
1102: register c;
1103:
1104: *ret = 0;
1105: while (((c = *stptr)>='0') && (c <= '9')) {
1106: stptr++;
1107: *ret = *ret*10+(c-'0');
1108: }
1109: return(stptr);
1110: }
1111:
1112:
1113: char *
1114: strcpy(cp,cp1)
1115:
1116: register char *cp;
1117: register char *cp1;
1118: {
1119: while (*cp++ = *cp1++);
1120: return(cp-1);
1121: }
1122:
1123: seprintf(string,fmt, x1)
1124: register char *string;
1125: register char *fmt;
1126: unsigned x1;
1127: {
1128: int c;
1129: int width;
1130: register unsigned int *adx;
1131: extern char *strcpy();
1132:
1133: adx = &x1;
1134: loop:
1135: while((c = *fmt++) != '%') {
1136: *string++ = c;
1137: if(c == '\0') {
1138: return;
1139: }
1140: }
1141: width = 0;
1142: c = *fmt++;
1143: if ((c >= '0') && (c <= '9')) {
1144: fmt = nscan(fmt-1,&width);
1145: c = *fmt++;
1146: }
1147:
1148: switch(c) {
1149: case 'd':
1150: case 'D':
1151: case 'o':
1152: case 'O':
1153: {
1154: register int b;
1155: long n;
1156: long n1;
1157: register int i;
1158: char dstack[20];
1159:
1160: b = (((c=='o') || (c == 'O'))? 8: 10); /* number base */
1161: if ((c == 'o') || (c == 'd')) {
1162: n = (long) (*adx);
1163: if (n > 32768L) n = n-65536L; /* sign correction */
1164: } else {
1165: n = *((long *) adx);
1166: adx += ((sizeof(n)-sizeof(i))/sizeof(i));
1167: }
1168: i = 0;
1169: if (n < 0) {
1170: n = -n;
1171: *string++ = '-';
1172: }
1173:
1174: do {
1175: n1 = n/b;
1176: dstack[i++] = (short) (n-(n1*b));
1177: n = n1;
1178: } while (n != 0); /* figure number */
1179: if ((b == 8) && ((i !=1 ) || (dstack[0] != 0))) dstack[i++]=0;
1180: while (i<width) dstack[i++] = 0;
1181: while (i > 0) *string++ =(dstack[--i] + '0'); /* print number */
1182: }
1183: break;
1184: case 'P':
1185: width *= SREGION;
1186: /* Fall through */
1187: case 'p':
1188: while (width > 0) {
1189: *string++ = *NOP;
1190: width -= ttywarp;
1191: }
1192: adx--;
1193: break;
1194: case 's':
1195: string = strcpy(string,(char *)*adx);
1196: break;
1197: case 'm':
1198: case 'M':
1199: {
1200: char *cp;
1201: if (c=='m') {
1202: cp = &TMAP[width * (*adx)];
1203: } else {
1204: cp = &SMAP[width * (*adx)];
1205: }
1206: for (c = 0; c < width; c++) {
1207: if (*cp) *string++ = *cp++;
1208: }
1209: }
1210: break;
1211: case 'c':
1212: c = *adx;
1213: if (c) {
1214: *string++ = c;
1215: } else {
1216: *string++ = '^';
1217: *string++ = '@'; /* punt */
1218: }
1219: break;
1220: case '%':
1221: *string++ ='%';
1222: adx--;
1223: break;
1224: default:
1225: break;
1226: }
1227: adx++;
1228: goto loop;
1229: }
1230:
1231: mgetchar()
1232: {
1233: fflush(stdout); /* force output */
1234: return(0177 & getchar());
1235: }
1236:
1237: /*VARARGS1*/
1238:
1239: eprintf(string,a1,a2,a3,a4,a5,a6,a7)
1240:
1241: register char *string;
1242:
1243: {
1244: char pbuf[1024];
1245: seprintf(pbuf,string,a1,a2,a3,a4,a5,a6,a7);
1246: PUTS(pbuf);
1247: }
1248:
1249:
1250:
1251: xprintf(sp,ap1,ap2,ap3,ap4,ap5,ap6)
1252: register char *sp;
1253: {
1254: char sbuf[0400]; /* buffer */
1255: register c;
1256: int x;
1257:
1258:
1259: sprintf(sbuf,sp,ap1,ap2,ap3,ap4,ap5,ap6);
1260: sp = sbuf;
1261: while (c = *sp++) {
1262: if (c == '\n') {
1263: clrl();
1264: if (++mline >= ECHOL) {
1265: mline=0;
1266: }
1267: mcol=0;
1268: } else {
1269: xputc(c);
1270: }
1271: }
1272: }
1273:
1274: die(arg)
1275: int arg;
1276: {
1277: mgo(SCRNLIN-1,0);
1278: clrl();
1279: cook();
1280: if (arg) abort(arg);
1281: else exit(0);
1282: }
1283: ttystart()
1284: {
1285: int i;
1286: char *tp;
1287:
1288: setbuf(stdout,ttobuf);
1289:
1290: uncook();
1291: for (i = 0; i < 16; i++) {
1292: signal(i,die);
1293: }
1294: tp = getenv("TERM");
1295: if (tp == NULL) ttype();
1296: else sttype(tp);
1297: }
1298:
1299: insrtc(c)
1300: int c;
1301: {
1302: if (INSERTC == NULL) return(0);
1303: INSON = 1;
1304: ldchar = c;
1305: ldcol = mcol-1;
1306: mputc(c);
1307: INSON = 0;
1308: return(1);
1309: }
1310: delc()
1311: {
1312: register i;
1313:
1314: if (DELC == NULL) return(0);
1315: SREGION=scrjnk[mline]-mcol; /* number of char's gobbled */
1316: if (DELMODE && (osert == 0)) {
1317: eprintf(INSERTM);
1318: osert++;
1319: }
1320: eprintf(DELC); /*clobber next char */
1321: for (i = mcol; i <=scrjnk[mline];i++) {
1322: cmap[mline] [i] = cmap[mline] [i+1];
1323: }
1324: scrjnk[mline]--;
1325: return(1);
1326: }
1327:
1328: /* adjust vertical position of line -- open (or close) lines on */
1329: /* the screen argument is the number of lines to add (or drop). */
1330:
1331: vadjust(xline,tline,x)
1332:
1333: register x;
1334: int xline;
1335: int tline;
1336: {
1337: register i;
1338: register j;
1339: int oldx;
1340:
1341: if (LOPEN == NULL) return(0);
1342:
1343: oldx = xline;
1344:
1345: if (x<0) {
1346: x = -x;
1347: i = 1;
1348: } else i = 0;
1349: SREGION=tline-oldx; /* effected region */
1350: if (i) { /* if deleting lines */
1351: sgo(xline,0);
1352:
1353: if (SCREG) { /*if vt100 stype scrolling */
1354: eprintf(SCREG,oldx+XBASE,tline+XBASE); /*define region*/
1355: scrlin = scrcol = 0;
1356: sgo(tline,0);
1357: for (i = 0; i < x; i ++) {
1358: eprintf(SSCROLL);
1359: }
1360: eprintf(SCREG,XBASE,SCRNLIN);
1361: scrlin = scrcol = 0;
1362: } else {
1363: for (i = 0; i < x; i++) {
1364: eprintf(LDEL);
1365: }
1366: sgo(tline-x+1,0);
1367: for (i = 0; i < x; i++) {
1368: eprintf(LOPEN);
1369: }
1370: }
1371: sgo(oldx,0);
1372: vshift (oldx,tline,x);
1373: } else {
1374: if (SCREG) { /* if vt100 style scrolling */
1375:
1376: eprintf(SCREG,oldx+XBASE,tline+XBASE); /*define region */
1377: scrlin = scrcol = 0; /* vt100 dies */
1378: sgo(xline,0);
1379: for (i = 0; i < x; i ++) {
1380: eprintf(RSCROLL);
1381: }
1382: eprintf(SCREG,XBASE,SCRNLIN);
1383: scrlin = scrcol = 0;
1384: } else {
1385: sgo(tline+1-x,0);
1386: for (i = 0; i < x;i++) eprintf(LDEL);
1387: sgo(oldx,0);
1388: for (i = 0; i < x; i++) eprintf(LOPEN);
1389: }
1390: mgo(oldx,0);
1391:
1392: vshift(oldx,tline,-x);
1393: }
1394: return(1);
1395: }
1396:
1397:
1398: /* sscroll -- try to fix display by scrolling */
1399:
1400: sscroll(x)
1401:
1402: register int x;
1403:
1404: {
1405: register int i;
1406:
1407:
1408: if (SSCROLL == NULL) return(0);
1409:
1410:
1411: sgo(SCRNLIN-1,0); /* to bottom */
1412: SREGION=SCRNLIN; /* number of lines effected */
1413: for (i = 0; i < x; i++) {
1414: eprintf(SSCROLL); /* scroll screen */
1415: }
1416: vshift (0,SCRNLIN-1,x);
1417: }
1418:
1419: /* vshift -- shift the display image from top to bottom (inclusive) by x */
1420:
1421:
1422: vshift(top,bottom,x)
1423:
1424: int top;
1425: int bottom;
1426: int x;
1427:
1428: {
1429: register i;
1430: register j;
1431: char *cp1;
1432: char *cp2;
1433: int *jnkptr;
1434: int start;
1435: int stop;
1436: register int off;
1437:
1438: if (x > 0) {
1439: off = 1;
1440: start = top;
1441: stop = bottom+1;
1442: } else {
1443: off = -1;
1444: start = bottom;
1445: stop = top-1;
1446: }
1447: for (i = start,jnkptr = scrjnk+i; i != stop-x; i+=off,jnkptr+=off) {
1448: *jnkptr = *(jnkptr+x);
1449: cp1 = cmap[i];
1450: cp2 = cmap[i+x];
1451: for (j = 0; j < *jnkptr; j++) {
1452: *cp1++ = *cp2++;
1453: }
1454: }
1455: while (i != stop) {
1456: if (off > 0) {
1457: *jnkptr++ = 0;
1458: i++;
1459: } else {
1460: *jnkptr-- = 0;
1461: i--;
1462: }
1463: }
1464: }
1465:
1466:
1467: /* print an underscored character. */
1468:
1469: pu(c)
1470: register char c;
1471: {
1472: register oc;
1473: c &= 0177;
1474: if ((c == 0)||(c == 040)) {
1475: /* bare underscore */
1476: putchar('_');
1477: return; /* just put out the underscore */
1478: }
1479: if (UEND == 0) {
1480: eprintf(ULINE,c);
1481: } else {
1482: eprintf(ULINE); /* enter "underscore mode" */
1483: putchar(c);
1484: eprintf(UEND);
1485: }
1486: }
1487:
1488: putit(c)
1489: char c;
1490: {
1491: if (drain) return;
1492: if (c & 0200) {
1493: pu(c);
1494: return;
1495: }
1496: putchar(0177 & c);
1497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.