zzledt.c

Go to the documentation of this file.
00001 /* Copyright INRIA/ENPC */
00002 /***********************************************************************
00003  * zzledt.c - line editing routine
00004  * Initial Version : Copyright (c) Mitchell and Gauthier assoc, inc 1993
00005  * Modified by Jean Philippe Chancelier (ENPC) and Serge Steer (INRIA) 
00006  *  - Console (xterm) and Scilab window mode handled, 
00007  *    used in Console mode for GTK
00008  *  - Interruption for Scilab menu execution
00009  *  - History functions changed to use linked lists
00010  **********************************************************************/
00011 #include "machine.h" 
00012 #include "sciprint.h"
00013 
00014 static char Sci_Prompt[10];
00015 
00016 
00017 #ifndef WITHOUT_STD_ZZLEDT 
00018 #ifndef _MSC_VER 
00019 #include <string.h>
00020 #include <signal.h> /* for SIGINT */
00021 
00022 #ifdef __STDC__
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 #endif
00026 #include <sys/ioctl.h>
00027 
00028 #ifdef aix
00029 #define ATTUNIX
00030 #endif
00031 #ifdef aix370
00032 #define ATTUNIX
00033 #endif
00034 #ifdef cdcu
00035 #define ATTUNIX
00036 #endif
00037 #ifdef cray
00038 #define B42UNIX
00039 #endif
00040 #ifdef hpux
00041 #define ATTUNIX
00042 #endif
00043 #ifdef sgi
00044 #define ATTUNIX
00045 #endif
00046 #ifdef sun
00047 #define ATTUNIX
00048 #define TERMCAP
00049 #endif
00050 #ifdef ultrix
00051 #define B42UNIX
00052 #define TERMCAP
00053 #endif
00054 #if !defined(linux) && !defined(netbsd) && !defined(freebsd)
00055 #ifdef  __alpha
00056 #define B42UNIX
00057 #endif
00058 #endif
00059 #ifdef linux
00060 #define ATTUNIX
00061 #define TERMCAP
00062 #endif
00063 #if defined(netbsd) || defined(freebsd)
00064 #define TERMCAP
00065 #endif
00066 
00067 #include <stdio.h>
00068 #include <ctype.h>
00069 #include "machine.h"
00070 #include "core_math.h"
00071 #include "Scierror.h"
00072 #include "prompt.h"
00073 
00074 #ifndef HAVE_TERMCAP
00075 #undef TERMCAP
00076 #endif
00077 
00078 #ifdef B42UNIX
00079 #define KEYPAD 
00080 #include <sys/file.h>
00081 #include <sgtty.h>
00082 static short save_sg_flags;
00083 static struct sgttyb arg;
00084 static struct tchars arg1;
00085 #endif
00086 
00087 #ifdef ATTUNIX
00088 #define KEYPAD 
00089 #include <termio.h>
00090 static struct termio save_term;
00091 static struct termio arg;
00092 #endif
00093 
00094 #define EXCL                  0x0021
00095 #define UP_ARROW              0x0148
00096 #define DOWN_ARROW            0x0150
00097 #define LEFT_ARROW            0x014b
00098 #define RIGHT_ARROW           0x014d
00099 #define SEARCH_BACKWARD       0x015e
00100 #define SEARCH_FORWARD        0x0160
00101 #define HOME                  0x0001  /* control-A */
00102 #define ENDS                  0x0005  /* control-E */
00103 #define LDEL                  0x0015  /* control-U */
00104 #define INS                   0x0014  /* control-T */
00105 #define DEL                   0x007f
00106 #define BS                    0x0008  /* control-H */
00107 #define CR                    0x000d
00108 #define LF                    0x000a
00109 #define BEL                   0x0007
00110 #define CTRL_B                0x0002  /* back a character */
00111 #define CTRL_C                0x0003  /* redo line */
00112 #define CTRL_D                0x0004  /* delete next char */
00113 #define CTRL_F                0x0006  /* forward a character */
00114 #define CTRL_K                0x000b  /* delete to end of line */
00115 #define CTRL_L                0x000c  /* delete to end of line */
00116 #define CTRL_N                0x000e  /* next line */
00117 #define CTRL_P                0x0010  /* previous line */
00118 #define CTRL_Y                0x0019  /* paste */
00119 #define CTRL_Z                0x0020  /* stop */
00120 #define CASE_PRINT            63      /* from x_VTparse.h */
00121 
00122 
00123 #define NUL '\0'
00124 #define TRUE 1
00125 #define FALSE 0
00126 #define TAB_SKIP 8
00127 #define NO_SAVED_LINES 100
00128 #define WK_BUF_SIZE 520
00129 #define SV_BUF_SIZE 5000
00130 
00131 
00132 #define N_SEQS       6      /* number of special sequences */
00133 #define MAX_SEQ_LEN  10     /* max chars in special termcap seqs */
00134 #define ESC          0x01b
00135 /* declare and define initial sequences. They
00136  * may be overwritten by termcap entries */
00137 static char seqs[N_SEQS][MAX_SEQ_LEN] = {
00138   { 0x1b, 0x5b, 0x41, 0x00 },   /* up arrow */
00139   { 0x1b, 0x5b, 0x42, 0x00 },   /* down arrow */
00140   { 0x1b, 0x5b, 0x44, 0x00 },   /* left arrow */
00141   { 0x1b, 0x5b, 0x43, 0x00 },    /* right arrow */
00142   { 0x1b, 0x3c, 0x00, 0x00 },   /* search backward*/
00143   { 0x1b, 0x3e, 0x00, 0x00 }    /* search forward */
00144 };
00145 static int key_map[] = {UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, SEARCH_BACKWARD, SEARCH_FORWARD};
00146 
00147 
00148 static char yank_buf[WK_BUF_SIZE + 1];/* yank buffer for copy/paste */
00149 static char tosearch[SV_BUF_SIZE] = "";/* place to store search string */
00150 static int insert_flag = 1; /*insertion mode */
00151 static int modeX; /* Window or Console mode */
00152 /* --- locally defined functions ---  */
00153 static void move_right(char *source, int max_chars);
00154 static void move_left(char *source);
00155 static void display_string(char *string);
00156 static void backspace(int n);
00157 static void erase_nchar(int n);
00158 static int  gchar_no_echo(int interrupt);
00159 static int  CopyCurrentHist(char *wk_buf,int *cursor,int *cursor_max);
00160 static void strip_blank(char *source);
00161 static int  translate(int ichar);
00162 static void PutChar(int c);
00163 static int  GetCharOrEvent(int interrupt);
00164 
00165 /* function for console mode */
00166 static void enable_keypad_mode(void);
00167 static void disable_keypad_mode(void);
00168 static void init_io(void);
00169 static void set_crmod(void);
00170 static void set_cbreak(void);
00171 
00172 int using_readline(void);
00173 int XSaveNative _PARAMS((char *fname, unsigned long fname_len));
00174 int HomeFunction _PARAMS((char *fname, unsigned long fname_len));
00175 int ClearScreenConsole _PARAMS((char *fname, unsigned long fname_len));
00176 int ShowWindowFunction _PARAMS((char *fname, unsigned long fname_len));
00177 
00178 /* --- extern functions ---  */
00179 extern void set_echo_mode(int mode);
00180 extern void set_is_reading(int mode);
00181 extern int  get_echo_mode(void);
00182 extern void C2F(sigbas)(int *n);
00183 extern void XHomeFunction(void);
00184 extern int XClearScreenConsole(char *fname);
00185 
00186 /*history functions*/
00187 #include "history.h" 
00188 
00189 /*end history functions*/
00190 
00191 
00192 extern int  XEvorgetchar(int interrupt);  
00193 extern void Xputchar(int c);  
00194 
00195 extern int  Xorgetchar(int interrupt);
00196 /* --- End extern functions ---  */
00197 
00198 /*  ---- interruption handling ---*/
00199 static char wk_buf_save[WK_BUF_SIZE + 1];
00200 static int cursor_save=0;
00201 static int cursor_max_save=0;
00202 static int interrupted=0;
00203 /*  ---- end of interruption handling ---*/
00204 
00205 static int sendprompt=1;
00206 
00207 extern int groundtable[]; /* character table */ 
00208 
00209 /*-------------- Declarations  specific for console mode    -----------------  */
00210 static int init_flag = TRUE;
00211 static int tty;
00212 
00213 
00214 static int cbreak_crmod = 1;/* crmod on */
00215 static int fd=0;            /* file number for standard in */
00216 
00217 #ifdef TERMCAP
00218 /* termcap capability string for arrow up,down, left, and right */
00219 static char *tc_capabilities[] = { "ku", "kd", "kl", "kr", "" };
00220 static char strings[128];   /* place to store output strings from termcap file */
00221 static char *KS=NULL;            /* enable keypad */
00222 static char *KE=NULL;            /* disable keypad */
00223 static char *CE=NULL;            /* clear to end of line */
00224 static char *BC=NULL;            /* backspace */
00225 static char *IM=NULL;            /* start insert mode */
00226 static char *IC=NULL;            /* insert character */
00227 static char *EI=NULL;            /* end insert mode */
00228 static char *CL=NULL;            /* clear screen */
00229 #endif
00230 
00231 extern int GetSaveHistoryAfterNcommands(void);
00232 extern char * getfilenamehistory(void);
00233 
00234 extern void C2F(zzledt)(char *buffer,int *buf_size,int *len_line,int * eof,     int *menusflag,int * modex,long int dummy1);
00235 
00236 int NumberOfCommands=0;
00237 
00238 /*-------------- End of Declarations  specific for console mode-----------------  */
00239 
00240 /***********************************************************************
00241  * line editor
00242  **********************************************************************/
00243 
00244 extern void C2F(zzledt)(char *buffer,int *buf_size,int *len_line,int * eof,
00245                         int *menusflag,int * modex,long int dummy1)
00246 {
00247   int cursor_max = 0;
00248   int cursor = 0;
00249   int yank_len,i;
00250 
00251   int keystroke;
00252   int character_count;
00253   char wk_buf[WK_BUF_SIZE + 1];
00254 
00255   GetCurrentPrompt(Sci_Prompt);
00256 
00257   modeX=*modex;
00258 
00259   if(!modeX) {
00260     if(init_flag) {
00261       init_io();
00262       init_flag = FALSE;
00263     }
00264     
00265     if(!tty) { /* if not an interactive terminal */
00266       /* read a line into the buffer, but not too
00267        * big */
00268       fputs("-->",stdout);
00269       *eof = (fgets(buffer, *buf_size, stdin) == NULL);
00270       *len_line = strlen(buffer);
00271       /* remove newline character if there */
00272       if(buffer[*len_line - 1] == '\n')
00273         (*len_line)--;
00274       return;
00275     }
00276   }
00277 
00278   if (interrupted) {
00279     /* restore the state */
00280     interrupted=0;
00281     strcpy(wk_buf,wk_buf_save);
00282     cursor=cursor_save;cursor_save=0;
00283     cursor_max=cursor_max_save;cursor_max_save=0;
00284   }
00285   else
00286     wk_buf[0] = NUL; /* initialize empty  buffer */
00287 
00288   if(!modeX) {
00289 #ifdef KEYPAD 
00290     set_cbreak();
00291     enable_keypad_mode();
00292 #endif
00293     if(sendprompt) printf(Sci_Prompt);/* write prompt */
00294   }
00295   else {
00296     if(sendprompt) sciprint_nd(Sci_Prompt);/* write prompt */
00297   }
00298   
00299   sendprompt=1;
00300   set_is_reading(TRUE); /* did not exist in old gtk version */
00301         
00302                     
00303   while(1) {  /* main loop to read keyboard input */
00304     /* get next keystroke (no echo) returns -1 if interrupted */
00305     keystroke = gchar_no_echo(*menusflag);
00306 
00307     if (keystroke==-1) {
00308       /* preserve the state */
00309       interrupted=1;
00310       strcpy(wk_buf_save,wk_buf);
00311       cursor_save=cursor;
00312       cursor_max_save=cursor_max;
00313       sendprompt=0;
00314       *eof=-1;
00315       return;
00316     }
00317 
00318     if ( keystroke ==  CTRL_C ) /* did not exist in old gtk version */
00319       {
00320         int j = SIGINT;
00321         C2F(sigbas)(&j);
00322         keystroke = '\n';
00323       };
00324 
00325     /* check for ascii extended characters */
00326     if( ( iscntrl(keystroke) && groundtable[keystroke] != CASE_PRINT)
00327         || keystroke > 0x0100 )
00328       {
00329         /* stroke is line editing command */
00330         switch(keystroke) {
00331         case UP_ARROW: /* move one line up if any in history */
00332         case CTRL_P:
00333           if (history != NULL) {
00334             if (cur_entry == NULL) {
00335               cur_entry = history;
00336               CopyCurrentHist(wk_buf,&cursor, &cursor_max); 
00337             }
00338             else if (cur_entry->prev != NULL) {
00339               cur_entry = cur_entry->prev;
00340               CopyCurrentHist(wk_buf,&cursor, &cursor_max); 
00341             }
00342           }
00343           break;
00344         case DOWN_ARROW:  /* move one line down if any in history */
00345         case CTRL_N:
00346           if (cur_entry != NULL) {
00347             cur_entry = cur_entry->next;
00348 
00349             /* To get a empty line when no more data in history */
00350             backspace(cursor);
00351             erase_nchar(cursor_max);
00352             wk_buf[0] = NUL;
00353             cursor = cursor_max = 0;
00354 
00355             if (cur_entry != NULL) {
00356               CopyCurrentHist(wk_buf,&cursor, &cursor_max); 
00357             }
00358           }
00359           break;
00360         case LEFT_ARROW:/* move left*/
00361         case CTRL_B:
00362           if(cursor > 0) {/* is there room to move left */
00363             cursor--;
00364             backspace(1);
00365           }
00366           else {
00367             PutChar(BEL); /* au lieu de XPutChar(BEL);*/
00368           }
00369           break;
00370         case RIGHT_ARROW: /* move right*/
00371         case CTRL_F:
00372           if(cursor < cursor_max) {/* is there room to move right */
00373             PutChar(wk_buf[cursor++]);
00374           }
00375           else {
00376             PutChar(BEL);
00377           }
00378           break;
00379 
00380         case HOME:
00381           backspace(cursor); /* move to beginning of the line */
00382           cursor = 0;
00383           break;
00384 
00385         case ENDS:  /* move to end of line */
00386           while(cursor < cursor_max) {
00387             PutChar(wk_buf[cursor++]);
00388           }
00389           break;
00390 
00391         case INS: /* toggle insert/overwrite flag */
00392           insert_flag = !insert_flag;
00393           break;
00394                     
00395         case CTRL_C: 
00396           {
00397             int j = SIGINT;
00398             C2F(sigbas)(&j);
00399           };
00400           break;
00401            
00402         case CTRL_D: /* delete next character*/
00403           if(cursor == cursor_max) {
00404             /* reminder that backing up over edge */
00405             PutChar(BEL);
00406             break;
00407           }
00408           move_left(&wk_buf[cursor]);
00409           cursor_max--;
00410           /* and write rest of line to end */
00411           display_string(&wk_buf[cursor]);
00412           /* erase extra character now at end. */
00413           erase_nchar(1);
00414           /* backspace to proper cursor position */
00415           backspace(cursor_max - cursor);
00416           break;
00417 
00418         case DEL: /* backspace with delete */
00419         case BS:
00420           if(cursor == 0) {
00421             /* reminder that backing up over edge */
00422             PutChar(BEL);
00423             break;
00424           }
00425           /* move string in work, one left from cursor */
00426           move_left(&wk_buf[cursor - 1]);
00427           cursor_max--;
00428           cursor--;
00429           backspace(1);
00430           /* and write rest of line to end */
00431           display_string(&wk_buf[cursor]);
00432           /* erase extra character now at end. */
00433           erase_nchar(1);
00434           /* backspace to proper cursor position */
00435           backspace(cursor_max - cursor);
00436           break;
00437 
00438         case CTRL_K: /* delete to end of line */ 
00439           if(cursor == cursor_max) {
00440             /* reminder that backing up over edge */
00441             PutChar(BEL);
00442             break;
00443           }
00444           /* erase  character  at end. */
00445           erase_nchar(cursor_max - cursor);
00446           /* store cutted part in tyank buffer*/
00447           strcpy(yank_buf,&wk_buf[cursor]);
00448           /* backspace to proper cursor position */
00449           wk_buf[cursor] = NUL;
00450           cursor_max = cursor;
00451           break;
00452 
00453         case CTRL_Y: /* Paste at the current point */
00454           yank_len=strlen(yank_buf);
00455           if(yank_len!=0 ){
00456             if (cursor==cursor_max) {
00457               strcpy(&wk_buf[cursor],yank_buf);
00458               display_string(&wk_buf[cursor]);
00459               cursor = cursor_max + yank_len;
00460               cursor_max = cursor;
00461 
00462             }
00463             else {
00464               for(i = 0; i <= cursor_max-cursor; i++)
00465                 wk_buf[cursor_max+yank_len-i]=wk_buf[cursor_max-i];
00466               wk_buf[cursor_max+yank_len]=NUL;
00467               strncpy(&wk_buf[cursor],yank_buf,yank_len);
00468               erase_nchar(cursor_max - cursor);
00469               display_string(&wk_buf[cursor]);
00470               backspace(cursor_max-cursor);
00471               cursor_max=cursor_max+yank_len;
00472               cursor=cursor+yank_len;
00473             }
00474 
00475           }
00476           break;
00477         case CTRL_Z:
00478           break;
00479 
00480         case CTRL_L:
00481           if(modeX) {
00482             PutChar(CTRL_L);
00483             wk_buf[0]=NUL;
00484             goto exit;
00485           }
00486           else {
00487 #ifdef TERMCAP
00488             fputs(CL,stdout);
00489             wk_buf[0]=NUL;
00490             goto exit;
00491 #else
00492             PutChar(BEL);
00493             break;
00494 #endif
00495           }
00496 
00497         case LDEL: /* clear line buffer */
00498           backspace(cursor);
00499           erase_nchar(cursor_max);
00500           wk_buf[0] = NUL;
00501           cursor = cursor_max = 0;
00502           break;
00503 
00504         case CR: /* carrage return indicates line is ok;*/
00505         case LF:
00506           strip_blank(wk_buf);/* first strip any trailing blanks */
00507           if (wk_buf[0]==EXCL) { /* search backward */
00508             strcpy(tosearch,wk_buf); /* memorise search key for further use */
00509             cur_entry=SearchBackwardInHistory(tosearch+1);
00510             if(cur_entry == NULL) {
00511               PutChar(BEL);
00512             }
00513             else {
00514               research_knot_last=cur_entry;
00515               CopyCurrentHist(wk_buf,&cursor, &cursor_max); 
00516               AddHistory(wk_buf);
00517               cur_entry=NULL;
00518 
00519             }
00520             break;
00521           }
00522 
00523           if(get_echo_mode()==1)   {
00524             AddHistory(wk_buf);
00525             cur_entry=NULL;
00526           }
00527           goto exit;
00528 
00529         case SEARCH_BACKWARD:
00530           if(tosearch[0]!=EXCL) {
00531             PutChar(BEL);
00532           }
00533           else {
00534             if (research_knot_last != NULL) research_knot_last=research_knot_last->prev;
00535             cur_entry=SearchBackwardInHistory(tosearch+1);
00536             if(cur_entry == NULL) {
00537               PutChar(BEL);
00538             }
00539             else {
00540               research_knot_last=cur_entry;
00541               CopyCurrentHist(wk_buf,&cursor, &cursor_max); 
00542             }
00543           }
00544           break;
00545 
00546         case SEARCH_FORWARD:
00547           if(tosearch[0]!=EXCL) {
00548             PutChar(BEL);
00549           }
00550           else {
00551             if (research_knot_last != NULL) research_knot_last=research_knot_last->next;
00552             cur_entry=SearchForwardInHistory(tosearch+1);
00553             if(cur_entry == NULL) {
00554               PutChar(BEL);
00555             }
00556             else {
00557               research_knot_last=cur_entry;
00558               CopyCurrentHist(wk_buf,&cursor, &cursor_max); 
00559             }}
00560           break;
00561 
00562         default:
00563           PutChar(BEL);
00564           break;
00565 
00566         }
00567       } 
00568     else {
00569       /* alpha/numeric keystroke.
00570        * substitute blank fill for tab char */
00571       if(keystroke == '\t') {
00572         keystroke = ' ';
00573         character_count = TAB_SKIP - (cursor%TAB_SKIP);
00574         if(character_count == 0)
00575           character_count = TAB_SKIP;
00576       }
00577       else {
00578         if(keystroke == EOF) {
00579           character_count = 0;
00580         }
00581         else {
00582           character_count = 1;
00583         }
00584       }
00585       while(character_count--) {
00586         if(get_echo_mode()==0) {
00587           wk_buf[cursor] = keystroke;
00588           cursor++;
00589         }
00590         else {
00591           if(insert_flag) {
00592             /* insert mode, move rest of line right and
00593              * add character at cursor */
00594             move_right(&wk_buf[cursor], WK_BUF_SIZE - cursor);
00595             /* bump max cursor but not over buffer
00596              * size */
00597             cursor_max = (++cursor_max > WK_BUF_SIZE)
00598               ?WK_BUF_SIZE : cursor_max;
00599             /* if cursor at end of line, backspace so
00600              * that new character overwrites last one */
00601             if(cursor == WK_BUF_SIZE) {
00602               cursor--;
00603               backspace(1);
00604             }
00605             wk_buf[cursor] = keystroke;
00606             display_string(&wk_buf[cursor]);
00607             cursor++;
00608             backspace(cursor_max - cursor);
00609                
00610           } 
00611           else {
00612             /* overstrike mode */
00613             if(cursor == WK_BUF_SIZE) {
00614               cursor--;
00615               backspace(1);
00616             }
00617             wk_buf[cursor] = keystroke;
00618             PutChar(keystroke);
00619             if(cursor < WK_BUF_SIZE - 1) {
00620               cursor++;
00621               cursor_max = Max(cursor_max, cursor);
00622             }
00623             else {
00624               backspace(1);
00625             }
00626           }
00627         }
00628       }
00629     }
00630   }
00631 
00632  exit:
00633   /* copy to return buffer */
00634   if(get_echo_mode()==0)  
00635     {
00636       *len_line=cursor;
00637       strncpy(buffer,wk_buf,*buf_size);
00638       set_echo_mode(TRUE);
00639       wk_buf[0] = NUL;
00640     }
00641   else {
00642     *len_line = strlen(wk_buf);
00643     strncpy(buffer, wk_buf,*buf_size);
00644     PutChar('\r');  PutChar('\n');
00645     
00646   }
00647 #ifdef KEYPAD
00648   if(!modeX) {
00649     set_crmod();
00650     disable_keypad_mode();
00651   }
00652 #endif
00653   *eof = FALSE;
00654   set_is_reading(FALSE);
00655   
00656   /* see savehistory */
00657   NumberOfCommands++;
00658   if ( ( GetSaveHistoryAfterNcommands() == NumberOfCommands ) && ( GetSaveHistoryAfterNcommands() > 0) )
00659   {
00660           char *filenamehistory=NULL;
00661         
00662           filenamehistory=getfilenamehistory();
00663           write_history( filenamehistory );
00664           free(filenamehistory);
00665 
00666           NumberOfCommands=0;
00667   }
00668   
00669   return;
00670 
00671 }
00672 
00673 /***********************************************************************
00674  * move_right - move source string to one address larger (right)
00675  **********************************************************************/
00676 static void move_right(char *source, int max_chars)
00677 {
00678   char *p;
00679 
00680   p = source;              /* point to beginning */
00681   while(max_chars-- && *p++) /* increment until max chars or string
00682                               * end */
00683     ;
00684   *p = NUL;                /* force new string end */
00685   while(--p > source) {    /* move from rightmost edge to right */
00686     *p = *(p - 1);
00687   }
00688 }
00689 
00690 /***********************************************************************
00691  * move_left - move source string to one address less (left)
00692  **********************************************************************/
00693 
00694 static void move_left(char *source)
00695 {
00696   do {                     /* move from left edge to left */
00697     *source = *(source + 1);
00698   } while(*source++ != NUL);
00699 }
00700 
00701 /***********************************************************************
00702  * display_string - display string starting at current cursor position
00703  **********************************************************************/
00704 
00705 static void display_string(char *string)
00706 {
00707   while(*string != NUL) {
00708     PutChar(*string++);
00709   }
00710 }
00711 
00712 /***********************************************************************
00713  * backspace - move cursor n char to the left
00714  **********************************************************************/
00715 static void backspace(int n)
00716 {
00717   if(n < 1)
00718     return;
00719   if (modeX) {
00720     while(n--)
00721       PutChar('\010');
00722   }
00723   else {
00724     while(n--)
00725 #ifdef TERMCAP
00726       if(BC) {                 /* if control-H won-t work */
00727         fputs(BC, stdout);
00728       }
00729       else {                   /* otherwise just use a normal control-H */
00730         PutChar('\010');
00731       }
00732 #else
00733     PutChar('\010');
00734 #endif
00735   }
00736 }
00737 
00738 /***********************************************************************
00739  * erase n characters to right and back up cursor
00740  **********************************************************************/
00741 
00742 static void erase_nchar(int n)
00743 {
00744   int i;                   /* fill field with blanks */
00745   for(i = 0; i < n; i++) {
00746     PutChar(' ');
00747   }
00748   backspace(n);            /* and back up over blanks just written */
00749 }
00750 
00751 /***********************************************************************
00752  * strip_blank(source) - strip trailing blanks by inserting NUL-s
00753  **********************************************************************/
00754 static void strip_blank(char *source)
00755 {
00756   char *p;
00757 
00758   p = source;
00759   /* look for end of string */
00760   while(*p != NUL) {
00761     p++;
00762   }
00763   while(p != source) {
00764     p--;
00765     if(*p != ' ') break;
00766     *p = NUL;
00767   }
00768 }
00769 /***********************************************************************
00770  * get single character with no echo
00771  * if interrupt is true, gchar_no_echo escape if an event arises
00772  **********************************************************************/
00773 
00774 static int gchar_no_echo(int interrupt)
00775 {
00776   int i;
00777   /* get next character, gotten in cbreak mode so no wait for <cr> */
00778   i = GetCharOrEvent(interrupt);/* i=-1 if return on an event */
00779 
00780   /* if more than one character */
00781   if(i == ESC) {
00782     /* translate control code sequences to codes over 100 hex */
00783     i = translate(i);
00784   }
00785   return(i);
00786 }
00787 /***********************************************************************
00788  * translate escape sequences
00789  **********************************************************************/
00790 static int translate(int ichar)
00791 {
00792   int i, j, not_done;
00793   char *pstr[N_SEQS];      /* points to each sequence as it progresses */
00794 
00795   /* initialize pointer array */
00796   for(i = 0; i < N_SEQS; i++)
00797     pstr[i] = &seqs[i][0];
00798   /* examine all pstrings one char at a time */
00799   for(j=0; j++ < MAX_SEQ_LEN;) {
00800 
00801     not_done = 0;
00802     for(i = 0; i < N_SEQS; i++) {
00803       /* if matches next character, this sequence */
00804       if(ichar == *pstr[i]) {
00805         /* if next character, this sequence, null */
00806         if(!*(++pstr[i]))
00807           /* return sequence mapped to integer */
00808           return(key_map[i]);
00809         else
00810           /* flag not done with this sequence yet */
00811           not_done = 1;
00812       }
00813     }
00814     /* if any sequence not finished yet */
00815     if(not_done) {
00816       ichar = GetCharOrEvent(0);
00817     }
00818     else {
00819       /* hopefully at first character */
00820       break;
00821     }
00822   }
00823 
00824   return(ichar);
00825 }
00826 
00827 /***********************************************************************
00828  * Copy the history current line to the screen
00829  **********************************************************************/
00830 
00831 static int CopyCurrentHist(char *wk_buf,int *cursor,int *cursor_max) 
00832 {
00833   if (cur_entry != NULL) 
00834     {
00835       strcpy (wk_buf,cur_entry->line); /* copy history to buffer*/
00836       backspace(*cursor);/* backspace to beginning of line */
00837       display_string(wk_buf);/* copy to screen */
00838       *cursor = strlen(wk_buf);/* cursor set at end of line */
00839       /* erase extra characters left over if any */
00840       erase_nchar(Max(0, *cursor_max - *cursor));
00841       *cursor_max = *cursor;
00842       return 1;
00843     }
00844   return 0;
00845 }
00846 /************************************************************************
00847  * PutChar : common interface to putchar and Xputchar
00848  ***********************************************************************/
00849 
00850 void PutChar(int c)
00851 {
00852   if(modeX)
00853     Xputchar(c);
00854   else
00855     putchar(c);
00856 }
00857 
00858 /************************************************************************
00859  * GetCharOrEvent : common interface to XEvorgetchar and Xorgetchar
00860  ***********************************************************************/
00861 
00862 int GetCharOrEvent(int interrupt)
00863 {
00864   if(modeX)
00865     return XEvorgetchar(interrupt);
00866   else
00867     return Xorgetchar(interrupt);
00868 }
00869 
00870  
00871 /************************************************************************
00872  * set CBREAK mode and switch off echo and disable CR action!
00873  ***********************************************************************/
00874 static void set_cbreak()
00875 {
00876   /* switch to CBREAK mode without flushing
00877    * line buffer */
00878 #ifdef B42UNIX
00879   arg.sg_flags |= CBREAK;
00880   arg.sg_flags &= ~ECHO; 
00881   /* arg.sg_flags &= ~CRMOD; */
00882   ioctl(fd, TIOCSETN, &arg);
00883 #endif
00884 
00885 #ifdef ATTUNIX
00886   arg.c_lflag &= ~ICANON;
00887   arg.c_lflag &= ~ECHO;
00888   /* arg.c_iflag &= ~ICRNL; */
00889   arg.c_oflag &= ~OPOST;
00890   arg.c_cc [VMIN] = 1;
00891   arg.c_cc [VTIME] = 0;
00892   ioctl(fd, TCSETAW, &arg);
00893 #endif
00894   cbreak_crmod = 0;
00895   return;
00896 }
00897 
00898 /************************************************************************
00899  * reset to original mode 
00900  ***********************************************************************/
00901 
00902 static void set_crmod()
00903 {
00904   /* reset to original mode (CRMOD) */
00905 #ifdef B42UNIX
00906   arg.sg_flags = save_sg_flags;
00907   ioctl(fd, TIOCSETN, &arg);
00908   arg1.t_intrc = 3;
00909   ioctl(fd, TIOCSETC, &arg1);
00910 #endif
00911 #ifdef ATTUNIX
00912   ioctl(fd, TCSETAW, &save_term);
00913 #endif
00914   cbreak_crmod = 1;
00915   return;
00916 }
00917 
00918 /************************************************************************
00919  * initialise the io sequences
00920  ***********************************************************************/
00921 
00922 static void init_io()
00923 {
00924   int  tgetent();
00925   char *getenv();
00926   char *tgetstr();
00927   char tc_buf[1024];       /* holds termcap buffer */
00928   char *area;
00929   char erase_char;
00930   int i;
00931   /* check standard for interactive */
00932   fd=fileno(stdin);
00933   tty = isatty(fileno(stdin));
00934   if (tty == 0) return;
00935 
00936 #ifdef B42UNIX
00937   ioctl(fd,TIOCGETP,&arg);
00938   save_sg_flags = arg.sg_flags;
00939   ioctl(fd,TIOCGETC,&arg1);
00940   erase_char = arg.sg_erase;
00941 #endif
00942 
00943 #ifdef ATTUNIX
00944   ioctl(fd, TCGETA, &arg);
00945   ioctl(fd, TCGETA, &save_term);
00946   erase_char = save_term.c_cc [VERASE];
00947 #endif
00948 
00949 #ifdef TERMCAP
00950   /* get termcap translations */
00951   if(tgetent(tc_buf, getenv("TERM")) == 1) {
00952     /* loop thru zero terminated list of input
00953      * capabilities */
00954     for(i = 0; *tc_capabilities[i]; i++) {
00955       area = &seqs[i][0];
00956       tgetstr(tc_capabilities[i], &area);
00957     }
00958     area = strings;       /* point to place where strings are to
00959                            * be stored */
00960     KS = tgetstr("ks", &area);
00961     KE = tgetstr("ke", &area);
00962     CE = tgetstr("ce", &area);
00963     BC = tgetstr("bc", &area);
00964     IM = tgetstr("im", &area);
00965     IC = tgetstr("ic", &area);
00966     EI = tgetstr("ei", &area);
00967     CL = tgetstr("cl", &area);
00968   }
00969 #endif
00970   setvbuf(stdin, NULL, _IONBF, 0); /* ehrlich juin 2001 */
00971 
00972 }
00973 /************************************************************************
00974  * To make known that this zzledt code does not use readline
00975  ***********************************************************************/
00976 
00977 int using_readline() 
00978 { 
00979   return 0;
00980 }
00981 
00982 #ifdef TERMCAP
00983 /************************************************************************
00984  * enable keypad mode if using termcap
00985  ***********************************************************************/
00986 
00987 static void enable_keypad_mode()
00988 {
00989   /* enable keypad transmit mode */
00990   if(KS && *KS)
00991     fputs(KS, stdout);
00992 }
00993 
00994 /************************************************************************
00995  * disable the keypad mode if using termcap
00996  ***********************************************************************/
00997 
00998 static void disable_keypad_mode()
00999 {
01000   /* disable keypad transmit mode */
01001   if(KE && *KE)
01002     fputs(KE, stdout);
01003 }
01004 #else 
01005 /************************************************************************
01006  *wee need references to thoses function if using KEYPAD but not Having TERMCAP
01007  ***********************************************************************/
01008 
01009 static void disable_keypad_mode(){}
01010 #endif
01011 
01012 int XSaveNative _PARAMS((char *fname, unsigned long fname_len))
01013 {
01014         Scierror(999,"\nNot yet implemented. \n");      
01015         return 0;
01016 }
01017 
01018 int HomeFunction _PARAMS((char *fname, unsigned long fname_len))
01019 {
01020   XHomeFunction(); /* In SCI/modules/gui/src/c/xsci/x_util.c */
01021   return 0;
01022 }
01023 
01024 int ClearScreenConsole _PARAMS((char *fname, unsigned long fname_len))
01025 {
01026   return XClearScreenConsole(fname); /* In SCI/modules/gui/src/c/xsci/x_util.c */
01027 }
01028 
01029 int ShowWindowFunction _PARAMS((char *fname, unsigned long fname_len))
01030 {
01031   Scierror(999,"\nNot yet implemented. \n");    
01032   return 0;
01033 }
01034 
01035 
01036 #endif /* The win32 version is defined in the wsci directory **/
01037 #endif

Generated on Sun Mar 4 15:03:57 2007 for Scilab [trunk] by  doxygen 1.5.1