641 lines
19 KiB
C
641 lines
19 KiB
C
/*****************************************************************************
|
|
ReadCS()
|
|
Read command string.
|
|
*****************************************************************************/
|
|
#if CURSES
|
|
#if ULTRIX
|
|
#include <curses.h> /* has to come before zport.h */
|
|
#else
|
|
#include <curses.h> /* has to come before zport.h */
|
|
#endif
|
|
#endif
|
|
#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 */
|
|
#include "deferr.h" /* define identifiers for error messages */
|
|
#include "dscren.h" /* define identifiers for screen i/o */
|
|
#if USE_PROTOTYPES
|
|
static VVOID InpDel(void);
|
|
static unsigned char FirstChar(void);
|
|
static BOOLEAN ChkHlp(charptr HlpEnd);
|
|
#endif
|
|
/*****************************************************************************
|
|
CRCnt maintains a count of the number of carriage returns that have
|
|
been typed by the user while entering a command string. It is used to
|
|
recognize when the user executes a HELP command, which is the only TECO
|
|
command that does not need to be terminated by double escapes. When the very
|
|
first carriage return in the user's command string is struck, TECO checks
|
|
if the text preceding the carriage return is a valid HELP command. This
|
|
checking is only performed when the first carriage return is struck.
|
|
*****************************************************************************/
|
|
static LONG CRCnt; /* carriage-return count */
|
|
static charptr Prompt = (charptr)"\n\r*";
|
|
#if CURSES
|
|
extern int skiprefresh;
|
|
#endif
|
|
/*****************************************************************************
|
|
InpDel()
|
|
This function is called when the user types the DELETE key while
|
|
typing in a command string. What is displayed on his terminal when this
|
|
happens depends on what kind of terminal he has and what the deleted
|
|
character is. This function displays the required character(s).
|
|
*****************************************************************************/
|
|
static VVOID InpDel()
|
|
{
|
|
int i;
|
|
charptr TmpPtr; /* temporary pointer */
|
|
DBGFEN(4, "InpDel", NULL);
|
|
--CBfPtr; /* back up over the DEL */
|
|
if (CBfPtr < CBfBeg) { /* if cmd buffer is empty */
|
|
ZDspBf(Prompt, 3); /* prompt */
|
|
DBGFEX(4, DbgFNm, NULL);
|
|
return;
|
|
}
|
|
if (EtFlag & ET_SCOPE) { /* if it's a scope */
|
|
if (((*CBfPtr > USCHAR) && /* if it was ... */
|
|
(*CBfPtr < DELETE)) || /* ... printable or ... */
|
|
(*CBfPtr == ESCAPE) || /* ... escape or ... */
|
|
(*CBfPtr & '\200')) { /* ....eighth bit is on */
|
|
ZDspBf("\b \b", 3); /* erase one character */
|
|
} else {
|
|
switch (*CBfPtr) {
|
|
case LINEFD:
|
|
ZScrOp(SCR_CUP);
|
|
/* fall through */
|
|
case DELETE:
|
|
break;
|
|
case VRTTAB:
|
|
case FORMFD:
|
|
for (i = 1; i <= FFLINS; i++)
|
|
ZScrOp(SCR_CUP);
|
|
/* fall through */
|
|
case TABCHR:
|
|
case BAKSPC:
|
|
case CRETRN:
|
|
ZDspCh(CRETRN);
|
|
ZScrOp(SCR_EEL);
|
|
if (*CBfPtr == CRETRN) {
|
|
--CRCnt;
|
|
}
|
|
TmpPtr = CBfPtr;
|
|
while (TmpPtr > CBfBeg) {
|
|
TmpPtr--;
|
|
if (IsEOL(*TmpPtr)) {
|
|
++TmpPtr;
|
|
break;
|
|
}
|
|
}
|
|
if (TmpPtr == CBfBeg) {
|
|
ZDspCh('*');
|
|
}
|
|
TypBuf(TmpPtr, CBfPtr);
|
|
break;
|
|
default:
|
|
ZDspBf("\b \b\b \b", 6);
|
|
break;
|
|
} /* end of switch */
|
|
}
|
|
} else { /* else (it's not a scope) */
|
|
EchoIt(*CBfPtr);
|
|
}
|
|
--CBfPtr; /* actually delete the char */
|
|
DBGFEX(4,DbgFNm,NULL);
|
|
}
|
|
/*****************************************************************************
|
|
FirstChar()
|
|
This function deals with the following immediate mode commands:
|
|
? display previous command string up to erroneous command
|
|
/ display verbose explanation of last error
|
|
*q copy last command string to q-register q
|
|
This function is called by ReadCS to read the very first command
|
|
typed by the user. It handles the above immediate mode commands without
|
|
destroying the previous command buffer. Once this function returns, the
|
|
previous command string and error are considered lost by ReadCS, which then
|
|
overwrites the old command string with a new one.
|
|
This function does not deal with the LF and BS immediate mode commands
|
|
because of the following possible sequence of events: the user starts typing
|
|
a command string, then does a ^U to delete it, then tries to use LF or BS
|
|
to position himself in the edit buffer. If this function were responsible for
|
|
LF and BS, then they would not work. ReadCS is responsible for handling the
|
|
LF and BS immediate mode commands.
|
|
*****************************************************************************/
|
|
static unsigned char FirstChar()
|
|
{
|
|
BOOLEAN ImdCmd; /* TRUE if it's '?' or '*' or '/' */
|
|
unsigned char LclStr[2]; /* local string for * processing */
|
|
DEFAULT Status; /* return value for FindQR() */
|
|
charptr TCBfPt; /* temporary holder of CBfPtr */
|
|
charptr TCStEn; /* temporary holder of CStEnd */
|
|
DEFAULT TmpChr; /* temporary character */
|
|
ptrdiff_t TmpSiz;
|
|
#if CURSES
|
|
chtype curses_char;
|
|
int yy;
|
|
int xx;
|
|
#endif
|
|
do {
|
|
if (EvFlag) { /* if EV (edit verify) flag is set */
|
|
DoEvEs(EvFlag); /* handle EV flag */
|
|
}
|
|
#if CURSES
|
|
if (ScroLn > 0 && !skiprefresh)
|
|
redraw();
|
|
#endif
|
|
ZDspCh('*'); /* prompt */
|
|
#if CURSES
|
|
/*
|
|
* This works on a Sun but may be somewhat system dependent - depending on
|
|
* the type of chtype
|
|
*/
|
|
ccs();
|
|
keypad_on();
|
|
l1: getyx(stdscr,yy,xx);
|
|
curses_char = ZChIn(FALSE);
|
|
TmpChr = curses_char;
|
|
if (curses_char == KEY_RIGHT) {
|
|
do_right();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if (curses_char == KEY_LEFT) {
|
|
do_left();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if (curses_char == KEY_DOWN || curses_char == KEY_B2) {
|
|
do_down();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if (curses_char == KEY_UP) {
|
|
do_up();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if ((curses_char == KEY_F(1)) || (curses_char == KEY_ENTER)) {
|
|
do_seetog();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if ((curses_char == KEY_SF) || (curses_char == KEY_NPAGE)) {
|
|
do_sf();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if ((curses_char == KEY_SR) || (curses_char == KEY_PPAGE)) {
|
|
do_sr();
|
|
move(yy,xx);
|
|
goto l1;
|
|
} else if (curses_char >= 0400) {
|
|
ZDspCh('?');
|
|
move(yy,xx);
|
|
goto l1;
|
|
}
|
|
keypad_off();
|
|
#else
|
|
TmpChr = ZChIn(FALSE); /* get a character */
|
|
#endif
|
|
ImdCmd = FALSE; /* assume not an immediate command */
|
|
switch (TmpChr) {
|
|
case DELETE:
|
|
case CTRL_U:
|
|
ZDspCh(CRETRN);
|
|
ImdCmd = TRUE;
|
|
break;
|
|
case '/': /* display verbose error message */
|
|
if (LstErr != ERR_XXX) {
|
|
ZDspCh('/');
|
|
ErrVrb(LstErr);
|
|
ImdCmd = TRUE;
|
|
}
|
|
break;
|
|
case '?': /* display erroneous command string */
|
|
if (LstErr != ERR_XXX) { /* if there was an error */
|
|
ZDspCh('?');
|
|
TypESt();
|
|
ImdCmd = TRUE;
|
|
}
|
|
break;
|
|
case '*': /* store last cmd string in q-reg */
|
|
ZDspCh('*'); /* echo the "*" */
|
|
TmpChr = ZChIn(FALSE); /* get a q-register name */
|
|
if (GotCtC) { /* user typed control-C? */
|
|
GotCtC = FALSE;
|
|
return CTRL_C;
|
|
}
|
|
switch (TmpChr) {
|
|
case CRETRN:
|
|
TmpChr = 0;
|
|
break;
|
|
case DELETE:
|
|
case CTRL_U:
|
|
case BAKSPC:
|
|
ZDspCh(CRETRN);
|
|
break;
|
|
default:
|
|
EchoIt((unsigned char)TmpChr);
|
|
TCBfPt = CBfPtr; /* save CBfPtr */
|
|
TCStEn = CStEnd; /* save CStEnd */
|
|
LclStr[0] = (unsigned char)TmpChr;
|
|
CBfPtr = &LclStr[0];
|
|
if (TmpChr == (DEFAULT)'.') {
|
|
LclStr[1] = (unsigned char)ZChIn(FALSE);
|
|
EchoIt((unsigned char)TmpChr);
|
|
CStEnd = &LclStr[1];
|
|
} else {
|
|
CStEnd = &LclStr[0];
|
|
}
|
|
Status = FindQR(); /* find q-register */
|
|
CBfPtr = TCBfPt; /* restore CBfPtr */
|
|
CStEnd = TCStEn; /* restore CStEnd */
|
|
if (Status == SUCCESS) {
|
|
if (QR->Start != NULL) {
|
|
ZFree((charptr)QR->Start);
|
|
QR->Start = QR->End_P1 = NULL;
|
|
}
|
|
TmpSiz = (CStEnd-CStBeg) + 1;
|
|
if (TmpSiz > 0) {
|
|
if (MakRom((SIZE_T)TmpSiz) != FAILURE) {
|
|
MEMMOVE(QR->Start,CStBeg,(SIZE_T)TmpSiz);
|
|
QR->End_P1 = QR->Start + TmpSiz;
|
|
}
|
|
}
|
|
ZDspBf("\r\n", 2);
|
|
}
|
|
} /* end switch */
|
|
ImdCmd = TRUE;
|
|
break;
|
|
} /* end switch */
|
|
} while (ImdCmd);
|
|
return (unsigned char)TmpChr;
|
|
}
|
|
/*****************************************************************************
|
|
ChkHlp()
|
|
This function checks if the command string buffer contains a HELP
|
|
command. If it does, the help command is processed and a TRUE is returned.
|
|
If the command buffer does not contain a HELP command, a FALSE is returned.
|
|
A HELP command must be the only command in the command string. It takes
|
|
the form
|
|
HELP [/LIBRARY=[=]name] [key-1] [key-2] ...
|
|
*****************************************************************************/
|
|
static BOOLEAN ChkHlp(HlpEnd) /* check for HELP command */
|
|
charptr HlpEnd; /* end of help command */
|
|
{
|
|
DBGFEN(3, "ChkHlp", NULL);
|
|
if ((*CBfBeg != 'H' && *CBfBeg != 'h') ||
|
|
(*(CBfBeg+1) != 'E' && *(CBfBeg+1) != 'e') ||
|
|
(*(CBfBeg+2) != 'L' && *(CBfBeg+2) != 'l') ||
|
|
(*(CBfBeg+3) != 'P' && *(CBfBeg+3) != 'p')) {
|
|
DBGFEX(3, DbgFNm, "FALSE");
|
|
return FALSE;
|
|
}
|
|
if ((*(CBfBeg+4) != '/') &&
|
|
(*(CBfBeg+5) != 'S') && (*(CBfBeg+5) != 's')) {
|
|
ZHelp(CBfBeg+4, HlpEnd-1, FALSE, TRUE);
|
|
} else {
|
|
ZHelp(CBfBeg+6, HlpEnd-1, TRUE, TRUE);
|
|
}
|
|
DBGFEX(3, DbgFNm, "TRUE");
|
|
return TRUE;
|
|
}
|
|
/*****************************************************************************
|
|
ReadCS()
|
|
This function reads a command string from the terminal. It returns to it's
|
|
caller when the command buffer pointed to by CBfBeg contains a command string.
|
|
In addition to echoing the characters typed by the user, this function
|
|
handles the following special things:
|
|
1. DEL delete last character
|
|
2. ^G* retype command string
|
|
3. ^G<SP> retype command line
|
|
4. ^G^G delete command string
|
|
5. ^U delete command line
|
|
6. ^Z^Z^Z exit TECO-C
|
|
7. LF immediate mode: do a 1L1T command
|
|
8. BS immediate mode: do a -1L1T
|
|
9. *q immediate mode: store last command string in q
|
|
10. HELP immediate mode: access HELP subsystem
|
|
11. / immediate mode: display explanation of last error
|
|
12. ? immediate mode: display erroneous command string
|
|
*****************************************************************************/
|
|
#define PRV_CTC 1 /* previous character was control-C */
|
|
#define PRV_CTG 2 /* previous character was control-G */
|
|
#define PRV_DEF 3 /* previous character wasn't ^Z, ^G or ESC */
|
|
#define PRV_ESC 4 /* previous character was escape */
|
|
#define PRV_Z1 5 /* previous character was one control-Z */
|
|
#define PRV_Z2 6 /* previous character was two control-Z */
|
|
VVOID ReadCS()
|
|
{
|
|
BOOLEAN BadSeq; /* bad escape sequence indicator */
|
|
unsigned char ctrstr[3]; /* temp buffer to display ^chars as string */
|
|
LONG HowFar;
|
|
int PrvChr; /* previous character flags */
|
|
unsigned char TmpChr; /* temporary character */
|
|
charptr TmpPtr; /* temporary pointer */
|
|
int i;
|
|
ctrstr[0] = '^'; /* caret */
|
|
ctrstr[2] = '\0'; /* end-of-string */
|
|
CRCnt = 0; /* count of carriage-returns */
|
|
PrvChr = PRV_DEF; /* no previous characters */
|
|
TmpChr = FirstChar(); /* get first character */
|
|
CBfPtr = CBfBeg; /* make command buffer empty */
|
|
*CBfPtr = TmpChr;
|
|
LstErr = ERR_XXX; /* last error message is undefined */
|
|
FOREVER {
|
|
if (*CBfPtr == ESCAPE) {
|
|
if (EtFlag & ET_VT200) { /* if vt200 mode */
|
|
*CBfPtr = (unsigned char)ZChIn(FALSE);
|
|
BadSeq = FALSE; /* initialize BadSeq */
|
|
if (*CBfPtr != '[') { /* if not ESC sequence */
|
|
BadSeq = TRUE;
|
|
} else {
|
|
*CBfPtr = (unsigned char)ZChIn(FALSE);
|
|
switch (*CBfPtr) {
|
|
case '2': /* f9 - f16 */
|
|
*CBfPtr = (unsigned char)ZChIn(FALSE);
|
|
if (*CBfPtr == '4') {
|
|
TmpChr = (unsigned char)ZChIn(FALSE);
|
|
if (TmpChr != '~') {
|
|
BadSeq = TRUE;
|
|
} else {
|
|
*CBfPtr = BAKSPC;
|
|
}
|
|
} else if (*CBfPtr == '5') {
|
|
TmpChr = (unsigned char)ZChIn(FALSE);
|
|
if (TmpChr != '~') {
|
|
BadSeq = TRUE;
|
|
} else {
|
|
*CBfPtr = LINEFD;
|
|
}
|
|
} else {
|
|
BadSeq = TRUE;
|
|
}
|
|
break;
|
|
#if FALSE
|
|
case 'A': /* up arrow */
|
|
case 'B': /* down arrow */
|
|
case 'C': /* right arrow */
|
|
case 'D': /* left arrow */
|
|
#endif
|
|
default:
|
|
BadSeq = TRUE;
|
|
} /* end of switch */
|
|
} /* */
|
|
if (BadSeq) {
|
|
ZDspBf("\r\n\n\tInvalid escape sequence.\r\n\n", 31);
|
|
ZDspBf("\tThe 16384 bit of the ET flag is set, which means\r\n", 52);
|
|
ZDspBf("\tthat you are in VT200 mode. In this mode, the\r\n", 50);
|
|
ZDspBf("\tescape character is not used to terminate commands.\r\n", 54);
|
|
ZDspBf("\tIt is used to introduce escape sequences. This\r\n", 50);
|
|
ZDspBf("\tallows the function keys to take on meanings. The\r\n", 53);
|
|
ZDspBf("\taccent grave (~) character is the command terminator.\r\n", 56);
|
|
ZDspBf("\tIf you want to turn off VT200 mode, say 16384,0ET``\r\n", 55);
|
|
ZDspBf("\tNote that the recognition of accent grave as a\r\n", 49);
|
|
ZDspBf("\tcommand terminator is controlled by the 8192 bit\r\n", 51);
|
|
ZDspBf("\tof the ET flag, separate from the VT200 bit.\r\n\n", 49);
|
|
ZDspBf("\tThere may be a part of the unrecognized escape\r\n", 49);
|
|
ZDspBf("\tsequence in the command string. The last line of\r\n", 52);
|
|
ZDspBf("\tthe command string is shown to help you recover.\r\n", 51);
|
|
PrvChr = PRV_CTG;
|
|
CBfPtr++;
|
|
*CBfPtr = ' ';
|
|
} /* end if BadSeq) */
|
|
} else { /* else not vt200 mode */
|
|
ZDspCh('$');
|
|
if (PrvChr == PRV_ESC) {
|
|
ZDspBf("\r\n", 2);
|
|
CStEnd = CBfPtr;
|
|
return;
|
|
}
|
|
PrvChr = PRV_ESC;
|
|
}
|
|
} else { /* else *CBfPtr != ESCAPE */
|
|
switch (ChrMsk[(unsigned char)*CBfPtr] & '\17') {
|
|
case RCS_LWR: /* lowercase */
|
|
if ((EtFlag & ET_READ_LOWER) == 0) {
|
|
*CBfPtr &= '\137'; /* convert to uppercase */
|
|
}
|
|
/* fall through */
|
|
case RCS_DEF: /* default case */
|
|
ZDspCh(*CBfPtr); /* echo the character */
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_GRV: /* accent-grave */
|
|
ZDspCh('`');
|
|
if (EtFlag & ET_ACCENT_GRAVE) {
|
|
*CBfPtr = ESCAPE;
|
|
if (PrvChr == PRV_ESC) {
|
|
ZDspBf("\r\n", 2);
|
|
CStEnd = CBfPtr;
|
|
return;
|
|
}
|
|
PrvChr = PRV_ESC;
|
|
} else {
|
|
PrvChr = PRV_DEF;
|
|
}
|
|
break;
|
|
case RCS_SP: /* space */
|
|
if (PrvChr == PRV_CTG) { /* if previous char was ^G */
|
|
CBfPtr--; /* remove the space */
|
|
TmpPtr = CBfPtr;
|
|
while (TmpPtr > CBfBeg) {
|
|
TmpPtr--;
|
|
if (IsEOL(*TmpPtr)) {
|
|
++TmpPtr;
|
|
break;
|
|
}
|
|
}
|
|
ZDspBf("\r\n", 2);
|
|
if (TmpPtr == CBfBeg) {
|
|
ZDspCh('*');
|
|
}
|
|
TypBuf(TmpPtr, CBfPtr);
|
|
CBfPtr--; /* remove ^G */
|
|
} else { /* previous char was not ^G */
|
|
ZDspCh(SPACE); /* just echo space */
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_DEL: /* delete */
|
|
InpDel();
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_CR: /* carriage return */
|
|
ZDspCh(CRETRN);
|
|
if ((CRCnt == 0) && ChkHlp(CBfPtr)) {
|
|
ZDspCh('*');
|
|
CBfPtr = CBfBeg - 1;
|
|
} else {
|
|
++CRCnt;
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_LF: /* line feed */
|
|
if (CBfPtr == CBfBeg) { /* if immediate mode */
|
|
#if CURSES
|
|
if (ScroLn == 0 || skiprefresh)
|
|
#endif
|
|
if (EtFlag & ET_SCOPE) {
|
|
ZDspCh(CRETRN);
|
|
ZScrOp(SCR_EEL);
|
|
}
|
|
HowFar = Ln2Chr((LONG)1);
|
|
MEMMOVE(GapBeg, GapEnd+1, (SIZE_T)HowFar);
|
|
GapBeg += HowFar;
|
|
GapEnd += HowFar;
|
|
if (EvFlag) {
|
|
DoEvEs(EvFlag);
|
|
} else {
|
|
#if CURSES
|
|
if (ScroLn == 0 || skiprefresh)
|
|
#endif
|
|
TypBuf(GapEnd+1, GapEnd+Ln2Chr((LONG)1)+1);
|
|
}
|
|
#if CURSES
|
|
if (ScroLn > 0 || skiprefresh)
|
|
dolf(HowFar);
|
|
if (ScroLn == 0 || skiprefresh)
|
|
#endif
|
|
ZDspCh('*');
|
|
#if CURSES
|
|
clrtoeol();
|
|
#endif
|
|
CBfPtr = CBfBeg - 1;
|
|
} else {
|
|
ZDspCh(LINEFD);
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_CTC: /* control-C */
|
|
GotCtC = FALSE; /* clear "stop soon" flag */
|
|
ctrstr[1] = 'C';
|
|
ZDspBf(ctrstr, 2); /* display "^C" */
|
|
if (PrvChr == PRV_CTC) { /* if second control-C */
|
|
TAbort(EXIT_SUCCESS); /* terminate */
|
|
} else {
|
|
PrvChr = PRV_CTC;
|
|
}
|
|
ZDspBf(Prompt, 3); /* prompt */
|
|
CBfPtr = CBfBeg - 1; /* reset cmd-buffer pointer */
|
|
CRCnt = 0; /* carriage-return cnt = 0 */
|
|
break;
|
|
case RCS_BS: /* backspace */
|
|
if (CBfPtr == CBfBeg) { /* if immediate mode */
|
|
#if CURSES
|
|
if (ScroLn == 0 || skiprefresh)
|
|
#endif
|
|
if (EtFlag & ET_SCOPE) {
|
|
ZDspCh(CRETRN);
|
|
ZScrOp(SCR_EEL);
|
|
}
|
|
HowFar = Ln2Chr(-1L);
|
|
GapBeg += HowFar;
|
|
GapEnd += HowFar;
|
|
MEMMOVE(GapEnd+1, GapBeg, (SIZE_T)-HowFar);
|
|
if (EvFlag) {
|
|
DoEvEs(EvFlag);
|
|
} else {
|
|
#if CURSES
|
|
if (ScroLn == 0 || skiprefresh)
|
|
#endif
|
|
TypBuf(GapEnd+1, GapEnd+Ln2Chr((LONG)1)+1);
|
|
}
|
|
#if CURSES
|
|
if (ScroLn > 0 && !skiprefresh)
|
|
dobs(HowFar);
|
|
if (ScroLn == 0 || skiprefresh)
|
|
#endif
|
|
ZDspCh('*');
|
|
#if CURSES
|
|
clrtoeol();
|
|
#endif
|
|
CBfPtr = CBfBeg - 1;
|
|
} else {
|
|
ZDspCh(BAKSPC);
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_CTG: /* control-G */
|
|
ZBell(); /* ring the bell (or flash) */
|
|
ZDspBf("^G", 2);
|
|
if (PrvChr == PRV_CTG) { /* if previous char was ^G */
|
|
CBfPtr = CBfBeg - 1;
|
|
ZDspBf(Prompt, 3);
|
|
CRCnt = 0;
|
|
PrvChr = PRV_DEF;
|
|
} else {
|
|
PrvChr = PRV_CTG;
|
|
}
|
|
break;
|
|
case RCS_AST: /* asterisk */
|
|
ZDspCh('*');
|
|
if (PrvChr == PRV_CTG) {
|
|
CBfPtr -= 2;
|
|
ZDspBf(Prompt, 3);
|
|
CRCnt = 0;
|
|
TypBuf(CBfBeg, CBfPtr);
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_CTZ: /* control-Z */
|
|
ctrstr[1] = 'Z';
|
|
ZDspBf(ctrstr, 2);
|
|
if (PrvChr == PRV_Z2) {
|
|
TAbort(EXIT_SUCCESS);
|
|
} else if (PrvChr == PRV_Z1) {
|
|
PrvChr = PRV_Z2;
|
|
} else {
|
|
PrvChr = PRV_Z1;
|
|
}
|
|
break;
|
|
case RCS_CCH: /* other control char */
|
|
#if CURSES
|
|
if (*CBfPtr == CTRL_W) {
|
|
if (CBfPtr == CBfBeg) {
|
|
if (ScroLn > 0) {
|
|
centre();
|
|
} else {
|
|
ZDspBf(Prompt, 3);
|
|
}
|
|
clrtoeol();
|
|
CBfPtr = CBfBeg - 1;
|
|
} else {
|
|
ZDspBf("^W", 2);
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
}
|
|
#endif
|
|
ctrstr[1] = *CBfPtr | '\100';
|
|
ZDspBf(ctrstr, 2);
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_CTU: /* control-U */
|
|
while (--CBfPtr >= CBfBeg) {
|
|
if (IsEOL(*CBfPtr)) {
|
|
break;
|
|
}
|
|
}
|
|
ZDspCh(CRETRN);
|
|
if (EtFlag & ET_SCOPE) {
|
|
ZScrOp(SCR_EEL); /* erase line */
|
|
} else {
|
|
ZDspCh(LINEFD);
|
|
}
|
|
if (CBfPtr < CBfBeg) {
|
|
ZDspCh('*');
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
case RCS_VF: /* vert. tab or form feed */
|
|
ZDspCh(CRETRN);
|
|
for (i = 1; i <= FFLINS; i++) {
|
|
ZDspCh(LINEFD);
|
|
}
|
|
PrvChr = PRV_DEF;
|
|
break;
|
|
} /* end of switch */
|
|
}
|
|
if (++CBfPtr > CBfEnd) {
|
|
ZDspBf("command buffer overflow\r\n", 25); /* ??? */
|
|
TAbort(EXIT_FAILURE); /* exit TECO-C */
|
|
}
|
|
*CBfPtr = (unsigned char)ZChIn(FALSE); /* read a character */
|
|
} /* end of FOREVER loop */
|
|
}
|