/* @(#)tvgets.c 17.1.1.1 (ES0-DMD) 01/25/02 17:36:56 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .IDENTIFICATION tvgets.c .AUTHOR Francois Ochsenbein [ESO-IPG] .LANGUAGE C .KEYWORDS On-line input editing .ENVIRONMENT TermWindows .COMMENTS This module contains routines to perform command input, at the Terminal Level \begin{TeX} \\ This module is only there to be able to use on-line editiing facilities without any window. Unlike tw\_gets functions, commands are not stacked, and the memory is limited to what was just typed. The default actions of control characters are defined as TW\_cc\_default in {\tt twparam.h}, with choices UNIX-like, VMS-like or a third set. The action of each control character may be modified with the tv\_setcc(control\_character, action) (DefineControl) function. The characters that stop output may be defined via the tv\_stopin funtion. \end{TeX} .VERSION 3.0 14-Apr-1988: Creation for MIDAS usage. .VERSION 3.1 05-Oct-1988: Modifications for MIDAS: Command Stacking allowed. .VERSION 3.2 21-Feb-1990: Suppress all warnings -----------------------------------------------------------------------*/ #define DEBUG 0 /* For debugging */ #define PM_LEVEL LEVEL_TV #define TW_import 0 #define TW_STRUCT 0 /* Do not use window Structures */ #define TW_MACROS 0 /* Don't use Windows Macros */ #include MID_EXTERN TERM *terms ; #if DEBUG # define ENTER_DEBUG(x) ENTER(x) # define EXIT_DEBUG(x) EXIT(x) # define TERMTEST if(!terms->version) tv_gopen();\ tv_ed(terms) #else # define TERMTEST if(!terms->version) tv_gopen() # define ENTER_DEBUG(x) # define EXIT_DEBUG(x) return(x) #endif #define FINISH goto FIN MID_STATIC unsigned int f = 0; /* Flags to communicate */ MID_STATIC unsigned int f0= Echo|Stacking;/* Flags to communicate */ static int J; /* Column width */ static int init_pos; /* Where is the cursor at beginning */ static char *p_start; MID_STATIC char *stop_list = (char *)0; MID_STATIC int stop_len = 0; #define Stop 0x0100 #define Stop1 0x0400 #define Special 0x0200 #define NoMore 0x1000 #define Raw 0x2000 /* Stored Commands as a static structure */ static unsigned char command_buffer[1600] = {0,0,0,0}; static COMMAND command = { MASK('\r'), /* Which controls exit */ 0, /* Which arrow keys exit */ 0, /* Which special keys exit */ 0, /* last_type */ 0, /* last_char */ sizeof(command_buffer), 2, /* used */ 0, /* pointed */ 0, /* pointed_no */ 1, /* first_no */ 0, /* last_no */ command_buffer }; static COMMAND *c = &command; static short command_number; static int command_len; MONITOR(TVGETS); /*========================================================================== * o1 *==========================================================================*/ static int o1(ch, len) /*+++ .PURPOSE Optimized output of 1 character. .RETURNS 0 / 1 (number of chars output on Screen) .REMARKS Complete string rewritten if in InsertMode. ---*/ char *ch; /* IN: Character to output */ int len; /* IN: Length of input */ { char *p; int state_buffer; ENTER_DEBUG("+o1"); if_not(f&Echo) EXIT_DEBUG(0); p = ch; state_buffer = tv_buffer(1); /* To output only at end */ status = WriteBinary(p, 1); p++; if ( f & Imode) /* Continuation to write */ { len--; WriteBinary(p, len); SetPosition(GetPosition() - len); } tv_buffer(state_buffer); /* Output everything */ /* Check if the Screen scrolled; modify accordingly init_pos */ init_pos = GetPosition() - (p - p_start); EXIT_DEBUG(status); } /*====================================================================== * mv1 *======================================================================*/ static int mv1(direction, max_move) /*+++++ .PURPOSE Optimized cursor mouvement of 1 place in the specified direction: up, down, right, left or home. .RETURNS The actual displacement in bytes. .REMARKS Move is limited... ------*/ int direction; /* IN: The direction of the displacement */ int max_move; /* IN: Maximal right / down displacement in bytes */ { int pos, new_pos; ENTER_DEBUG("+mv1"); pos = GetPosition(); new_pos = pos; switch(direction) { case _LEFT_: new_pos -= 1; break; case _RIGHT_: new_pos += MIN(max_move, 1); break; case _UP_: new_pos -= J; break; case _DOWN_: new_pos += MIN(max_move, J); break; default: new_pos = init_pos; } if (new_pos < init_pos) new_pos = init_pos; SetPosition(new_pos); EXIT_DEBUG(new_pos - pos); } /*====================================================================== * dc *======================================================================*/ static int dc(str, nd, len) /*+++++ .PURPOSE Delete characters at left of cursor. .RETURNS 0 .REMARKS ------*/ char *str; /* IN: The new string */ int nd; /* IN: Number of bytes to delete */ int len; /* IN: Length of text */ { int pos, nb, state_buffer; static char blanks[] = " "; ENTER_DEBUG("dc"); state_buffer = tv_buffer(1); /* To output only at end */ pos = GetPosition() - nd; SetPosition(pos); /* ClearDown(); */ if (len) WriteBinary(str, len); for (nb = nd; nb > 0; nb -= sizeof(blanks)-1) WriteBinary(blanks, MIN(nb, sizeof(blanks)-1)); SetPosition(pos); tv_buffer(state_buffer); /* Output everything */ EXIT_DEBUG(0); } /*====================================================================== * show *======================================================================*/ static int show(str, in, len) /*+++++ .PURPOSE Redisplay the string (in, len) in place of the current command, and copy it to str. .RETURNS Length of string .REMARKS ------*/ char *str; /* OUT: copied string */ char *in; /* IN: string to display */ int len; /* IN: Length of in */ { int l; l = MIN (len, command_len); oscopy (str, in, l); SetPosition(init_pos); ClearDown(); WriteBinary(str, l); /* Check if the Screen scrolled; modify accordingly init_pos */ init_pos = GetPosition() - l; return(l); } /*==========================================================================*/ static int zm(direction) /*+++ .PURPOSE Move in the command stack according to the specified direction. .RETURNS OK / NOK (at the top or bottom of the stack) .REMARKS ---*/ int direction; /* IN: _UP_, _DOWN_ or _HOME_ (last command) */ { status = NOK; switch(direction) { case _UP_: /* Towards the beginning of the stack */ if (c->pointed_no <= c->first_no) { c->pointed_no = c->first_no - 1; c->pointed = 0; FINISH; } (c->pointed_no)--; (c->pointed)--; /* Index of suffix length */ (c->pointed) -= (1 + *(c->text + c->pointed)); break; case _DOWN_: /* Towards the bottom of the stack */ if (c->pointed_no >= c->last_no) { c->pointed_no = c->last_no + 1; c->pointed = c->used; FINISH; } (c->pointed_no)++; (c->pointed) += (2 + *(c->text + c->pointed)); break; default: /* The last issued command */ if (c->last_no < c->first_no) { c->pointed_no = 0; c->pointed = 0; FINISH; } c->pointed_no = c->last_no; c->pointed = (c->used) - 1; (c->pointed) -= (1 + *(c->text + c->pointed)); break; } status = OK; FIN: return(status); } /*========================================================================== * zadd *==========================================================================*/ static int zadd(str, nbytes, opt) /*+++ .PURPOSE Insert into the command stack the string str. .RETURNS OK / NOK (not enough space) .REMARKS ---*/ char *str; /* IN: The string to insert */ int nbytes; /* IN: Length of the str string */ int opt; /* IN: Option 1 to add effectively / 2 only if\ differs from previous */ { char *p; int i,u, l; TRACE_ED_STR2("Command = ",str,nbytes); status = NOK; if (nbytes < 0) FINISH; if (c->size == 0) FINISH; /* Check it it's the same command as previous one */ if ((opt == 2) && zm(_HOME_)) /* Get last command */ { p = (char *)(c->text + c->pointed); if ((*(p++) == nbytes) && (oscomp(p, str, nbytes) == 0)) { status = OK; FINISH; } } u = c->used + nbytes + 2; /* Used bytes after addition */ i = 2; while (u > c->size) /* Look if stack must be compressed */ { l = *(c->text + i) + 2; /* Length of command */ (c->first_no)++; u -= l, i += l; } if (u < 2) /* Not enough space ... */ { c->used = 2; FINISH; } if (i>2) { l = c->used - i; /* Length to copy */ c->used = 2 + oscopy((char *)(c->text+2), (char *)(c->text + i), l); } c->pointed = c->used; p = (char *)(c->text + c->used); *(p++) = nbytes; /* Prefix length */ p += oscopy((char *)p, (char *)str, nbytes); /* Copy text */ *(p++) = nbytes; /* Suffix length */ if (opt) /* Modify only if required */ { c->used = (unsigned char *)p - (c->text); (c->last_no)++; (c->pointed_no) = c->last_no; } status = OK; FIN: return(status); } /*========================================================================== * tv_stopin *==========================================================================*/ int tv_stopin(type, list) /*+++ .PURPOSE Define the list of Characters that stop the Input: Control Characters, Arrows, Keypad, Function Keys. .RETURNS OK / NOK .REMARKS For type _STANDARD_ or _ARROW_, list gives the ASCII equivalence, e.g. A for Control A, U for the Up Key. For a void string (""), all stopping characters are removed; a string starting with + means "add to existing list", with - "delete from existing list". The * acts as the wild character, e.g. "*-" means "delete all". By default, only the \r (Carriage-Return) stops the input. ---*/ int type; /* IN: _STANDARD_ , _ARROW_, _KEYPAD_, _PF_ or _FK_ */ char *list; /* IN: The characters that may be used to terminate; \ the * is used as a wild character \ (enable all) */ { char *p; int wild; unsigned int i; ENTER("tv_stopin"); if_not(list) EXIT(NOK); p = list; wild = (*p == '+' ? 1 : (*p == '-' ? -1 : 0)); switch(type) { case _ARROW_: if_not(wild) c->exit_ar = 0; for ( ; *p; p++) { switch(tolower(*p)) { case 'u': i = MASK(_UP_); break; case 'd': i = MASK(_DOWN_); break; case 'l': case 'b': i = MASK(_LEFT_); break; case 'r': case 'f': i = MASK(_RIGHT_); break; default : i = MASK(_HOME_); break; case '*': i = 0xff; break;; case '+': wild = 1; continue; case '-': wild = -1; continue; } if (wild<0) c->exit_ar &= ~i; else c->exit_ar |= i; } break; case _KEYPAD_: case _PF_: case _FK_: i = MASK(type); if (*p == '*') wild = 1; if (wild) c->exit_pf &= ~i; if (wild > 0) c->exit_pf |= i; break; default: /* Control Characters */ if_not(wild) c->exit_cc = MASK('\r'); for ( ; *p; p++) { switch(*p) { case '+': wild = 1; continue; case '-': wild = -1; continue; case '*': i = (unsigned int)0xffffffff; break; default: i = MASK(Control_(*p)); break; } if (wild<0) c->exit_cc &= ~i; else c->exit_cc |= i; } break; } EXIT(OK); } /*========================================================================== * tv_get1 *==========================================================================*/ int tv_get1(str, nbytes, stop1) /*+++ .PURPOSE Get a command string from terminal, made of up to (nbytes-1) characters, but stop if one of the characters in stop1 was hit as the {\em first} input. .RETURNS _EOF_ / 0 / _STANDARD_ / _ARROW_ / _KEYPAD_ / _FK_ / _PF_ (see tv_mods) ---*/ char *str; /* MOD: The buffer to get the input */ int nbytes; /* IN: Length of the input buffer */ char *stop1; /* IN: List of characters to stop */ { int status; ENTER("tv_get1"); stop_list = stop1; stop_len = strlen(stop1); status = tv_mods(str, nbytes, 0); stop_len = 0; EXIT(status); } /*========================================================================== * tv_getp *==========================================================================*/ int tv_getp(str, nbytes) /*+++ .PURPOSE Get a password (no echo) .RETURNS _EOF_ / 0 / _STANDARD_ / _ARROW_ / _KEYPAD_ / _FK_ / _PF_ (see tv_mods) ---*/ char *str; /* MOD: The buffer to get the input */ int nbytes; /* IN: Length of the input buffer */ { int status; ENTER("tv_getp"); f0 = 0; status = tv_mods(str, nbytes, 0); f0 = Echo | Stacking; EXIT(status); } /*========================================================================== * tv_mods *==========================================================================*/ int tv_mods(str, nbytes, linput) /*+++ .PURPOSE Display a template command, and get a command string from terminal, made of up to (nbytes-1) characters, and echo. The input stops when the one of the characters specified by tv_stopin is hit (the Carriage Return only by default). \begin{TeX} {\em Note that} keypad characters are considered as normal chars, unless {\tt tv\_stopin(w, \_KEYPAD\_,"*")} was called. \end{TeX} .RETURNS OK or _STANDARD_, EOF, NOK, _KEYPAD_, _PF_, _FK_ with the following meanings: \begin{TeX} \begin{itemize} \item OK or \_STANDARD\_: a $<$Carriage\_Return$>$ or $<$Enter$>$ terminates the input; this last character is not reported to the string, but {\em is replaced by the EOS character.} \item NOK: either \begin{itemize} \item the size of the input string is 1 character or less (nbytes $<2$) \item a control / arrow / keypad / PK / Function character was typed at the terminal, which is {\em not the first} input char; the returned string contains the previous characters (\ie before the stopping char), and a next call to the function will return the control character. \end{itemize} \item EOF: the EOF (Control\_Z or Control\_D, depending on initialization) char was typed as the {\em first} input character; the output string contains only a zero (EOS). {\em Note that the EOF character not typed as the first char returns NOK.} \item \_KEYPAD\_: a keypad key is the {\em first} input character and the Keypad is enabled via a previous call to {\tt tv\_stopin(w, \_KEYPAD\_, "*")}; the output string contains the equivalence keypad. If the Keypad is enabled via {\em tv\_stopin}, and a Keypad was hit after normal ASCII characters, the function returns NOK. Note that keypad keys are translated if the keypad is not enabled. \item \_PF\_: a PF key is the {\em first} input character if PF keys were previously enabled via {\tt tv\_stopin(w, \_PF\_, "*")}. \item \_FK\_: a Function is the {\em first} input character if Function keys were previously enabled via {\tt tv\_stopin(w, \_FK\_, "*")}. \end{itemize} \end{TeX} .REMARKS ---*/ char *str; /* MOD: The buffer to get the input */ int nbytes; /* IN: Length of the input buffer */ int linput; /* IN: Length of template string */ { register char *p; /* Current position in str */ char *pw, *p_end; /* pw is last valid char in str */ int type; static char ch; int i, l; ENTER("tv_mods"); f = f0, f0 = Echo | Stacking; if (nbytes < 2) EXIT(NOK); /* Buffer too small */ TERMTEST; /* Open Terminal if not yet done */ p_start = str; p = p_start, pw = p; command_len = nbytes - 1; p_end = p + command_len; init_pos = GetPosition(); /* Keep first initial data */ J = terms->dim[1]; /* Column width */ if (linput) TRACE_STR2(str, linput); /* Echo template string, and position cursor to End of Template */ if (linput > 0) { i = MIN(linput, p_end - p_start); WriteBinary(p_start, i); p += i, pw = p; } /* Initialize the Stack of Commands */ c->pointed = c->used; c->pointed_no = c->last_no + 1; command_number = c->pointed_no; /* ============ Loop on the input char ======== */ while ( ! (f&Stop) ) { if (f & NoMore) /* Too long string... */ { Bell(); f &= ~NoMore; } type = GetChar(&ch); #if DEBUG TRACE_ED_STR2("Total string is: ",str, pw-str); TRACE_ED_STR2("Present string is: ",str, p-str); TRACE_ED_STR2("Just read : ",&ch, 1); TRACE_ED_I (" ... of type: ",type); #endif if ( type == NOK) /* Bad Escape Sequence... */ { Bell(); continue; } if (f & Raw) type = _STANDARD_; switch(type) { case EOF: f |= (Stop|Special); continue; case _PF_: case _FK_: if (c->exit_pf & MASK(type)) f |= (Stop|Special); else Bell(); continue; case _ARROW_: if (c->exit_ar & MASK(ch)) { f |= (Stop|Special); continue; } switch(ch) /* Execute the Cursor Movements */ { case _LEFT_: case _RIGHT_: p += mv1(ch, pw - p); /* Maximal Displacement is pw-p */ continue; default: SetPosition(init_pos), p = p_start; continue; case _UP_: case _DOWN_: /* Copy retrieved command, and edit it */ if_not(f&Echo) continue; if (c->pointed_no == command_number) /* Save what has been typed */ zadd(str, pw-str, 0); zm(ch); /* Move in Stack */ i = c->pointed; l = *(c->text + i); l = show(p_start, (char *)(c->text + i + 1), l); p = str + l, pw = p; } continue; case _KEYPAD_: if (c->exit_pf & MASK(_KEYPAD_)) { f |= (Stop|Special); continue; } type = _STANDARD_; /* Keypad chars are considered as normal */ break; } /* --- Here Only if it's an ASCII character ---- */ if ((isprint(ch)) || (f&Raw)) { f &= ~Raw; if (f & Imode) { if ( (pw) >= p_end) f |= NoMore; else oscopy ( p+1, p, pw++ - p); } else /* Replace Mode */ { if (pw <= p) pw = p+1; if (pw > p_end) pw--, f |= NoMore; } if (f & NoMore) /* Too long string... */ continue; *p = ch; o1(p, pw-p); /* Echo the character...*/ p++; if (stop_len) /* Check first byte */ { if (oscloc(stop_list, stop_len, ch) < stop_len) ch = '\r'; else ch = EOS; stop_len = 0; if(ch == EOS) continue; } else continue; } /*==============================================*/ /* --- Here only if it's a Control Char */ /*==============================================*/ if (ch == '\r') /* Normal End */ { f |= Stop; continue; } i = *(unsigned char *)(&ch); if (i > 32) /* Delete char */ i = 32; if (c->exit_cc & MASK(i)) /* Exit on Control */ { f |= (Stop|Special); continue; } switch(terms->tc[i]) { default: Bell(); /* Just ignore... */ continue; case TW_cc_RAW: f |= Raw; continue; case TW_cc_REFR: /* Refresh Screen */ SetPosition(init_pos); ClearDown(); WriteBinary(p_start, pw-p_start); SetPosition(init_pos + (p-p_start)); continue; case TW_cc_HELP: /* Go first to end of text, show help, * and reissue text */ SetPosition(init_pos + (pw - p_start)); ShowHelp(); WriteBinary(p_start, pw-p_start); init_pos = GetPosition() - (pw - p_start); SetPosition(init_pos + (p - p_start)); continue; case TW_cc_MODE: f ^= Imode; /* Change mode */ continue; /* Imode flag done at loop top */ case TW_cc_NW: /* Move to next word */ p += oscscan(p, pw-p, _SPACE_, main_ascii); p += oscspan(p, pw-p, _SPACE_, main_ascii); SetPosition(init_pos + (p-p_start)); continue; case TW_cc_EOL: /* Move cursor to end */ SetPosition(init_pos + (pw - p_start)); p = pw; continue; case TW_cc_DELC: /* Delete Char */ if (p == p_start) continue; p--, pw--; oscopy(p, p+1, pw-p); dc(p, 1, pw-p); continue; case TW_cc_DELL: /* Clear Line */ p = p_start, pw = p; SetPosition(init_pos); ClearDown(); continue; case TW_cc_DELE: /* Delete to the right */ pw = p; ClearDown(); continue; case TW_cc_DELW: /* Delete Previous Word */ if (p == p_start) continue; i = oscbspan(p_start, p-p_start, _SPACE_, main_ascii); i = oscbscan(p_start, i+1, _SPACE_, main_ascii); i = (p-p_start) - (i+1); /* Number of chars to delete */ oscopy(p-i, p, pw-p); p -= i, pw -= i; dc(p, i, pw-p); continue; } } p = pw, l = p - p_start; /* Final Length of String */ SetPosition(init_pos + l); /* Where the cursor must be */ /* Add the string to command stack */ if ( (type <= _STANDARD_) && (l > 0) && (f&Stacking)) zadd(str, l, 2); if (f & Special) { if (pw == str) /* Was First Input Character */ *(p++) = ch; else tv_push(type, ch), type = NOK; } *p = EOS; TRACE(p_start); EXIT(type); } /*========================================================================== * tv_kmods *==========================================================================*/ int tv_kmods(flag,str, nbytes, linput) /*+++ .PURPOSE Display a template command, and get a command string from terminal, made of up to (nbytes-1) characters, and echo. The input stops when the one of the characters specified by tv_stopin is hit (the Carriage Return only by default). \begin{TeX} {\em Note that} keypad characters are considered as normal chars, unless {\tt tv\_stopin(w, \_KEYPAD\_,"*")} was called. \end{TeX} .RETURNS OK or _STANDARD_, EOF, NOK, _KEYPAD_, _PF_, _FK_ with the following meanings: \begin{TeX} \begin{itemize} \item OK or \_STANDARD\_: a $<$Carriage\_Return$>$ or $<$Enter$>$ terminates the input; this last character is not reported to the string, but {\em is replaced by the EOS character.} \item NOK: either \begin{itemize} \item the size of the input string is 1 character or less (nbytes $<2$) \item a control / arrow / keypad / PK / Function character was typed at the terminal, which is {\em not the first} input char; the returned string contains the previous characters (\ie before the stopping char), and a next call to the function will return the control character. \end{itemize} \item EOF: the EOF (Control\_Z or Control\_D, depending on initialization) char was typed as the {\em first} input character; the output string contains only a zero (EOS). {\em Note that the EOF character not typed as the first char returns NOK.} \item \_KEYPAD\_: a keypad key is the {\em first} input character and the Keypad is enabled via a previous call to {\tt tv\_stopin(w, \_KEYPAD\_, "*")}; the output string contains the equivalence keypad. If the Keypad is enabled via {\em tv\_stopin}, and a Keypad was hit after normal ASCII characters, the function returns NOK. Note that keypad keys are translated if the keypad is not enabled. \item \_PF\_: a PF key is the {\em first} input character if PF keys were previously enabled via {\tt tv\_stopin(w, \_PF\_, "*")}. \item \_FK\_: a Function is the {\em first} input character if Function keys were previously enabled via {\tt tv\_stopin(w, \_FK\_, "*")}. \end{itemize} \end{TeX} .REMARKS ---*/ int flag; /* IN: 1 or 0 for Insert or Change mode */ char *str; /* MOD: The buffer to get the input */ int nbytes; /* IN: Length of the input buffer */ int linput; /* IN: Length of template string */ { register char *p; /* Current position in str */ char *pw, *p_end; /* pw is last valid char in str */ int type; static char ch; int i, l; ENTER("tv_mods"); f = f0, f0 = Echo | Stacking; if (nbytes < 2) EXIT(NOK); /* Buffer too small */ TERMTEST; /* Open Terminal if not yet done */ p_start = str; p = p_start, pw = p; command_len = nbytes - 1; p_end = p + command_len; init_pos = GetPosition(); /* Keep first initial data */ J = terms->dim[1]; /* Column width */ if (linput) TRACE_STR2(str, linput); /* Echo template string, and position cursor to End of Template */ if (linput > 0) { i = MIN(linput, p_end - p_start); WriteBinary(p_start, i); p += i, pw = p; } /* Initialize the Stack of Commands */ c->pointed = c->used; c->pointed_no = c->last_no + 1; command_number = c->pointed_no; if (flag == 1) f ^= Imode; /* Change mode */ /* ============ Loop on the input char ======== */ while ( ! (f&Stop) ) { if (f & NoMore) /* Too long string... */ { Bell(); f &= ~NoMore; } type = GetChar(&ch); #if DEBUG TRACE_ED_STR2("Total string is: ",str, pw-str); TRACE_ED_STR2("Present string is: ",str, p-str); TRACE_ED_STR2("Just read : ",&ch, 1); TRACE_ED_I (" ... of type: ",type); #endif if ( type == NOK) /* Bad Escape Sequence... */ { Bell(); continue; } if (f & Raw) type = _STANDARD_; switch(type) { case EOF: f |= (Stop|Special); continue; case _PF_: case _FK_: if (c->exit_pf & MASK(type)) f |= (Stop|Special); else Bell(); continue; case _ARROW_: if (c->exit_ar & MASK(ch)) { f |= (Stop|Special); continue; } switch(ch) /* Execute the Cursor Movements */ { case _LEFT_: case _RIGHT_: p += mv1(ch, pw - p); /* Maximal Displacement is pw-p */ continue; default: SetPosition(init_pos), p = p_start; continue; case _UP_: case _DOWN_: /* Copy retrieved command, and edit it */ if_not(f&Echo) continue; if (c->pointed_no == command_number) /* Save what has been typed */ zadd(str, pw-str, 0); zm(ch); /* Move in Stack */ i = c->pointed; l = *(c->text + i); l = show(p_start, (char *)(c->text + i + 1), l); p = str + l, pw = p; } continue; case _KEYPAD_: if (c->exit_pf & MASK(_KEYPAD_)) { f |= (Stop|Special); continue; } type = _STANDARD_; /* Keypad chars are considered as normal */ break; } /* --- Here Only if it's an ASCII character ---- */ if ((isprint(ch)) || (f&Raw)) { f &= ~Raw; if (f & Imode) { if ( (pw) >= p_end) f |= NoMore; else oscopy ( p+1, p, pw++ - p); } else /* Replace Mode */ { if (pw <= p) pw = p+1; if (pw > p_end) pw--, f |= NoMore; } if (f & NoMore) /* Too long string... */ continue; *p = ch; o1(p, pw-p); /* Echo the character...*/ p++; if (stop_len) /* Check first byte */ { if (oscloc(stop_list, stop_len, ch) < stop_len) ch = '\r'; else ch = EOS; stop_len = 0; if(ch == EOS) continue; } else continue; } /*==============================================*/ /* --- Here only if it's a Control Char */ /*==============================================*/ if (ch == '\r') /* Normal End */ { f |= Stop; continue; } i = *(unsigned char *)(&ch); if (i > 32) /* Delete char */ i = 32; if (c->exit_cc & MASK(i)) /* Exit on Control */ { f |= (Stop|Special); continue; } switch(terms->tc[i]) { default: Bell(); /* Just ignore... */ continue; case TW_cc_RAW: f |= Raw; continue; case TW_cc_REFR: /* Refresh Screen */ SetPosition(init_pos); ClearDown(); WriteBinary(p_start, pw-p_start); SetPosition(init_pos + (p-p_start)); continue; case TW_cc_HELP: /* Go first to end of text, show help, * and reissue text */ SetPosition(init_pos + (pw - p_start)); ShowHelp(); WriteBinary(p_start, pw-p_start); init_pos = GetPosition() - (pw - p_start); SetPosition(init_pos + (p - p_start)); continue; case TW_cc_MODE: f ^= Imode; /* Change mode */ continue; /* Imode flag done at loop top */ case TW_cc_NW: /* Move to next word */ p += oscscan(p, pw-p, _SPACE_, main_ascii); p += oscspan(p, pw-p, _SPACE_, main_ascii); SetPosition(init_pos + (p-p_start)); continue; case TW_cc_EOL: /* Move cursor to end */ SetPosition(init_pos + (pw - p_start)); p = pw; continue; case TW_cc_DELC: /* Delete Char */ if (p == p_start) continue; p--, pw--; oscopy(p, p+1, pw-p); dc(p, 1, pw-p); continue; case TW_cc_DELL: /* Clear Line */ p = p_start, pw = p; SetPosition(init_pos); ClearDown(); continue; case TW_cc_DELE: /* Delete to the right */ pw = p; ClearDown(); continue; case TW_cc_DELW: /* Delete Previous Word */ if (p == p_start) continue; i = oscbspan(p_start, p-p_start, _SPACE_, main_ascii); i = oscbscan(p_start, i+1, _SPACE_, main_ascii); i = (p-p_start) - (i+1); /* Number of chars to delete */ oscopy(p-i, p, pw-p); p -= i, pw -= i; dc(p, i, pw-p); continue; } } p = pw, l = p - p_start; /* Final Length of String */ SetPosition(init_pos + l); /* Where the cursor must be */ /* Add the string to command stack */ if ( (type <= _STANDARD_) && (l > 0) && (f&Stacking)) zadd(str, l, 2); if (f & Special) { if (pw == str) /* Was First Input Character */ *(p++) = ch; else tv_push(type, ch), type = NOK; } *p = EOS; TRACE(p_start); EXIT(type); }