1 /*****************************************************************************
2 
3 	TypBuf()
4 
5 	This function displays a buffer on the terminal screen.  YBfBeg
6 points to the first character of the buffer,  and YBfEnd points to the
7 character following the last character of the buffer.
8 	If the "no conversions" bit is not set in the ET flag,  then this
9 function will convert non-displayable characters into a displayable form
10 before displaying them.  The following conversions are performed:
11 
12 	1. uppercase and lowercase conversions based on EU flag
13 	2. <DEL> is not output
14 	3. <VT> to <lf><lf><lf><lf><lf>
15 	4. <FF> to <cr><lf><lf><lf><lf><lf>
16 	5. ^G to <BEL> and ^G
17 	6. <ESC> to $
18 	7. all control characters except <BS>, <TAB>, <LF>, <CR> and the
19 	   ones listed above to the ^x format,  where x is uppercase
20 
21 	It is inefficient (though easy) to simply output each character in the
22 buffer to be displayed individually,  one after the other.  To make output
23 to the terminal fast requires calls to ZDspBf,  which outputs a group of
24 characters in one operation.  The following code groups each sequence of
25 characters containing no "convertable" characters and calls ZDspBf with the
26 group.  Whenever a character which needs to be converted is encountered,
27 the group up to the character is output,  a separate output call is made
28 for the special character,  and another group is started.
29 
30 *****************************************************************************/
31 
32 #include "zport.h"		/* define portability identifiers */
33 #include "tecoc.h"		/* define general identifiers */
34 #include "defext.h"		/* define external global variables */
35 #include "dchars.h"		/* define identifiers for characters */
36 #include "chmacs.h"		/* define character processing macros */
37 
TypBuf(YBfBeg,YBfEnd)38 VVOID TypBuf(YBfBeg, YBfEnd)	/* type a buffer on the terminal */
39 charptr YBfBeg;
40 charptr YBfEnd;
41 {
42     charptr YBfPtr;
43 
44 #if DEBUGGING
45     static char *DbgFNm = "TypBuf";
46     sprintf(DbgSBf,"YBfBeg = %ld, YBfEnd = %ld, (length = %ld)",
47 	    Zcp2ul(YBfBeg), Zcp2ul(YBfEnd), (YBfEnd-YBfBeg));
48     DbgFEn(5,DbgFNm,DbgSBf);
49 #endif
50 
51     if (EtFlag & ET_IMAGE_MODE) {		/* if no conversions */
52         ZDspBf(YBfBeg, YBfEnd-YBfBeg);
53 	DBGFEX(5,DbgFNm,NULL);
54 	return;
55     }
56 
57     YBfPtr = YBfBeg;
58     while (YBfPtr < YBfEnd && !GotCtC) {
59         if (EuFlag != EU_NONE) {		/* do case flagging? */
60 	    if (Is_Lower(*YBfPtr)) {
61 /*
62  * It is lowercase. If EuFlag is EU_LOWER, flag it.  In any case, convert
63  * to uppercase for display.
64  */
65 	        if (YBfPtr != YBfBeg) {
66 		    ZDspBf(YBfBeg, YBfPtr-YBfBeg);
67 		}
68 		if (EuFlag == EU_LOWER) {
69 		    ZDspCh('\'');		/* flag it */
70 		}
71 		ZDspCh(*YBfPtr & '\137');
72 		YBfBeg = ++YBfPtr;
73 		continue;
74 	    } else if (Is_Upper(*YBfPtr) && (EuFlag == EU_UPPER)) {
75 /*
76  * it is uppercase and we're flagging uppercase.
77  */
78 	        if (YBfPtr != YBfBeg) {
79 		    ZDspBf(YBfBeg, YBfPtr-YBfBeg);
80 		}
81 		ZDspCh('\'');			/* flag it */
82 		ZDspCh(*YBfPtr);
83 		YBfBeg = ++YBfPtr;
84 		continue;
85 	    }
86 /* else it isn't lower or uppercase, fall through...*/
87 	}
88 
89 /*
90  * if *YBfPtr is a line feed, display what we've accumulated so far.
91  * We do this so ^C's can interrupt the display of a large buffer.
92  *
93  * else if the character is displayable, accumulate it
94  *
95  * else (the character is a control character), handle it
96  */
97 
98 	if (*YBfPtr == LINEFD) {
99 	    ++YBfPtr;
100 	    ZDspBf(YBfBeg, YBfPtr-YBfBeg);
101 	    YBfBeg = YBfPtr;
102 	} else if (((*YBfPtr > USCHAR) && (*YBfPtr < DELETE)) ||
103 		   (*YBfPtr == TABCHR) ||
104 		   (*YBfPtr == CRETRN)) {
105 	    ++YBfPtr;
106 	} else if (*YBfPtr  & '\200') {		/* MSB set? */
107 	    if (EtFlag & ET_EIGHTBIT) {
108 	        ++YBfPtr;
109 	    } else {
110 	        if (YBfPtr != YBfBeg) {
111 		    ZDspBf(YBfBeg, YBfPtr-YBfBeg);
112 		}
113 		ZDspCh('[');
114 		MakDBf((LONG)*YBfPtr, 16);
115 		*DBfPtr++ = ']';
116 		ZDspBf(DBfBeg, DBfPtr-DBfBeg);
117 		YBfBeg = ++YBfPtr;
118 	    }
119 	} else {				/* it's a control character */
120 	    if (YBfPtr != YBfBeg) {
121 	        ZDspBf(YBfBeg, YBfPtr-YBfBeg);
122 	    }
123 	    switch (*YBfPtr) {
124 		case ESCAPE:	ZDspCh('$');
125 				break;
126 		case BAKSPC:	ZDspBf("^H",2);
127 				break;
128 		case FORMFD:	ZDspCh('\r');
129 				/* fall through */
130 		case VRTTAB:	ZDspBf("\n\n\n\n",4);
131 				/* fall through */
132 		case DELETE:	break;
133 		case CTRL_G:	ZDspCh(CTRL_G);
134 		default:	ZDspCh('^');
135 				ZDspCh(*YBfPtr | '\100');
136 	    }
137 	    YBfBeg = ++YBfPtr;
138 	}
139     }
140 
141     if (YBfPtr != YBfBeg) {
142         ZDspBf(YBfBeg, YBfPtr-YBfBeg);
143     }
144 
145     DBGFEX(5,DbgFNm,NULL);
146 }
147