home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / READLINE.C < prev    next >
C/C++ Source or Header  |  1993-05-25  |  23KB  |  959 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: readline.c%v 3.38.2.81 1993/02/24 02:29:34 woo Exp woo $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - readline.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  *
  25.  *   Original Software:
  26.  *     Tom Tkacik
  27.  *
  28.  *   Msdos port and some enhancements:
  29.  *     Gershon Elber and many others.
  30.  * 
  31.  * There is a mailing list for gnuplot users. Note, however, that the
  32.  * newsgroup 
  33.  *    comp.graphics.gnuplot 
  34.  * is identical to the mailing list (they
  35.  * both carry the same set of messages). We prefer that you read the
  36.  * messages through that newsgroup, to subscribing to the mailing list.
  37.  * (If you can read that newsgroup, and are already on the mailing list,
  38.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  39.  * removed from the mailing list.)
  40.  *
  41.  * The address for mailing to list members is
  42.  *       info-gnuplot@dartmouth.edu
  43.  * and for mailing administrative requests is 
  44.  *       info-gnuplot-request@dartmouth.edu
  45.  * The mailing list for bug reports is 
  46.  *       bug-gnuplot@dartmouth.edu
  47.  * The list of those interested in beta-test versions is
  48.  *       info-gnuplot-beta@dartmouth.edu
  49.  */
  50.  
  51. #ifdef READLINE
  52. #ifdef ATARI
  53. #include "plot.h"
  54. #endif
  55. #ifdef _WINDOWS
  56. #define _Windows
  57. #endif
  58.  
  59. /* a small portable version of GNU's readline */
  60. /* this is not the BASH or GNU EMACS version of READLINE due to Copyleft 
  61.     restrictions */
  62. /* do not need any terminal capabilities except backspace, */
  63. /* and space overwrites a character */
  64.  
  65. /* NANO-EMACS line editing facility */
  66. /* printable characters print as themselves (insert not overwrite) */
  67. /* ^A moves to the beginning of the line */
  68. /* ^B moves back a single character */
  69. /* ^E moves to the end of the line */
  70. /* ^F moves forward a single character */
  71. /* ^K kills from current position to the end of line */
  72. /* ^P moves back through history */
  73. /* ^N moves forward through history */
  74. /* ^H and DEL delete the previous character */
  75. /* ^D deletes the current character, or EOF if line is empty */
  76. /* ^L/^R redraw line in case it gets trashed */
  77. /* ^U kills the entire line */
  78. /* ^W kills last word */
  79. /* LF and CR return the entire line regardless of the cursor postition */
  80. /* EOF with an empty line returns (char *)NULL */
  81.  
  82. /* all other characters are ignored */
  83.  
  84. #include <stdio.h>
  85. #include <ctype.h>
  86. #include <signal.h>
  87.  
  88. #if !defined(MSDOS) && !defined(ATARI) && !defined(_Windows) && !defined(DOS386)
  89.  
  90. /*
  91.  * Set up structures using the proper include file
  92.  */
  93. #ifdef _IBMR2
  94. #define SGTTY
  95. #endif
  96. /*  submitted by Francois.Dagorn@cicb.fr */
  97. #ifdef SGTTY
  98. #include <sgtty.h>
  99. static struct sgttyb orig_termio, rl_termio;
  100. /* define terminal control characters */
  101. static struct tchars s_tchars;
  102. #define VERASE    0
  103. #define VEOF      1
  104. #define VKILL     2
  105. #ifdef TIOCGLTC         /* available only with the 'new' line discipline */
  106. static struct ltchars s_ltchars;
  107. #define VWERASE   3
  108. #define VREPRINT  4
  109. #define VSUSP     5
  110. #endif /* TIOCGLTC */
  111. #define NCCS      6
  112.  
  113. #else /* SGTTY */
  114.  
  115. /* SIGTSTP defines job control */
  116. /* if there is job control then we need termios.h instead of termio.h */
  117. /* (Are there any systems with job control that use termio.h?  I hope not.) */
  118. #ifdef SIGTSTP
  119. #define TERMIOS
  120. #include <termios.h>
  121. /* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
  122. #ifdef ISC22
  123. #ifndef ONOCR            /* taken from sys/termio.h */
  124. #define ONOCR 0000020    /* true at least for ISC 2.2 */
  125. #endif 
  126. #ifndef IUCLC
  127. #define IUCLC 0001000
  128. #endif
  129. #endif /* ISC22 */
  130.  
  131. static struct termios orig_termio, rl_termio;
  132. #else
  133. #include <termio.h>
  134. static struct termio orig_termio, rl_termio;
  135. /* termio defines NCC instead of NCCS */
  136. #define NCCS    NCC
  137. #endif /* SIGTSTP */
  138. #endif /* SGTTY */
  139.  
  140. /* ULTRIX defines VRPRNT instead of VREPRINT */
  141. #ifdef VRPRNT
  142. #define VREPRINT VRPRNT
  143. #endif
  144.  
  145. /* define characters to use with our input character handler */
  146. static char term_chars[NCCS];
  147.  
  148. static int term_set = 0;    /* =1 if rl_termio set */
  149.  
  150. #ifdef NeXT
  151. #define special_getc() ESCgetc()
  152. static char ESCgetc();
  153. #else
  154. #define special_getc() getc(stdin)
  155. #endif
  156.  
  157. #else /* !MSDOS && !ATARI && !_Windows */
  158.  
  159. #ifdef _Windows
  160. #include <windows.h>
  161. #include "win/wtext.h"
  162. #include "win/wgnuplib.h"
  163. extern TW textwin;
  164. #define TEXTUSER 0xf1
  165. #define TEXTGNUPLOT 0xf0
  166. #define special_getc() msdos_getch()
  167. static char msdos_getch();
  168. #endif
  169.  
  170. #if defined(MSDOS) || defined(DOS386)
  171. /* MSDOS specific stuff */
  172. #ifdef DJGPP
  173. #include <pc.h>
  174. #endif
  175. #ifdef __EMX__
  176. #include <conio.h>
  177. #endif
  178. #define special_getc() msdos_getch()
  179. static char msdos_getch();
  180. #endif /* MSDOS */
  181.  
  182. #ifdef ATARI
  183. #include <stdlib.h>
  184. #ifdef __PUREC__
  185. #include <tos.h>
  186. #else
  187. #include <osbind.h>
  188. #endif
  189. #define special_getc() tos_getch()
  190. static char tos_getch();
  191. #endif
  192.  
  193. #endif /* !MSDOS && !ATARI && !_Windows */
  194.  
  195. #if !defined(ATARI)
  196. /* is it <string.h> or <strings.h>?   just declare what we need */
  197. extern int strlen();
  198. extern char *strcpy();
  199. #endif
  200. extern char *alloc();    /* we'll use the safe malloc from misc.c */
  201.  
  202. #define MAXBUF    1024
  203. #define BACKSPACE 0x08    /* ^H */
  204. #define SPACE    ' '
  205.  
  206. struct hist {
  207.     char *line;
  208.     struct hist *prev;
  209.     struct hist *next;
  210. };
  211.  
  212. static struct hist *history = NULL;  /* no history yet */
  213. static struct hist *cur_entry = NULL;
  214.  
  215. static char cur_line[MAXBUF];  /* current contents of the line */
  216. static int cur_pos = 0;    /* current position of the cursor */
  217. static int max_pos = 0;    /* maximum character position */
  218.  
  219.  
  220. void add_history();
  221. static void fix_line();
  222. static void redraw_line();
  223. static void clear_line();
  224. static void clear_eoline();
  225. static void copy_line();
  226. static void set_termio();
  227. static void reset_termio();
  228.  
  229. /* user_putc and user_puts should be used in the place of
  230.  * fputc(ch,stderr) and fputs(str,stderr) for all output
  231.  * of user typed characters.  This allows MS-Windows to 
  232.  * display user input in a different color. */
  233. int
  234. user_putc(ch)
  235. int ch;
  236. {
  237.     int rv;
  238. #ifdef _Windows
  239.     TextAttr(&textwin,TEXTUSER);
  240. #endif
  241.     rv = fputc(ch, stderr);
  242. #ifdef _Windows
  243.     TextAttr(&textwin,TEXTGNUPLOT);
  244. #endif
  245.     return rv;
  246. }
  247.  
  248. int
  249. user_puts(str)
  250. char *str;
  251. {
  252.     int rv;
  253. #ifdef _Windows
  254.     TextAttr(&textwin,TEXTUSER);
  255. #endif
  256.     rv = fputs(str, stderr);
  257. #ifdef _Windows
  258.     TextAttr(&textwin,TEXTGNUPLOT);
  259. #endif
  260.     return rv;
  261. }
  262.  
  263. /* This function provides a centralized non-destructive backspace capability */
  264. /* M. Castro */
  265.  
  266. backspace()
  267. {
  268.     user_putc(BACKSPACE);
  269. }
  270.     
  271. char *
  272. readline(prompt)
  273. char *prompt;
  274. {
  275.  
  276.     unsigned char cur_char;
  277.     char *new_line;
  278.     /* unsigned char *new_line; */
  279.  
  280.     /* set the termio so we can do our own input processing */
  281.     set_termio();
  282.  
  283.     /* print the prompt */
  284.     fputs(prompt, stderr);
  285.     cur_line[0] = '\0';
  286.     cur_pos = 0;
  287.     max_pos = 0;
  288.     cur_entry = NULL;
  289.  
  290.     /* get characters */
  291.     for(;;) {
  292.         cur_char = special_getc();
  293. #ifdef OS2
  294.  /* for emx: remap scan codes for cursor keys */
  295.                 if( cur_char == 0 ) {
  296.                     cur_char = getc(stdin);
  297.                     switch( cur_char){
  298.                         case 75:  /* left, map to ^B */
  299.                             cur_char=2;
  300.                             break ;
  301.                         case 77:  /* right, map to ^F */
  302.                             cur_char=6;
  303.                             break ;
  304.                         case 115: /* ctrl left */
  305.                         case 71:  /* home, map to ^A */
  306.                             cur_char=1;
  307.                             break ;
  308.                         case 116: /* ctrl right */
  309.                         case 79:  /* end, map to ^E */
  310.                             cur_char=5;
  311.                             break ;
  312.                         case 72:  /* up, map to ^P */
  313.                             cur_char=16;
  314.                             break ;
  315.                         case 80:  /* down, map to ^N */
  316.                             cur_char=14;
  317.                             break ;
  318.                         case 83:  /* delete, map to ^D */
  319.                             cur_char=4;
  320.                             break ;
  321.                         default:  /* ignore */
  322.                             cur_char=0;
  323.                             continue ;
  324.                             }
  325.                         }
  326. #endif  /*OS2*/
  327.         if((isprint(cur_char) 
  328. #if defined(ATARI) || defined(_Windows) || defined(MSDOS) || defined(DOS386)
  329.    /* this should be used for all 8bit ASCII machines, I guess */
  330.                     || ((unsigned char)cur_char > 0x7f)
  331. #endif
  332.                                )&& max_pos<MAXBUF-1) {
  333.             int i;
  334.             for(i=max_pos; i>cur_pos; i--) {
  335.                 cur_line[i] = cur_line[i-1];
  336.             }
  337.             user_putc(cur_char);
  338.             cur_line[cur_pos] = cur_char;
  339.             cur_pos += 1;
  340.             max_pos += 1;
  341.             if (cur_pos < max_pos)
  342.                 fix_line();
  343.             cur_line[max_pos] = '\0';
  344.  
  345.         /* else interpret unix terminal driver characters */
  346. #ifdef VERASE
  347.         } else if(cur_char == term_chars[VERASE] ){  /* DEL? */
  348.             if(cur_pos > 0) {
  349.                 int i;
  350.                 cur_pos -= 1;
  351.                 backspace();
  352.                 for(i=cur_pos; i<max_pos; i++)
  353.                     cur_line[i] = cur_line[i+1];
  354.                 max_pos -= 1;
  355.                 fix_line();
  356.             }
  357. #endif /* VERASE */
  358. #ifdef VEOF
  359.         } else if(cur_char == term_chars[VEOF] ){   /* ^D? */
  360.             if(max_pos == 0) {
  361.                 reset_termio();
  362.                 return((char *)NULL);
  363.             }
  364.             if((cur_pos < max_pos)&&(cur_char == 004)) { /* ^D */
  365.                 int i;
  366.                 for(i=cur_pos; i<max_pos; i++)
  367.                     cur_line[i] = cur_line[i+1];
  368.                 max_pos -= 1;
  369.                 fix_line();
  370.             }
  371. #endif /* VEOF */
  372. #ifdef VKILL
  373.         } else if(cur_char == term_chars[VKILL] ){  /* ^U? */
  374.             clear_line(prompt);
  375. #endif /* VKILL */
  376. #ifdef VWERASE
  377.         } else if(cur_char == term_chars[VWERASE] ){  /* ^W? */
  378.             while((cur_pos > 0) &&
  379.                   (cur_line[cur_pos-1] == SPACE)) {
  380.                 cur_pos -= 1;
  381.                 backspace();
  382.             }
  383.             while((cur_pos > 0) &&
  384.                   (cur_line[cur_pos-1] != SPACE)) {
  385.                 cur_pos -= 1;
  386.                 backspace();
  387.             }
  388.             clear_eoline();
  389.             max_pos = cur_pos;
  390. #endif /* VWERASE */
  391. #ifdef VREPRINT
  392.         } else if(cur_char == term_chars[VREPRINT] ){  /* ^R? */
  393.             putc('\n',stderr); /* go to a fresh line */
  394.             redraw_line(prompt);
  395. #endif /* VREPRINT */
  396. #ifdef VSUSP
  397.         } else if(cur_char == term_chars[VSUSP]) {
  398.             reset_termio();
  399.             kill(0, SIGTSTP);
  400.  
  401.             /* process stops here */
  402.  
  403.             set_termio();
  404.             /* print the prompt */
  405.             redraw_line(prompt);
  406. #endif /* VSUSP */
  407.         } else {
  408.             /* do normal editing commands */
  409.             /* some of these are also done above */
  410.             int i;
  411.             switch(cur_char) {
  412.                 case EOF:
  413.                 reset_termio();
  414.                 return((char *)NULL);
  415.                 case 001: /* ^A */
  416.                 while(cur_pos > 0) {
  417.                     cur_pos -= 1;
  418.                     backspace();
  419.                 }
  420.                 break;
  421.                 case 002: /* ^B */
  422.                 if(cur_pos > 0) {
  423.                     cur_pos -= 1;
  424.                     backspace();
  425.                 }
  426.                 break;
  427.                 case 005: /* ^E */
  428.                 while(cur_pos < max_pos) {
  429.                     user_putc(cur_line[cur_pos]);
  430.                     cur_pos += 1;
  431.                 }
  432.                 break;
  433.                 case 006: /* ^F */
  434.                 if(cur_pos < max_pos) {
  435.                     user_putc(cur_line[cur_pos]);
  436.                     cur_pos += 1;
  437.                 }
  438.                 break;
  439.                 case 013: /* ^K */
  440.                 clear_eoline();
  441.                 max_pos = cur_pos;
  442.                 break;
  443.                 case 020: /* ^P */
  444.                 if(history != NULL) {
  445.                     if(cur_entry == NULL) {
  446.                         cur_entry = history;
  447.                         clear_line(prompt);
  448.                         copy_line(cur_entry->line);
  449.                     } else if(cur_entry->prev != NULL) {
  450.                         cur_entry = cur_entry->prev;
  451.                         clear_line(prompt);
  452.                         copy_line(cur_entry->line);
  453.                     }
  454.                 }
  455.                 break;
  456.                 case 016: /* ^N */
  457.                 if(cur_entry != NULL) {
  458.                     cur_entry = cur_entry->next;
  459.                     clear_line(prompt);
  460.                     if(cur_entry != NULL) 
  461.                         copy_line(cur_entry->line);
  462.                     else
  463.                         cur_pos = max_pos = 0;
  464.                 }
  465.                 break;
  466.                 case 014: /* ^L */
  467.                 case 022: /* ^R */
  468.                 putc('\n',stderr); /* go to a fresh line */
  469.                 redraw_line(prompt);
  470.                 break;
  471.                 case 0177: /* DEL */
  472.                 case 010: /* ^H */
  473.                 if(cur_pos > 0) {
  474.                     cur_pos -= 1;
  475.                     backspace();
  476.                     for(i=cur_pos; i<max_pos; i++)
  477.                         cur_line[i] = cur_line[i+1];
  478.                     max_pos -= 1;
  479.                     fix_line();
  480.                 }
  481.                 break;
  482.                 case 004: /* ^D */
  483.                 if(max_pos == 0) {
  484.                     reset_termio();
  485.                     return((char *)NULL);
  486.                 }
  487.                 if(cur_pos < max_pos) {
  488.                     for(i=cur_pos; i<max_pos; i++)
  489.                         cur_line[i] = cur_line[i+1];
  490.                     max_pos -= 1;
  491.                     fix_line();
  492.                 }
  493.                 break;
  494.                 case 025:  /* ^U */
  495.                 clear_line(prompt);
  496.                 break;
  497.                 case 027:  /* ^W */
  498.                 while((cur_pos > 0) &&
  499.                       (cur_line[cur_pos-1] == SPACE)) {
  500.                     cur_pos -= 1;
  501.                     backspace();
  502.                 }
  503.                 while((cur_pos > 0) &&
  504.                       (cur_line[cur_pos-1] != SPACE)) {
  505.                     cur_pos -= 1;
  506.                     backspace();
  507.                 }
  508.                 clear_eoline();
  509.                 max_pos = cur_pos;
  510.                 break;
  511.                 case '\n': /* ^J */
  512.                 case '\r': /* ^M */
  513.                 cur_line[max_pos+1] = '\0';
  514.                 putc('\n', stderr);
  515.                 new_line = (char *)alloc((unsigned long) (strlen(cur_line)+1), "history");
  516.                 strcpy(new_line,cur_line);
  517.                 reset_termio();
  518.                 return(new_line);
  519.                 default:
  520.                 break;
  521.             }
  522.         }
  523.     }
  524. }
  525.  
  526. /* fix up the line from cur_pos to max_pos */
  527. /* do not need any terminal capabilities except backspace, */
  528. /* and space overwrites a character */
  529. static void
  530. fix_line()
  531. {
  532.     int i;
  533.  
  534.     /* write tail of string */
  535.     for(i=cur_pos; i<max_pos; i++)
  536.         user_putc(cur_line[i]);
  537.  
  538.     /* write a space at the end of the line in case we deleted one */
  539.     user_putc(SPACE);
  540.  
  541.     /* backup to original position */
  542.     for(i=max_pos+1; i>cur_pos; i--)
  543.         backspace();
  544.  
  545. }
  546.  
  547. /* redraw the entire line, putting the cursor where it belongs */
  548. static void
  549. redraw_line(prompt)
  550. char *prompt;
  551. {
  552.     int i;
  553.  
  554.     fputs(prompt, stderr);
  555.     user_puts(cur_line);
  556.  
  557.     /* put the cursor where it belongs */
  558.     for(i=max_pos; i>cur_pos; i--)
  559.         backspace();
  560. }
  561.  
  562. /* clear cur_line and the screen line */
  563. static void
  564. clear_line(prompt)
  565. char *prompt;
  566. {
  567.     int i;
  568.     for(i=0; i<max_pos; i++)
  569.         cur_line[i] = '\0';
  570.  
  571.     for(i=cur_pos; i>0; i--)
  572.         backspace();
  573.  
  574.     for(i=0; i<max_pos; i++)
  575.         putc(SPACE, stderr);
  576.  
  577.     putc('\r', stderr);
  578.     fputs(prompt, stderr);
  579.  
  580.     cur_pos = 0;
  581.     max_pos = 0;
  582. }
  583.  
  584. /* clear to end of line and the screen end of line */
  585. static void
  586. clear_eoline(prompt)
  587. char *prompt;
  588. {
  589.     int i;
  590.     for(i=cur_pos; i<max_pos; i++)
  591.         cur_line[i] = '\0';
  592.  
  593.     for(i=cur_pos; i<max_pos; i++)
  594.         putc(SPACE, stderr);
  595.     for(i=cur_pos; i<max_pos; i++)
  596.         backspace();
  597. }
  598.  
  599. /* copy line to cur_line, draw it and set cur_pos and max_pos */
  600. static void
  601. copy_line(line)
  602. char *line;
  603. {
  604.     strcpy(cur_line, line);
  605.     user_puts(cur_line);
  606.     cur_pos = max_pos = strlen(cur_line);
  607. }
  608.  
  609. /* add line to the history */
  610. void
  611. add_history(line)
  612. char *line;
  613. {
  614.     struct hist *entry;
  615.     entry = (struct hist *)alloc((unsigned long)sizeof(struct hist),"history");
  616.     entry->line = alloc((unsigned long)(strlen(line)+1),"history");
  617.     strcpy(entry->line, line);
  618.  
  619.     entry->prev = history;
  620.     entry->next = NULL;
  621.     if(history != NULL) {
  622.         history->next = entry;
  623.     }
  624.     history = entry;
  625. }
  626.  
  627. #if defined(MSDOS) || defined(_Windows) || defined(DOS386)
  628.  
  629. /* Convert Arrow keystrokes to Control characters: */
  630. static  char
  631. msdos_getch()
  632. {
  633. #ifdef DJGPP
  634.     char c;
  635.     int ch = getkey();
  636.     c = (ch & 0xff00) ? 0 : ch & 0xff;
  637. #else
  638.     char c = getch();
  639. #endif
  640.  
  641.     if (c == 0) {
  642. #ifdef DJGPP
  643.     c = ch & 0xff;
  644. #else
  645.     c = getch(); /* Get the extended code. */
  646. #endif
  647.     switch (c) {
  648.         case 75: /* Left Arrow. */
  649.         c = 002;
  650.         break;
  651.         case 77: /* Right Arrow. */
  652.         c = 006;
  653.         break;
  654.         case 72: /* Up Arrow. */
  655.         c = 020;
  656.         break;
  657.         case 80: /* Down Arrow. */
  658.         c = 016;
  659.         break;
  660.         case 115: /* Ctl Left Arrow. */
  661.         case 71: /* Home */
  662.         c = 001;
  663.         break;
  664.         case 116: /* Ctl Right Arrow. */
  665.         case 79: /* End */
  666.         c = 005;
  667.         break;
  668.         case 83: /* Delete */
  669.         c = 004;
  670.         break;
  671.         default:
  672.         c = 0;
  673.         break;
  674.     }
  675.     }
  676.     else if (c == 033) { /* ESC */
  677.     c = 025;
  678.     }
  679.  
  680.  
  681.     return c;
  682. }
  683.  
  684. #endif /* MSDOS */
  685.  
  686. #ifdef ATARI
  687.  
  688. /* Convert Arrow keystrokes to Control characters: TOS version */
  689.  
  690. /* the volatile could be necessary to keep gcc from reordering 
  691.    the two Super calls
  692. */
  693. #define CONTERM ((/*volatile*/ char *)0x484L)
  694.  
  695. static void 
  696. remove_conterm()
  697. {
  698.   void *ssp=(void*)Super(0L);
  699.   *CONTERM &= ~0x8;
  700.   Super(ssp);
  701. }
  702.  
  703. static    char
  704. tos_getch()
  705. {
  706.     long rawkey;
  707.     char c;
  708.     int scan_code;
  709.     void *ssp;
  710.     static  int init = 1;
  711.     static  int in_help = 0;
  712.  
  713.     if (in_help) {
  714.     switch(in_help) {
  715.         case 1:
  716.         case 5: in_help++; return 'e';
  717.         case 2:
  718.         case 6: in_help++; return 'l';
  719.         case 3:
  720.         case 7: in_help++; return 'p';
  721.         case 4: in_help = 0; return 0x0d;
  722.         case 8: in_help = 0; return ' ';
  723.     }
  724.     }
  725.  
  726.     if (init) {
  727.     ssp = (void*)Super(0L);
  728.     if( !(*CONTERM & 0x8) ) {
  729.         *CONTERM |= 0x8;
  730.     } else {
  731.         init=0;
  732.     }
  733.     (void)Super(ssp);
  734.     if( init ) {
  735.         atexit(remove_conterm);
  736.         init = 0;
  737.     }
  738.     }
  739.  
  740.    (void)Cursconf(1, 0); /* cursor on */
  741.     rawkey = Cnecin();
  742.     c = (char)rawkey;
  743.     scan_code= ((int)(rawkey>>16)) & 0xff;    /* get the scancode */
  744.     if( rawkey&0x07000000 ) scan_code |= 0x80;     /* shift or control */
  745.  
  746.     switch (scan_code) {
  747.     case 0x62:                /* HELP        */
  748.         if (max_pos==0) {
  749.         in_help = 1;
  750.         return 'h';
  751.         } else {
  752.         return 0;
  753.         }
  754.     case 0xe2:                /* shift HELP    */
  755.         if (max_pos==0) {
  756.         in_help = 5;
  757.         return 'h';
  758.         } else {
  759.         return 0;
  760.         }
  761.     case 0x48: /* Up Arrow */
  762.         return 0x10; /* ^P */
  763.     case 0x50: /* Down Arrow */
  764.         return 0x0e; /* ^N */
  765.     case 0x4b: /* Left Arrow */
  766.         return 0x02; /* ^B */
  767.     case 0x4d: /* Right Arrow */
  768.         return 0x06; /* ^F */
  769.     case 0xcb: /* Shift Left Arrow */
  770.     case 0xf3: /* Ctrl Left Arrow (TOS-bug ?) */
  771.     case 0x47: /* Home */
  772.         return 0x01; /* ^A */
  773.     case 0xcd: /* Shift Right Arrow */
  774.     case 0xf4: /* Ctrl Right Arrow (TOS-bug ?) */
  775.     case 0xc7: /* Shift Home */
  776.     case 0xf7: /* Crtl Home */
  777.         return 0x05; /* ^E */
  778.     case 0x61: /* Undo - redraw line */
  779.         return 0x0c; /* ^L */
  780.     default:
  781.         if (c == 0x1b) return 0x15; /* ESC becomes ^U */
  782.         if (c == 0x7f) return 0x04; /* Del becomes ^D */
  783.         break;
  784.     }
  785.  
  786.     return c;
  787. }
  788.  
  789. #endif /* ATARI */
  790.  
  791. #ifdef NeXT
  792.  
  793. char ESCgetc()
  794. {
  795.   char c;
  796.  
  797.   c=getc(stdin);
  798.   if( c!='\033' ) { /* ESC */
  799.     return c;
  800.   }
  801.   
  802.   c=getc(stdin);
  803.   if( c!='[' ) {
  804.     return c;
  805.   }
  806.   
  807.   c=getc(stdin);
  808.   switch( c ) {
  809.     case 'A': return '\x10'; /* cursor up    becomes ^P */
  810.     case 'B': return '\x0e'; /* cursor down  becomes ^N */
  811.     case 'C': return '\x06'; /* cursor right becomes ^F */
  812.     case 'D': return '\x02'; /* cursor left  becomes ^B */
  813.     default : return c;
  814.   }
  815. }
  816.  
  817. #endif
  818.  
  819.   /* set termio so we can do our own input processing */
  820. static void
  821. set_termio()
  822. {
  823. #if !defined(MSDOS) && !defined(ATARI) && !defined(_Windows) && !defined(DOS386)
  824. /* set termio so we can do our own input processing */
  825. /* and save the old terminal modes so we can reset them later */
  826.     if(term_set == 0) {
  827.         /*
  828.          * Get terminal modes.
  829.          */
  830. #ifdef SGTTY
  831.         ioctl(0, TIOCGETP, &orig_termio);
  832. #else  /* SGTTY */
  833. #ifdef TERMIOS
  834. #ifdef TCGETS
  835.         ioctl(0, TCGETS, &orig_termio);
  836. #else
  837.         tcgetattr(0, &orig_termio);
  838. #endif /* TCGETS */
  839. #else
  840.         ioctl(0, TCGETA, &orig_termio);
  841. #endif /* TERMIOS */
  842. #endif /* SGTTY */
  843.  
  844.         /*
  845.          * Save terminal modes
  846.          */
  847.         rl_termio = orig_termio;
  848.  
  849.         /*
  850.          * Set the modes to the way we want them
  851.          *  and save our input special characters
  852.          */
  853. #ifdef SGTTY
  854.         rl_termio.sg_flags |= CBREAK;
  855.         rl_termio.sg_flags &= ~(ECHO|XTABS);
  856.         ioctl(0, TIOCSETN, &rl_termio);
  857.  
  858.         ioctl(0, TIOCGETC, &s_tchars);
  859.         term_chars[VERASE]   = orig_termio.sg_erase;
  860.         term_chars[VEOF]     = s_tchars.t_eofc;
  861.         term_chars[VKILL]    = orig_termio.sg_kill;
  862. #ifdef TIOCGLTC
  863.         ioctl(0, TIOCGLTC, &s_ltchars);
  864.         term_chars[VWERASE]  = s_ltchars.t_werasc;
  865.         term_chars[VREPRINT] = s_ltchars.t_rprntc;
  866.         term_chars[VSUSP]    = s_ltchars.t_suspc;
  867.  
  868.         /* disable suspending process on ^Z */
  869.         s_ltchars.t_suspc = 0;
  870.         ioctl(0, TIOCSLTC, &s_ltchars);
  871. #endif /* TIOCGLTC */
  872. #else  /* SGTTY */
  873.         rl_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK|IUCLC|IXON|IXOFF);
  874.         rl_termio.c_iflag |=  (IGNBRK|IGNPAR);
  875.  
  876.         /* rl_termio.c_oflag &= ~(ONOCR); Costas Sphocleous Irvine,CA */
  877.  
  878.         rl_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH);
  879. #ifdef OS2
  880.  /* for emx: remove default terminal processing */
  881.                 rl_termio.c_lflag &= ~(IDEFAULT);
  882. #endif /* OS2 */
  883.         rl_termio.c_lflag |=  (ISIG);
  884.         rl_termio.c_cc[VMIN] = 1;
  885.         rl_termio.c_cc[VTIME] = 0;
  886.  
  887. #ifndef VWERASE
  888. #define VWERASE 3
  889. #endif
  890.         term_chars[VERASE]   = orig_termio.c_cc[VERASE];
  891.         term_chars[VEOF]     = orig_termio.c_cc[VEOF];
  892.         term_chars[VKILL]    = orig_termio.c_cc[VKILL];
  893. #ifdef TERMIOS
  894.         term_chars[VWERASE]  = orig_termio.c_cc[VWERASE];
  895. #ifdef VREPRINT
  896.         term_chars[VREPRINT] = orig_termio.c_cc[VREPRINT];
  897. #else
  898. #ifdef VRPRNT
  899.         term_chars[VRPRNT] = orig_termio.c_cc[VRPRNT];
  900. #endif
  901. #endif
  902.         term_chars[VSUSP]    = orig_termio.c_cc[VSUSP];
  903.  
  904.         /* disable suspending process on ^Z */
  905.         rl_termio.c_cc[VSUSP] = 0;
  906. #endif /* TERMIOS */
  907. #endif /* SGTTY */
  908.  
  909.         /*
  910.          * Set the new terminal modes.
  911.          */
  912. #ifdef SGTTY
  913.         ioctl(0, TIOCSLTC, &s_ltchars);
  914. #else
  915. #ifdef TERMIOS
  916. #ifdef TCSETSW
  917.         ioctl(0, TCSETSW, &rl_termio);
  918. #else
  919.         tcsetattr(0, TCSADRAIN, &rl_termio);
  920. #endif /* TCSETSW */
  921. #else
  922.         ioctl(0, TCSETAW, &rl_termio);
  923. #endif /* TERMIOS */
  924. #endif /* SGTTY */
  925.         term_set = 1;
  926.     }
  927. #endif /* !MSDOS && !ATARI && !defined(_Windows) */
  928. }
  929.   
  930. static void
  931. reset_termio()
  932. {
  933. #if !defined(MSDOS) && !defined(ATARI) && !defined(_Windows) && !defined(DOS386)
  934. /* reset saved terminal modes */
  935.     if(term_set == 1) {
  936. #ifdef SGTTY
  937.         ioctl(0, TIOCSETN, &orig_termio);
  938. #ifdef TIOCGLTC
  939.         /* enable suspending process on ^Z */
  940.         s_ltchars.t_suspc = term_chars[VSUSP];
  941.         ioctl(0, TIOCSLTC, &s_ltchars);
  942. #endif /* TIOCGLTC */
  943. #else  /* SGTTY */
  944. #ifdef TERMIOS
  945. #ifdef TCSETSW
  946.         ioctl(0, TCSETSW, &orig_termio);
  947. #else
  948.         tcsetattr(0, TCSADRAIN, &orig_termio);
  949. #endif /* TCSETSW */
  950. #else
  951.         ioctl(0, TCSETAW, &orig_termio);
  952. #endif /* TERMIOS */
  953. #endif /* SGTTY */
  954.         term_set = 0;
  955.     }
  956. #endif /* !MSDOS && !ATARI && !_Windows */
  957. }
  958. #endif /* READLINE */
  959.