133 lines
4.3 KiB
C
133 lines
4.3 KiB
C
/*****************************************************************************
|
|
TypBuf()
|
|
This function displays a buffer on the terminal screen. YBfBeg
|
|
points to the first character of the buffer, and YBfEnd points to the
|
|
character following the last character of the buffer.
|
|
If the "no conversions" bit is not set in the ET flag, then this
|
|
function will convert non-displayable characters into a displayable form
|
|
before displaying them. The following conversions are performed:
|
|
1. uppercase and lowercase conversions based on EU flag
|
|
2. <DEL> is not output
|
|
3. <VT> to <lf><lf><lf><lf><lf>
|
|
4. <FF> to <cr><lf><lf><lf><lf><lf>
|
|
5. ^G to <BEL> and ^G
|
|
6. <ESC> to $
|
|
7. all control characters except <BS>, <TAB>, <LF>, <CR> and the
|
|
ones listed above to the ^x format, where x is uppercase
|
|
It is inefficient (though easy) to simply output each character in the
|
|
buffer to be displayed individually, one after the other. To make output
|
|
to the terminal fast requires calls to ZDspBf, which outputs a group of
|
|
characters in one operation. The following code groups each sequence of
|
|
characters containing no "convertable" characters and calls ZDspBf with the
|
|
group. Whenever a character which needs to be converted is encountered,
|
|
the group up to the character is output, a separate output call is made
|
|
for the special character, and another group is started.
|
|
*****************************************************************************/
|
|
#include "zport.h" /* define portability identifiers */
|
|
#include "tecoc.h" /* define general identifiers */
|
|
#include "defext.h" /* define external global variables */
|
|
#include "dchars.h" /* define identifiers for characters */
|
|
#include "chmacs.h" /* define character processing macros */
|
|
VVOID TypBuf(YBfBeg, YBfEnd) /* type a buffer on the terminal */
|
|
charptr YBfBeg;
|
|
charptr YBfEnd;
|
|
{
|
|
charptr YBfPtr;
|
|
#if DEBUGGING
|
|
static char *DbgFNm = "TypBuf";
|
|
sprintf(DbgSBf,"YBfBeg = %ld, YBfEnd = %ld, (length = %ld)",
|
|
Zcp2ul(YBfBeg), Zcp2ul(YBfEnd), (YBfEnd-YBfBeg));
|
|
DbgFEn(5,DbgFNm,DbgSBf);
|
|
#endif
|
|
if (EtFlag & ET_IMAGE_MODE) { /* if no conversions */
|
|
ZDspBf(YBfBeg, YBfEnd-YBfBeg);
|
|
DBGFEX(5,DbgFNm,NULL);
|
|
return;
|
|
}
|
|
YBfPtr = YBfBeg;
|
|
while (YBfPtr < YBfEnd && !GotCtC) {
|
|
if (EuFlag != EU_NONE) { /* do case flagging? */
|
|
if (Is_Lower(*YBfPtr)) {
|
|
/*
|
|
* It is lowercase. If EuFlag is EU_LOWER, flag it. In any case, convert
|
|
* to uppercase for display.
|
|
*/
|
|
if (YBfPtr != YBfBeg) {
|
|
ZDspBf(YBfBeg, YBfPtr-YBfBeg);
|
|
}
|
|
if (EuFlag == EU_LOWER) {
|
|
ZDspCh('\''); /* flag it */
|
|
}
|
|
ZDspCh(*YBfPtr & '\137');
|
|
YBfBeg = ++YBfPtr;
|
|
continue;
|
|
} else if (Is_Upper(*YBfPtr) && (EuFlag == EU_UPPER)) {
|
|
/*
|
|
* it is uppercase and we're flagging uppercase.
|
|
*/
|
|
if (YBfPtr != YBfBeg) {
|
|
ZDspBf(YBfBeg, YBfPtr-YBfBeg);
|
|
}
|
|
ZDspCh('\''); /* flag it */
|
|
ZDspCh(*YBfPtr);
|
|
YBfBeg = ++YBfPtr;
|
|
continue;
|
|
}
|
|
/* else it isn't lower or uppercase, fall through...*/
|
|
}
|
|
/*
|
|
* if *YBfPtr is a line feed, display what we've accumulated so far.
|
|
* We do this so ^C's can interrupt the display of a large buffer.
|
|
*
|
|
* else if the character is displayable, accumulate it
|
|
*
|
|
* else (the character is a control character), handle it
|
|
*/
|
|
if (*YBfPtr == LINEFD) {
|
|
++YBfPtr;
|
|
ZDspBf(YBfBeg, YBfPtr-YBfBeg);
|
|
YBfBeg = YBfPtr;
|
|
} else if (((*YBfPtr > USCHAR) && (*YBfPtr < DELETE)) ||
|
|
(*YBfPtr == TABCHR) ||
|
|
(*YBfPtr == CRETRN)) {
|
|
++YBfPtr;
|
|
} else if (*YBfPtr & '\200') { /* MSB set? */
|
|
if (EtFlag & ET_EIGHTBIT) {
|
|
++YBfPtr;
|
|
} else {
|
|
if (YBfPtr != YBfBeg) {
|
|
ZDspBf(YBfBeg, YBfPtr-YBfBeg);
|
|
}
|
|
ZDspCh('[');
|
|
MakDBf((LONG)*YBfPtr, 16);
|
|
*DBfPtr++ = ']';
|
|
ZDspBf(DBfBeg, DBfPtr-DBfBeg);
|
|
YBfBeg = ++YBfPtr;
|
|
}
|
|
} else { /* it's a control character */
|
|
if (YBfPtr != YBfBeg) {
|
|
ZDspBf(YBfBeg, YBfPtr-YBfBeg);
|
|
}
|
|
switch (*YBfPtr) {
|
|
case ESCAPE: ZDspCh('$');
|
|
break;
|
|
case BAKSPC: ZDspBf("^H",2);
|
|
break;
|
|
case FORMFD: ZDspCh('\r');
|
|
/* fall through */
|
|
case VRTTAB: ZDspBf("\n\n\n\n",4);
|
|
/* fall through */
|
|
case DELETE: break;
|
|
case CTRL_G: ZDspCh(CTRL_G);
|
|
default: ZDspCh('^');
|
|
ZDspCh(*YBfPtr | '\100');
|
|
}
|
|
YBfBeg = ++YBfPtr;
|
|
}
|
|
}
|
|
if (YBfPtr != YBfBeg) {
|
|
ZDspBf(YBfBeg, YBfPtr-YBfBeg);
|
|
}
|
|
DBGFEX(5,DbgFNm,NULL);
|
|
}
|