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